大话设计模式笔记の 策略模式 (2)

输出结果

单价:400.0 元,数量:3.0 个 折扣:正常收费;总价:1200.0 元 折扣:满300减100;总价:900.0 元 折扣:打8折;总价:960.0 元 仍然存在的缺点

简单工厂模式虽然也能够解决问题2,但这个模式只是解决对象的创建问题,而且由于工厂本身包括了所有的收费模式,商场是可能经常性的更改打折额度和返利额度,每次维护或扩展收费方式都要改动这个工厂,以致代码需要重新编译部署,这是很糟糕的,所以不是最好的解决办法。

策略模式 概念

定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化,不回影响到使用算法的客户。

UML图

大话设计模式笔记の 策略模式

代码实现

其实上面的简单工厂模式实现方式里面的CashSuper、CashNormal、CashRebate、CashReturn都不需要更改,只需要增加一个CashContext类,同时修改下客户端就可以了。

/** * 现金上下文 * Created by callmeDevil on 2019/6/1. */ public class CashContext { private CashSuper cs = null; public CashContext(String type) { switch (type) { case "正常收费": cs = new CashNormal(); break; case "满300减100": cs = new CashReturn(300, 100); break; case "打8折": cs = new CashRebate(0.8); break; default: break; } } public double getResult(double money) { return cs.acceptCash(money); } } /** * 策略模式测试 * Created by callmeDevil on 2019/6/1. */ public class ContextTest { public static void main(String[] args) { double price = 400; double num = 3; System.out.println(String.format("单价:%s 元,数量:%s 个", price, num)); String type = "正常收费"; CashContext cashContext = new CashContext(type); double total = cashContext.getResult(price) * num; System.out.println(String.format("折扣:%s;总价:%s 元", type, total)); type = "满300减100"; cashContext = new CashContext(type); total = cashContext.getResult(price) * num; System.out.println(String.format("折扣:%s;总价:%s 元", type, total)); type = "打8折"; cashContext = new CashContext(type); total = cashContext.getResult(price) * num; System.out.println(String.format("折扣:%s;总价:%s 元", type, total)); } } 需要注意的是

策略模式测试类中的代码与简单工厂的非常相似,因为这里将策略模式与简单工厂模式做了结合,因此比较难以判断策略模式的好处到底在哪。如果仔细分析一下会发现,只用简单工厂的测试类中,也就是客户端代码耦合了CashSuperCashFactory两个类,而使用了策略模式的客户端只涉及到了CashContext一个类,将客户端与具体算法的实现进行了解耦,这样如果商场需要变更促销折扣时,除了变更具体的折扣实现类,只需要更改CashContext即可,客户端完全不用做任何更改,这就是策略模式带来的最大好处。

总结

策略模式是一种定义一系列算法的方法,从概念上看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。

策略模式的Strategy类层次为Context定义了一系列的可供重用的算法或行为。

策略模式另一个优点就是简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。

当不同的行为堆砌在一个类中,就很难避免使用条件语句来选择合适的行为,将这些行为封装在一个个独立的Strategy类中,可以在使用这些行为的类中消除条件语句。

策略模式封装了算法,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。

在基本的策略模式中,选择所用具体实现的职责由客户端对象承担,并转给策略模式的Context对象。

最后不得不说的是,每增加一种算法,都免不了修改CashContext中的switch分支,这是没办法的,因为任何需求的变更都需要成本

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfswz.html