(三)商场促销——策略模式

(三)商场促销——策略模式

面向对象的编程并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的集合才是类。

  1. 需求:

    假如设计一个商场收银软件,营业员根据客户所购买的商品的单价和数量,向客户收费。==考虑到不同商品有不同的促销方式:打1折、打3折、满300减100、满200减50、满100积分10点(积分达到一定程度可以领取相对应奖品)==。
    考虑界面如下:

  2. 简单工厂实现

    按照上一节的讲法可以根据简单工厂模式建立类图如下,其中注意为了更好的抽象,应将打折操作(1折、2折等)抽象为一个类而不是两个类,其余操作也类似:

    如果现在需要再添加打5折、满500减200活动,按照简单工厂的思想,只需要在收费生成对象工厂添加两个switch条件,再在下拉选框里加两项就OK了;如果加入满100送10积分的活动,需要添加该收费标准子类,再到界面稍加改动,

    可以看出的是,简单工厂只是解决了对象创建的问题,每次维护和扩展收费方式都要改动这个工厂,以致代码需要重新编译部署。面对算法时常变动,应该有更好的设计模式去选择。

  3. 策略模式实现

    策略模式:是一种定义一系列算法的方法,从概念上看,所有这些算法完成的都是相同的工作,只是实现不同,它可以相同的方式调用所有的算法,减少各种算法与使用算法类之间的耦合。(即通过一个Context类,引入Strategy策略父类,根据传入不同对象,调用具体对应方法),**策略模式封装变化**

    CashContext类:


    客户端主要代码:

  4. 简单工厂-策略模式相结合

    可以发现策略模式又回到未用简单工厂之前的老套路,直接在哭护短去判断使用哪一个算法。显然是不合适的。所以可以将简单工厂在策略模式基础上将判断过程从客户端程序移走。
    改造后CashContext类:

    改造后客户端主要代码:


    对比原先简单工厂的发现,简单工厂需要客户端认识两个类:CashSuper、CashFactory;而现在只需要认识一个CashContext类就可以了。使得具体的收费算法彻底地与客户端分离,连算法的父类CashSuper都不让客户端认识了,耦合度更加降低。
    不过,目前仍不够完美,因为CashContext里还是用到了switch判断,但是相比原先的简单工厂改动成本较小。当然还有更好的办法,比如反射技术,在后面会进行相关整理介绍。

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×