策略模式
-
什么是策略模式
策略模式定义了一系列算法,并将每个算法封装起来,使每个算法可以相互替代,使算法本身和使用算法的客户端分割开来,相互独立。
-
主要解决
在有多种算法相似的情况下,使用if…else所带来的复杂和难以维护。
-
什么时候使用
一个系统有许多许多类,而区分它们的只有直接的行为。
-
关键代码
实现同一个接口。
-
应用实例
- 旅行的出游方式
- 计算器
- 商店打折活动
-
缺点
- 策略类会增多
- 所有策略类需要对外暴露
-
优点
- 算法可以自由切换
- 避免使用多重判断
- 扩展性良好
-
注意事项
如果一个系统的策略多于4个,就要考虑使用混合模式,解决策略类膨胀的问题。
使用一个冒险游戏,不同角色使用不同武器介绍
-
首先声明一个抽象策略。
/** * @author Timo * @create 2019-06-01 14:45 * 武器行为接口 * 抽象策略 */ public interface WeaponBehavior { //使用武器方法 void useWeapon(); }
-
创建不同的具体策略实现抽象策略
/** * @author Timo * @create 2019-06-01 14:47 * 具体策略类1 */ public class KnifeBehavior implements WeaponBehavior { //实现武器具体方法 public void useWeapon() { System.out.println("使用刀子攻击"); } }
/** * @author Timo * @create 2019-06-01 14:50 * 具体策略类2 */ public class AxeBehavior implements WeaponBehavior { public void useWeapon() { System.out.println("使用斧子劈人"); } }
-
创建角色父类
/** * @author Timo * @create 2019-06-01 14:51 * 游戏角色父类 */ public abstract class Character { //声明抽象策略 WeaponBehavior weapon; //为抽象策略赋值 public void setWeapon(WeaponBehavior w) { this.weapon = w; } //使用策略 public void attend() { weapon.useWeapon(); } //通用方法 public void speak() { //利用反射获取类名 System.out.println("我是"+getClass().getName()); } }
-
创建不同的子类
/** * @author Timo * @create 2019-06-01 14:58 * 子类1 */ public class King extends Character { public King() { //使用一种策略或算法 setWeapon(new KnifeBehavior()); } }
/** * @author Timo * @create 2019-06-01 15:02 * 子类2 */ public class People extends Character { public People() { //使用不同的策略,或者说是不同的算法 setWeapon(new AxeBehavior()); } }
-
创建测试类
/** * @author Timo * @create 2019-06-01 11:05 */ public class TestOO { public static void main(String[] args) { //创建角色1 Character c = new King(); //角色1说话 c.speak(); //角色1攻击 c.attend(); System.out.println("==================="); //创建角色2 Character c2 = new People(); //角色2 说话 c2.speak(); //角色2攻击 c2.attend(); } }
运行结果: