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

首先,我们要制作一个商场收银系统
要求:营业员根据客户所购买商品的单价和数量,向客户收费 。
用两个文本框来输入单价和数量,一个确定按钮来算出每种商品的费用,用一个列表框来记录商品的清单,一个标签来记录总计,还需要一个重置按钮来重新开始 。
首先,我们通过面向对象编程实现
代码结构图
现金收费抽象类
正常收费子类
打折收费子类
返利收费子类

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

文章插图
现金收费工厂类
【商场促销----策略模式】客户端程序主要部分
要注意的是:面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类 。
现在,我们如果要增加新的功能,只需要添加新的条件,再在界面修改一下就可以了
但是,简单工厂模式虽然也能解决这个问题,但这个模式只是解决对象的创建问题,而且由于工厂本身包括了所有的收费方式,商场是可能经常性地更改打折额度和返利额度,每次维护或扩展收费方式都要改动这个工厂,以致代码需重新编译部署,这真的是很糟糕的处理方式,所以用它不是最好的办法 。面对算法的时常变动,应该有更好的办法 。于是,我们需要学习新的模式 。
策略模式
策略模式定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户 。
我们将算法分别封装起来
现在,代码是写出来了,但是现在还是需要客户端判断用哪一种算法,解决这个方法最好的办法是让简单工厂和策略模式的结合
这样简单工厂模式我们只需要让客户端认识两个类,和,而策略模
式与简单工厂结合的用法,客户端就只需要认识一个类就可以了 。耦合更加降低 。”
“说得没错,我们在客户端实例化的是的对象,调用的是的方法,这使得具体的收费算法彻底地与客户端分离 。连算法的父类都不让客户端认识了 。
解析
策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合 。
策略模式的优点还有“策略模式的 类层次为定义了一系列的可供重用的算法或行为 。继承有助于析取出这些算法中的公共功能 。对于打折、返利或者其他的算法,其实都是对实际商品收费的一种计算方式,通过继承,可以得到它们的公共功能(获得计算费用的结果,这使得算法间有了抽象的父类) 。
另外,策略模式还有一个优点是简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试[DPE] 。每个算法可保证它没有错误,修改其中任一个时也不会影响其他的算法 。
当不同的行为堆砌在一个类中时,就很难避免使用条件语句来选择合适的行为 。将这些行为封装在一个个独立的类中,可以在使用这些行为的类中消除条件语句[DP] 。就商场收银系统的例子而言,在客户端的代码中就消除条件语句,避免了大量的判断 。
策略模式封装了变化,策略模式就是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性[DPE]" 。但在基本的策略模式中,选择所用具体实现的职责由客户端对象承担,并转给策略模式的对象[DPE] 。这本身并没有解除客户端需要选择判断的压力,而策略模式与简单工厂模式结合后,选择具体实现的职责也可以由来承担,这就最大化地减轻了客户端的职责 。
这已经比起初的策略模式好用了,不过,它依然不够完美 。它还有不足:因为在里还是用到了, 也就是说,如果我们需要增加一种算法,比如‘满200送50’,就必须要更改中的 代码 。