使用背景
在开发时,一个功能需根据场景选择不同的方法
举例
战士攻击
问题
算法和对象分开,使两者完全独立
解决方案
使用策略模式-策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。使用情景
1. 一个功能的不同类,仅仅实现方法2. 这功能一次仅需使用其中一个实现类
3. Client不需要知道算法的具体实现细节
4. 这些不同实现的类可以用if-else之类的进行使用---说明可用Strategy类替代
实现结构
组成成分
1. Context:可以通过Context访问必要的资源、数据
2. WeaponInterface:定义算法所支持的公共接口
3. ContextWeapon:实现了WeaponInterface的具体算法
优点
1. 通过Interface可以清晰看到各算法的差异
2. 将算法封装在Strategy类中,可动态改变算法。易于切换,易于理解,易于扩展
3. 干掉了if-else
4. Strategy模式提供了相同行为的更多实现。时间\空间上有更多选择。
缺点
1. Client必须要知道使用哪个类
2. Strategy跟Context偶尔会增加
3. Strategy类的数量更多。Strategy类的状态维护更类,要尽量改成无状态的Strategy类,其他状态用Context类维护,还有享元模式。
代码实现
以为战士选择武器为例
class Warrior {
WeaponInterface weapon;
public Warrior() {
}
public void setWeapon(WeaponInterface weapon) {
this.weapon = weapon;
}
public void attack() {
weapon.useWeapon();
}
}
interface WeaponInterface {
public void useWeapon();
}
class SwordWeapon implements WeaponInterface {
public void useWeapon() {
System.out.println("attack with sword...");
}
}
class AxWeapon implements WeaponInterface {
public void useWeapon() {
System.out.println("attack with Ax...");
}
}
class ArcheryWeapon implements WeaponInterface {
public void useWeapon() {
System.out.println("attack with archery...");
}
}
class BoardKnifeWeapon implements WeaponInterface {
public void useWeapon() {
System.out.println("attack with boardknife...");
}
}
class strategy {
public static void main(String[] args) {
Warrior warrior = new Warrior();
warrior.setWeapon(new SwordWeapon());
warrior.attack();
warrior.setWeapon(new AxWeapon());
warrior.attack();
warrior.setWeapon(new ArcheryWeapon());
warrior.attack();
warrior.setWeapon(new BoardKnifeWeapon());
warrior.attack();
}
}
运行结果:
attack with sword...
attack with Ax...
attack with archery...
attack with boardknife...