设计模式之策略模式

  • 模式定义

定义了算法族,分别封装起来,让它们之间可以互相替换,此模式的变化独立于算法的使用者。

  • 优点

1.可以将算法的实现细节与使用它的代码隔离开来。
2.符合开闭原则

  • 应用场景

1.当你有很多类似的类,但它们执行某些行为的方式不同时,请使用此策略。

2.使用该模式将类的业务逻辑与算法的实现细节隔离开来,这些算法在逻辑上下文中可能不那么重要。
3.当你的类具有大量的条件运算符,并且在同一算法的不同变体之间切换时,请使用此模式。

  • 举例:

比如说我们开发一个植物大战僵尸,最开始只有普通僵尸和旗手僵尸,我们将其共有的属性和方法封装为一个抽象的父类,代码如下:

public class ZombieTest {
    public static void main(String[] args) {
        AbstractZombie normalZombie = new NormalZombie();
        AbstractZombie flagZombie = new FlagZombie();

        normalZombie.display();
        normalZombie.move();
        normalZombie.attack();

        System.out.println("-------------------");
        flagZombie.display();
        flagZombie.move();
        flagZombie.attack();
    }
}
abstract class AbstractZombie{
    public abstract void display();
    public void attack(){
        System.out.println("咬。。");
    }
    public void move(){
        System.out.println("一步一步移动。。。");
    }
}
class NormalZombie extends AbstractZombie{

    @Override
    public void display() {
        System.out.println("我是普通僵尸。。。");
    }
}

class FlagZombie extends AbstractZombie{

    @Override
    public void display() {
        System.out.println("我是旗手僵尸");
    }
}

设计模式之策略模式

 这个时候我们在添加一个大头僵尸,其攻击方式是头撞,这时候我们只需要继承父类并重写display和attack方法即可,

class BigHeadZombie extends AbstractZombie{

    @Override
    public void display() {
        System.out.println("我是大头僵尸");
    }

    @Override
    public void attack() {
        System.out.println("头撞");
    }
}

如果我们再要开发一个跳舞僵尸,其攻击方式也是头撞,单他的移动方式是跳舞移动,那我们可以直接继承大头僵尸重写move方法即可。

        但是这也引申出一个问题,如果我们在开发一个舞王僵尸,他的移动方式是跳舞,但是攻击方式是挠的话,我们按照上述方式的做法应该是继承跳舞僵尸并重写attack方法。

        这种方式会显得我们的继承关系无比长,不易于我们的开发维护。这个时候就可以使用策略模式。

public class StrategyTest {
    public static void main(String[] args) {
        Zombie normalZombie = new NormalZombie();
        normalZombie.display();
        normalZombie.move();
        normalZombie.attack();
        normalZombie.setAttackable(new HeadAttack());
        normalZombie.attack();

    }
}
interface Moveable{
    void move();
}
interface Attackable{
    void attack();
}
abstract class Zombie{
    abstract public void display();
    Moveable moveable;
    Attackable attackable;
    abstract void move();
    abstract void attack();

    public Zombie(Moveable moveable, Attackable attackable) {
        this.moveable = moveable;
        this.attackable = attackable;
    }

    public Moveable getMoveable() {
        return moveable;
    }

    public void setMoveable(Moveable moveable) {
        this.moveable = moveable;
    }

    public Attackable getAttackable() {
        return attackable;
    }

    public void setAttackable(Attackable attackable) {
        this.attackable = attackable;
    }
}

class StepByStepMove implements Moveable{

    @Override
    public void move() {
        System.out.println("一步一步移动");
    }
}
class BiteAttack implements Attackable{

    @Override
    public void attack() {
        System.out.println("咬");
    }
}
class HeadAttack implements Attackable{

    @Override
    public void attack() {
        System.out.println("头撞");
    }
}

class NormalZombie extends Zombie{

    public NormalZombie(){
        super(new StepByStepMove(),new BiteAttack());
    }

    public NormalZombie(Moveable moveable, Attackable attackable) {
        super(moveable, attackable);
    }

    @Override
    public void display() {
        System.out.println("我是普通僵尸");
    }

    @Override
    void move() {
        moveable.move();
    }

    @Override
    void attack() {
        attackable.attack();
    }
}

class FlagZombie extends Zombie{

    public FlagZombie(){
        super(new StepByStepMove(),new BiteAttack());
    }

    public FlagZombie(Moveable moveable, Attackable attackable) {
        super(moveable, attackable);
    }

    @Override
    public void display() {
        System.out.println("我是旗手僵尸");
    }

    @Override
    void move() {
        moveable.move();
    }

    @Override
    void attack() {
        attackable.attack();
    }
}

普通僵尸本来attack是“咬”,我们重新设置他的攻击策略,他的攻击方式就变成了头撞,在实现策略时可以随意通过set不同的策略来达到不同的效果

设计模式之策略模式

 

  • Spring &JDK 源码中的应用

java.util.Comparator

org.springframework.beans.factory.support.InstantiationStrategy

上一篇:WPF案例(-)模拟Windows7 Win+Tab切换


下一篇:Spring-data-redis + Lettuce 如何使用 Pipeline