学习设计模式1策略模式
策略模式的结构
策略模式可以用于定义一系列算法,这些算法完成了相同的工作,只是实现方式不一样而已,而这个策略模式意义在于,可以使用相同的方式来调用不同的算法,减少各种算法类和使用算法类之间的耦合。
下面的Strategy
类,为Context
定义一系列的可供重用的算法和行为,在下面就是一个算法方法。
-
抽象策略算法类
/** * @Program: 设计模式 * @Description: 抽象算法类 * @Author Mokairui * @Date 2020/11/30 20:30 */ public abstract class Strategy { /** * 算法方法 */ public abstract void AlgorithmInterface(); }
-
具体抽象算法类
/** * @Program: 设计模式 * @Description: 具体算法A * @Author Mokairui * @Date 2020/11/30 20:36 */ public class ConcreteStrategyA extends Strategy { @Override public void AlgorithmInterface() { System.out.println("算法A"); } }
/** * @Program: 设计模式 * @Description: 具体算法B * @Author Mokairui * @Date 2020/11/30 20:36B */ public class ConcreteStrategyB extends Strategy { @Override public void AlgorithmInterface() { System.out.println("算法B"); } }
/** * @Program: 设计模式 * @Description: 具体算法C * @Author Mokairui * @Date 2020/11/30 20:36B */ public class ConcreteStrategyC extends Strategy { @Override public void AlgorithmInterface() { System.out.println("算法C"); } }
-
上下文
/** * @Program: 设计模式 * @Description: 上下文 * @Author Mokairui * @Date 2020/11/30 20:38 */ public class Context { private Strategy strategy; public Context(Strategy strategy) { this.strategy = strategy; } /** * 上下文接口实现,调用策略算法类的方法 */ public void ContextInterface() { strategy.AlgorithmInterface(); } }
-
测试
/** * @Program: 设计模式 * @Description: 测试类 * @Author Mokairui * @Date 2020/11/30 20:42 */ public class Demo { public static void main(String[] args) { Context context = null; context = new Context(new ConcreteStrategyA()); context.ContextInterface(); context = new Context(new ConcreteStrategyB()); context.ContextInterface(); context = new Context(new ConcreteStrategyC()); context.ContextInterface(); } }
说明:策略模式一般用于处理不同的算法,一个抽象算法方法,说明是干嘛的如商场中计算最后支付价格,这个就可以作为抽象策略算法方法,具体的算法实现就是打折啊,满多少减多少啊,特殊日子啊等等。 而上下文那个类就是加载初始化抽象策略方法,并且提供一个接口方法可以让别人来调用,而具体那个方法则是看你初始化的那个具体策略算法是哪一个。
策略模式实现例子
例子的背景:超市的收银,有很多中优惠方式,同时要应对,接下来可能会更换优惠方式的情况。
-
抽象的收费方式
package example; /** * @Program: 设计模式 * @Description: 抽象的收费方式 * @Author Mokairui * @Date 2020/11/30 21:56 */ public abstract class CashSuper { /** * 抽象的收费方式 * @return */ public abstract double acceptCash(double money); }
-
三个具体的收费方式
package example; /** * @Program: 设计模式 * @Description: 正常的收费,没有任何优惠 * @Author Mokairui * @Date 2020/11/30 21:57 */ public class CashNormal extends CashSuper { @Override public double acceptCash(double money) { return money; } }
package example; /** * @Program: 设计模式 * @Description: 打折收费子类 * @Author Mokairui * @Date 2020/11/30 22:00 */ public class CashRebate extends CashSuper { // 打折 private double moneyRebate = 1d; public CashRebate() { } // 在类初始的时候如果传参, 则就是打折数,如果没有默认不打折 public CashRebate(double moneyRebate) { this.moneyRebate = moneyRebate; } @Override public double acceptCash(double money) { return money * moneyRebate; } }
package example; /** * @Program: 设计模式 * @Description: 返利收费子类 * @Author Mokairui * @Date 2020/11/30 22:05 */ public class CashReturn extends CashSuper { // 满多少的条件 private double moneyCondition = 0.0d; // 满了后返利的费用 private double moneyReturn = 0.0d; public CashReturn() { } public CashReturn(double moneyCondition, double moneyReturn) { this.moneyCondition = moneyCondition; this.moneyReturn = moneyReturn; } @Override public double acceptCash(double money) { if (money >= moneyCondition) { // 减去返利的钱,每满moneyCondition就减一次 money = money - Math.floor(money / moneyReturn) * moneyReturn; } return money; } }
-
策略和简单共厂相结合的上下文,初始化策略模式
package example; /** * @Program: 设计模式 * @Description: 策略和简单工厂结合,上下文 * @Author Mokairui * @Date 2020/12/1 20:48 */ public class CashContext { private CashSuper cs; public CashContext(String type) { switch (type) { case "正常收费": CashNormal cs0 = new CashNormal(); cs = cs0; break; case "打8折": CashRebate cs1 = new CashRebate(0.8); cs = cs1; break; case "满300减100": CashReturn cs2 = new CashReturn(300, 100); cs = cs2; break; default: break; } } public double GetResult(double money) { return cs.acceptCash(money); } }
-
客服端,测试
package example; /** * @Program: 设计模式 * @Description: 客服端 * @Author Mokairui * @Date 2020/12/1 20:59 */ public class Demo { public static void main(String[] args) { double total = 350.0d; CashContext csuper = new CashContext("满300减100"); double totalPrice = 0d; totalPrice = csuper.GetResult(total); System.out.println(totalPrice); } }
应用场景:它可以封装几乎所有的规则,就是在需要在不同时间应用不同的业务规则(在例子中就是打折,正常收费,满减的这三种规则),就可以考虑使用策略模式来封装这些规则。