基于策略模式的商场价格优惠设计
基于策略模式的商场价格优惠设计
本文为个人的论文,由于一些原因未能发表,所以拿出来和朋友分享下
注:本文配有源码,如有需要的朋友,请在留言中留下邮箱地址,我会在第一时间发送
本文介绍一种基于策略模式的商场价格优惠管理的改进设计。本设计针对传统策略模式所暴露出来的不足和功能的限制,采用多种设计模式的组合以及灵活的理念,使得功能更加符合用户的需求。
0 引言
以往我们都是使用传统的策略模式来对商场促销功能进行设计,但是由于其传统的缺点和单一的处理策略并不能满足用户同时进行多种策略操作以及客户端和底层代码的灵活调用。所以,这些不足为我们改进策略模式提供了思路。
1 设计思路
1.1 问题的产生
使用传统的策略模式暴露的问题如下:
(1) 策略类数量较多,所有的策略类都需要对外暴露。
(2) 不能灵活处理多种策略的绑定。
(3) 与客户端的交互不够灵活。
1.2 解决方法
针对上述问题,可以通过不同设计模式(工厂方法模式、门面模式和模板模式)的组合以及策略枚举的组合,从而避免上述问题(详见总体设计)。
1.3 设计理念
对于一般的策略模式设计,其只能解决一种策略的实现,对于多种策略的组合有一定的局限性。因此,为了使两种策略思想的实现更加灵活,本设计采用“若干优惠组合策略包含单一优惠策略”的理念。
2 总体设计
2.1 传统模式设计构架
为了更好地说明传统模式和改进模式设计的不同,本文在介绍传统模式的基础上对改进模式进行详细说明。
在传统模式之中,实体类Purchase代表一个销售类与类User构成一对一的关系,其设计类图如图1所示。
传统的处理策略---本设计主要列举了打折策略(Discount)、等价策略(Equal)、满多少送多少策略(UpToUp)、用户积分策略(UserScore)。上述策略必须实现StrategyType接口,目的有两点:1、对策略进行抽象;2、上层代码可以通过接口进行编程。此外,这些策略必须通过一个封装类StrategyContext来使上层代码方便调用相应策略类。其类图如图2所示。
图1
图2
在传统的客户端与底层代码的交互中,往往直接通过调用相关的策略类来进行设计。但是,在策略颇多和逻辑复杂的系统中这样的设计为日后的维护和功能扩展带来了不小的麻烦。下文着重介绍改进后的策略模式。
2.2 改进模式设计构架
首先,在实体类的设计中,增加一个PurchaseBind类,这个类主要负责记录多种策略的组合,并且被类Purchase继承。其类图如图3所示。
图3
在图3的设计中,对金额的操作上并没有使用传统认为的double型,而是采用了易于操作的int型,这样做的原因有:1、int类型比double、float类型处理更方便,不用考虑进位取舍问题(取舍是有误差的);2、目前的二进制存储机制对一些浮点数是无法准确表达的。
其次,在策略类的实现上,上述传统的设计方法并不能满足若干销售策略进行组合的需求,因为上层模块需要调用更新的User对象,而策略类并不能向上层代码传递更新的对象。为了解决这一问题,采用如下设计,由于篇幅限制,本文只列出Discount类的相关设计,其他策略类相似。类图如图4所示。
图4
所以,更新后的User对象就能够通过执行父类StrategyParent中的方法将该对象即时储存在Helper类声明的列表中。上层代码通过调用Helper类中getChangeUser()方法,来获得更新的User对象,进而根据相应组合策略对更新的User对象递归遍历。
同时,为了解决传统策略模式的缺陷:所有的策略类都暴露出去,暴露的越多以后的修改风险也就越大。所以采用一个类似于增加一个配置文件的方法,实现策略类的隐藏,即策略枚举。枚举与策略类进行映射处理,避免高端模块直接访问策略类,同时使用工厂方法模式根据映射产生策略对象,其类图如图5所示。
图5
最后,采用门面模式对高层(客户端)模块与策略工厂模块的动态交互进行优化,从而封装了客户端与策略工厂之间的交互流程。这个流程主要分为以下几个子流程:
(1) 解析在类PurchaseBind中保存在LinkedList链表中的若干策略枚举,将其以参数形式传递给工厂。
(2) 通过递归调用,获得即时更新的User对象,将其与相应策略匹配。
(3) 执行相应方法,用相应策略处理相应User对象。
这一流程封装在类StrategyFacade中,其类图如图6所示:
图6
这样,在传统策略模式的基础上,通过对相应流程进行改进,不仅克服了传统模式的缺点,而且更加符合灵活的设计理念。由于篇幅的限制,只列出了相关设计类图而对代码进行了省略。
3 结束语
本设计遵循灵活的设计理念,通过其他相关设计模式对策略模式进行了优化,将抽象复杂的销售策略相对具体的设计出来。因此,不仅满足了组合策略的需求,而且同时也满足了单一策略的需求,更加有利于对相关销售金额管理系统的日后维护。
参考资料:
[1] 秦小波 设计模式之禅. 北京:机械工业出版社,2010
[2] 程杰 大话设计模式. 北京:清华大学出版社,2007
[3] http://seaizon.iteye.com/blog/753762
[4] 杨年华、张礼平 JAVA类库中的策略模式. 计算机应用与软件,2004