策略模式
定义
定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
使用鸭子的故事为例
当设计维护时,为了复用而使用继承结局并不完美,会导致代码在多个子类中重复,运行时的行为不易改变;很难知道所有鸭子的全部行为;改变会牵一发动全身,造成其他鸭子不想要的改变
设计原则
- 找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起
- 针对接口编程而不是针对实现编程
- 多用组合,少用继承
思考方式
把会变化的部分提取出并封装起来,以便以后可以轻易地改动或者扩充此部分,而不影响不需要变化地其他部分
例子:Character是抽象类,由具体的角色来继承,如国王、王后、骑士、妖怪。Weapon是接口,由具体的武器来继承,角色想换武器需要调用setWeapon方法,在打斗过程中可以调用useWeapon方法攻击其他对象
代码实现:
character基类
public abstract class Character {
public void setWeaponBehavior(WeaponBehavior weaponBehavior) {
this.weaponBehavior = weaponBehavior;
}
public WeaponBehavior getWeaponBehavior() {
return weaponBehavior;
}
WeaponBehavior weaponBehavior;
public abstract void fight();
}
角色实现类:
public class King extends Character {
@Override
public void fight() {
System.out.println(this.getClass().getName()+"开始攻击了");
getWeaponBehavior().useWeapon();
}
}
public class Knight extends Character {
@Override
public void fight() {
System.out.println(this.getClass().getName()+"开始攻击了");
getWeaponBehavior().useWeapon();
}
}
public class Queen extends Character {
@Override
public void fight() {
System.out.println(this.getClass().getName()+"开始攻击了");
getWeaponBehavior().useWeapon();
}
}
public class Troll extends Character {
@Override
public void fight() {
System.out.println(this.getClass().getName()+"开始攻击了");
getWeaponBehavior().useWeapon();
}
}
武器接口
public interface WeaponBehavior {
public void useWeapon();
}
接口实现类
public class BowAndArrowBehavior implements WeaponBehavior {
@Override
public void useWeapon() {
System.out.println("使用弓箭射击");
}
}
public class AxeBehavior implements WeaponBehavior {
@Override
public void useWeapon() {
System.out.println("使用斧头砍劈");
}
}
public class KnifeBehavior implements WeaponBehavior {
@Override
public void useWeapon() {
System.out.println("使用匕首攻击");
}
}
public class SwordBehavior implements WeaponBehavior {
@Override
public void useWeapon() {
System.out.println("使用宝剑攻击");
}
}
测试类
public static void main(String[] args) {
Character king = new King();
Character queen = new Queen();
Character knight = new Knight();
Character troll = new Troll();
king.setWeaponBehavior(new SwordBehavior());
king.fight();
queen.setWeaponBehavior(new KnifeBehavior());
queen.fight();
knight.setWeaponBehavior(new BowAndArrowBehavior());
knight.fight();
troll.setWeaponBehavior(new AxeBehavior());
troll.fight();
king.setWeaponBehavior(new BowAndArrowBehavior());
king.fight();
}
运行结果:
StrategyParttern.King开始攻击了
使用宝剑攻击
StrategyParttern.Queen开始攻击了
使用匕首攻击
StrategyParttern.Knight开始攻击了
使用弓箭射击
StrategyParttern.Troll开始攻击了
使用斧头砍劈
StrategyParttern.King开始攻击了
使用弓箭射击