商场促销----策略模式

首先,我们要制作一个商场收银系统

要求:营业员根据客户所购买商品的单价和数量,向客户收费。
用两个文本框来输入单价和数量,一个确定按钮来算出每种商品的费用,用一个列表框来记录商品的清单,一个标签来记录总计,还需要一个重置按钮来重新开始。

首先,我们通过面向对象编程实现

代码结构图

现金收费抽象类

正常收费子类

 打折收费子类

返利收费子类

现金收费工厂类

 

客户端程序主要部分 

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

现在,我们如果要增加新的功能,只需要添加新的条件,再在界面修改一下就可以了

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

                                                                       策略模式

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

  

 

 我们将算法分别封装起来

 

 

 现在,代码是写出来了,但是现在还是需要客户端判断用哪一种算法,解决这个方法最好的办法是让简单工厂和策略模式的Context结合

这样简单工厂模式我们只需要让客户端认识两个类,CashSuper 和CashFactory,而策略模
式与简单工厂结合的用法,客户端就只需要认识一个类CashContext就可以了。耦合更加降低。”
“说得没错,我们在客户端实例化的是CashContext的对象,调用的是CashContext的方法GetResut,这使得具体的收费算法彻底地与客户端分离。连算法的父类CashSuper都不让客户端认识了。

                                                                        解析

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

        策略模式的优点还有“策略模式的Strategy 类层次为Context定义了一系列的可供重用的算法或行为。继承有助于析取出这些算法中的公共功能。对于打折、返利或者其他的算法,其实都是对实际商品收费的一种计算方式,通过继承,可以得到它们的公共功能(获得计算费用的结果GetResult,这使得算法间有了抽象的父类CashSuper)。

        另外,策略模式还有一个优点是简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试[DPE]。每个算法可保证它没有错误,修改其中任一个时也不会影响其他的算法。

         当不同的行为堆砌在一个类中时,就很难避免使用条件语句来选择合适的行为。将这些行为封装在一个个独立的Strategy类中,可以在使用这些行为的类中消除条件语句[DP]。就商场收银系统的例子而言,在客户端的代码中就消除条件语句,避免了大量的判断。
        策略模式封装了变化,策略模式就是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性[DPE]"。但在基本的策略模式中,选择所用具体实现的职责由客户端对象承担,并转给策略模式的Context对象[DPE]。这本身并没有解除客户端需要选择判断的压力,而策略模式与简单工厂模式结合后,选择具体实现的职责也可以由Context来承担,这就最大化地减轻了客户端的职责。

        这已经比起初的策略模式好用了,不过,它依然不够完美。它还有不足:因为在CashContext里还是用到了switch, 也就是说,如果我们需要增加一种算法,比如‘满200送50’,就必须要更改CashContext中的switch 代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值