《HeadFirst设计模式》笔记——策略模式

定义

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

通俗点的讲,就是将类中一组经常变化的策略(方法)委托于一组具体策略类,这些策略类之间可以互相替换(共同继承于一个接口),自由选择行为进行组合。

用途

1、对同种行为的复用

2、继承也可以通过重载来实现多种行为,但是这种方式是采取硬编码的,具有一定的强制性,并且难以维护和难以扩展。

3、可以动态的变化行为。

参与对象

  • 上下文对象:持有对抽象策略类的引用,还有其他一些不变化的方法和变量。
  • 抽象策略对象:通常用接口实现
  • 具体策略对象:实现了不同功能的不同算法

举例应用

一个网络游戏中有多种不同的角色,每种角色一次可以使用一个武器,在游戏过程中可以更换武器。

进行抽象

  • 上下文对象:不同的角色
  • 抽象策略对象:使用武器
  • 具体策略对象:使用具体的武器

类图

《HeadFirst设计模式》笔记——策略模式_第1张图片
类图
  • Character:不同角色的抽象类
  • WeaponBehavior:使用武器这种行为的接口

具体实现

Character:

public class Character {
    String name;
    WeaponBehavior behavior = new KnifeBehavior();
    public Character(String name) {
        this.name = name;
    }
    public void fight(){
        System.out.print(name+":");
        behavior.userWeapon();
    }
    public void setBehavior(WeaponBehavior behavior) {
        this.behavior = behavior;
    }
}

具体角色:

public class King extends Character {
    public King(String name) {
        super(name);
    }
}

public class Queen extends Character {
    public Queen(String name) {
        super(name);
    }
}

public class Knight extends Character {
    public Knight(String name) {
        super(name);
    }
}

使用武器接口:

public interface WeaponBehavior {
    void userWeapon();
}

具体实现:

public class SwordBehavior implements WeaponBehavior{
    @Override
    public void userWeapon() {
        System.out.println("用宝剑攻击!");
    }
}

public class KnifeBehavior implements WeaponBehavior {
    @Override
    public void userWeapon() {
        System.out.println("用匕首攻击!");
    }
}

public class BowAndArrowBehavior implements WeaponBehavior {
    @Override
    public void userWeapon() {
        System.out.println("用弓箭射击!");
    }
}

public class AxeBehavior implements WeaponBehavior {
    @Override
    public void userWeapon() {
        System.out.println("用斧头砍劈!");
    }
}

使用:

public class Main {
    public static void main(String[] args) {
        King king = new King("King 1");
        king.setBehavior(new SwordBehavior());
        king.fight();
        king.setBehavior(new KnifeBehavior());
        king.fight();
    }
}

Console:
King 1:用宝剑攻击!
King 1:用匕首攻击!

Process finished with exit code 0

通过案例就可以发现,使用武器这种行为的具体实现不是由角色本身实现,而委托于WeaponBehavior的具体实现类(这种面向接口编程的方式可以灵活的扩展),可以动态的选择对应的策略适应不同的场景。

总结:

1、找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
  如果例子中,经常变化的fight()行为不委托于WeaponBehavior实现,那么就很难维护,修改的时候需要修改很多处。

2、针对接口编程,而不是针对实现编程
  使用WeaponBehavior这种接口(抽象类也可以),就能够很好的利用多态的性质,不必知道具体实现,也可以灵活的扩展,增加新的具体行为实现,而不影响原来的实现。

3、多用组合,少用继承
  组合具有更好的灵活性,WeaponBehavior采用组合的方式和Character进行结合,可以动态的改变行为,而且也可以隐藏行为的具体实现。

你可能感兴趣的:(《HeadFirst设计模式》笔记——策略模式)