设计模式|策略模式的思路整理

在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。
这种类型的设计模式属于行为型模式。
例如,植物大战僵尸中不同的僵尸有不同的属性,如下表:

类型 外观 移动 攻击
普通僵尸 普通 朝一个方向移动
旗手僵尸 普通 + 手持旗子 朝一个方向移动
舞王僵尸 衣着华丽 太空步 召唤术
它们之间有相同的属性,也有各自独立的功能实现,
每种功能之间也并无依赖关系,互相独立。
设计代码如下:
定义移动接口类
package strategy; /** * 移动方式接口 * * @Auther: 苏察哈尔丶灿 * @Date: 2020/8/8 09:44 * @Slogan: 我自横刀向天笑,笑完我就去睡觉。 */ public interface IMoveable { void move(); }

定义攻击接口类
package strategy; /** * 攻击方式接口 * * @Auther: 苏察哈尔丶灿 * @Date: 2020/8/8 09:45 * @Slogan: 我自横刀向天笑,笑完我就去睡觉。 */ public interface IAttackable { void attack(); }

定义僵尸的抽象类,指定抽象的僵尸共有属性
package strategy; /** * 僵尸行为抽象类 * 规定了移动方式、攻击方式、僵尸属性等信息 * * @Auther: 苏察哈尔丶灿 * @Date: 2020/8/8 09:46 * @Slogan: 我自横刀向天笑,笑完我就去睡觉。 */ public abstract class Zombie implements IMoveable, IAttackable {private IMoveable moveable; private IAttackable attackable; public Zombie(IMoveable moveable, IAttackable attackable) { this.moveable = moveable; this.attackable = attackable; } /** * 僵尸类型,具体交给子类实现 */ abstract void display(); public IMoveable getMoveable() { return moveable; }public void setMoveable(IMoveable moveable) { this.moveable = moveable; }public IAttackable getAttackable() { return attackable; }public void setAttackable(IAttackable attackable) { this.attackable = attackable; } }

至此,空壳已经搭建完成。
接下来准备创建普通僵尸类
先创建普通僵尸的【攻击】和【移动】具体实现类
普通僵尸攻击类
package strategy; /** * 普通攻击实现类 * * @Auther: 苏察哈尔丶灿 * @Date: 2020/8/8 10:04 * @Slogan: 我自横刀向天笑,笑完我就去睡觉。 */ public class NormalAttack implements IAttackable{ @Override public void attack() { System.out.println("攻击方式:咬"); } }

普通僵尸移动类
package strategy; /** * 普通移动实现类 * * @Auther: 苏察哈尔丶灿 * @Date: 2020/8/8 10:05 * @Slogan: 我自横刀向天笑,笑完我就去睡觉。 */ public class NormalMove implements IMoveable{ @Override public void move() { System.out.println("移动方式:一往无前"); } }

普通僵尸类
package strategy; /** * 普通僵尸类 * * @Auther: 苏察哈尔丶灿 * @Date: 2020/8/8 10:01 * @Slogan: 我自横刀向天笑,笑完我就去睡觉。 */ public class NormalZombie extends Zombie{public NormalZombie() { super(new NormalMove(), new NormalAttack()); }@Override public void display() { System.out.println("我是普通僵尸"); }@Override public void attack() { this.getAttackable().attack(); }@Override public void move() { this.getMoveable().move(); } }

【设计模式|策略模式的思路整理】至此,普通僵尸类已经创建完成
还可继续定义一个舞王僵尸类
舞王僵尸攻击类
package strategy; /** * 舞王攻击 * * @Auther: 苏察哈尔丶灿 * @Date: 2020/8/8 10:11 * @Slogan: 我自横刀向天笑,笑完我就去睡觉。 */ public class DancerAttack implements IAttackable{ @Override public void attack() { System.out.println("攻击方式:通灵术召唤大军"); } }

舞王僵尸移动类
package strategy; /** * 舞步移动 * * @Auther: 苏察哈尔丶灿 * @Date: 2020/8/8 10:10 * @Slogan: 我自横刀向天笑,笑完我就去睡觉。 */ public class DancerMove implements IMoveable{ @Override public void move() { System.out.println("移动方式:太空步"); } }

舞王僵尸类
package strategy; /** * 舞王僵尸实现类 * * @Auther: 苏察哈尔丶灿 * @Date: 2020/8/8 10:09 * @Slogan: 我自横刀向天笑,笑完我就去睡觉。 */ public class DancerZombie extends Zombie{ public DancerZombie() { super(new DancerMove(), new DancerAttack()); }@Override public void display() { System.out.println("我是舞王僵尸"); }@Override public void attack() { this.getAttackable().attack(); }@Override public void move() { this.getMoveable().move(); } }

至此【普通僵尸】和【普通僵尸】都已经创建完毕
测试用例
package strategy; /** * @Auther: 苏察哈尔丶灿 * @Date: 2020/8/8 10:13 * @Slogan: 我自横刀向天笑,笑完我就去睡觉。 */ public class Test { public static void main(String[] args) { Zombie normalZombie = new NormalZombie(); normalZombie.display(); normalZombie.move(); normalZombie.attack(); System.out.println("============================="); Zombie dancerZombie = new DancerZombie(); dancerZombie.display(); dancerZombie.move(); dancerZombie.attack(); // 攻击移动等具体操作解耦,可随意更替 dancerZombie.setAttackable(new NormalAttack()); System.out.println("==更换完攻击方式后=="); dancerZombie.attack(); } }

执行结果如下

    推荐阅读