- 浏览: 138621 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
jackroomage:
-HashMap 类 (除了不同步和允许使用 null ...
map,set,list,等JAVA中集合解析 -
bin_1715575332:
讲得很形象,呵呵。
Spring如何实现IOC与AOP的 -
love_miaohong:
表达的很清晰!
map,set,list,等JAVA中集合解析 -
Wuaner:
引用 4,sleep必须捕获异常,而wait,notify和n ...
sleep() 和 wait() 的区别 -
javawen:
dadsdddddd
java 异常类
首先感谢众多朋友的支持、评论和鼓励,只有多多努力,写点好的博文来回报大家的好意!
接下来想写写另外一个虽然较简单,但是使用很频繁的模式——策略模式
策略模式(Strategy)
1 场景问题
1.1 报价管理
向客户报价,对于销售部门的人来讲,这是一个非常重大、非常复杂的问题,对不同的客户要报不同的价格,比如:
- 对普通客户或者是新客户报的是全价
- 对老客户报的价格,根据客户年限,给予一定的折扣
- 对大客户报的价格,根据大客户的累计消费金额,给予一定的折扣
- 还要考虑客户购买的数量和金额,比如:虽然是新用户,但是一次购买的数量非常大,或者是总金额非常高,也会有一定的折扣
- 还有,报价人员的职务高低,也决定了他是否有权限对价格进行一定的浮动折扣
甚至在不同的阶段,对客户的报价也不同,一般情况是刚开始比较高,越接近成交阶段,报价越趋于合理。
总之,向客户报价是非常复杂的,因此在一些CRM(客户关系管理)的系统中,会有一个单独的报价管理模块,来处理复杂的报价功能。
为了演示的简洁性,假定现在需要实现一个简化的报价管理,实现如下的功能:
(1)对普通客户或者是新客户报全价
(2)对老客户报的价格,统一折扣5%
(3)对大客户报的价格,统一折扣10%
该怎么实现呢?
1.2 不用模式的解决方案
要实现对不同的人员报不同的价格的功能,无外乎就是判断起来麻烦点,也不多难,很快就有朋友能写出如下的实现代码,示例代码如下:
/** * 价格管理,主要完成计算向客户所报价格的功能 */ public class Price { /** * 报价,对不同类型的,计算不同的价格 * @param goodsPrice 商品销售原价 * @param customerType 客户类型 * @return 计算出来的,应该给客户报的价格 */ public double quote(double goodsPrice,String customerType){ if (customerType.equals(" 普通客户 ")){ System.out .println(" 对于新客户或者是普通客户,没有折扣 "); return goodsPrice; }else if (customerType.equals(" 老客户 ")){ System.out .println(" 对于老客户,统一折扣 5%"); return goodsPrice*(1-0.05); }else if (customerType.equals(" 大客户 ")){ System.out .println(" 对于大客户,统一折扣 10%"); return goodsPrice*(1-0.1); } // 其余人员都是报原价 return goodsPrice; } } |
1.3 有何问题
上面的写法是很简单的,也很容易想,但是仔细想想,这样实现,问题可不小,比如:
- 第一个问题:价格类包含了所有计算报价的算法,使得价格类,尤其是报价这个方法比较庞杂,难以维护。
有朋友可能会想,这很简单嘛,把这些算法从报价方法里面拿出去,形成独立的方法不就可以解决这个问题了吗?据此写出如下的实现代码,示例代码如下:
/** * 价格管理,主要完成计算向客户所报价格的功能 */ public class Price { /** * 报价,对不同类型的,计算不同的价格 * @param goodsPrice 商品销售原价 * @param customerType 客户类型 * @return 计算出来的,应该给客户报的价格 */ public double quote(double goodsPrice,String customerType){ if (customerType.equals(" 普通客户 ")){ return this .calcPriceForNormal(goodsPrice); }else if (customerType.equals(" 老客户 ")){ return this .calcPriceForOld(goodsPrice); }else if (customerType.equals(" 大客户 ")){ return this .calcPriceForLarge(goodsPrice); } // 其余人员都是报原价 return goodsPrice; } /** * 为新客户或者是普通客户计算应报的价格 * @param goodsPrice 商品销售原价 * @return 计算出来的,应该给客户报的价格 */ private double calcPriceForNormal(double goodsPrice){ System.out .println(" 对于新客户或者是普通客户,没有折扣 "); return goodsPrice; } /** * 为老客户计算应报的价格 * @param goodsPrice 商品销售原价 * @return 计算出来的,应该给客户报的价格 */ private double calcPriceForOld(double goodsPrice){ System.out .println(" 对于老客户,统一折扣 5%"); return goodsPrice*(1-0.05); } /** * 为大客户计算应报的价格 * @param goodsPrice 商品销售原价 * @return 计算出来的,应该给客户报的价格 */ private double calcPriceForLarge(double goodsPrice){ System.out .println(" 对于大客户,统一折扣 10%"); return goodsPrice*(1-0.1); } } |
这样看起来,比刚开始稍稍好点,计算报价的方法会稍稍简单一点,这样维护起来也稍好一些,某个算法发生了变化,直接修改相应的私有方法就可以了。扩展起来
也容易一点,比如要增加一个“战略合作客户”的类型,报价为直接8折,就只需要在价格类里面新增加一个私有的方法来计算新的价格,然后在计算报价的方法里
面新添一个else-if即可。看起来似乎很不错了。
真的很不错了吗?
再想想,问题还是存在,只不过从计算报价的方法挪动到价格类里面了,假如有100个或者更多这样的计算方式,这会让这个价格类非常庞大,难以维护。而且,维护和扩展都需要去修改已有的代码,这是很不好的,违反了开-闭原则。
- 第二个问题:经常会有这样的需要,在不同的时候,要使用不同的计算方式。
比如:在公司周年庆的时候,所有的客户额外增加3%的折扣;在换季促销的时候,普通客户是额外增加折扣2%,老客户是额外增加折扣3%,大客户是额外增加折扣5%。这意味着计算报价的方式会经常被修改,或者被切换。
通常情况下应该是被切换,因为过了促销时间,又还回到正常的价格体系上来了。而现在的价格类中计算报价的方法,是固定调用各种计算方式,这使得切换调用不同的计算方式很麻烦,每次都需要修改if-else里面的调用代码。
看到这里,可能有朋友会想,那么到底应该如何实现,才能够让价格类中的计算报价的算法,能很容易的实现可维护、可扩展,又能动态的切换变化呢?
未完待续......
转载自:http://chjavach.iteye.com/blog/696977
发表评论
-
研磨设计模式之简单工厂模式-3(转)
2011-03-22 15:25 8103 模式讲解 3.1 典型 ... -
研磨设计模式之简单工厂模式-2(转)
2010-11-19 16:17 7052 解决方案 1 简单工厂来解决 ... -
研磨设计模式之简单工厂模式-1(转)
2010-11-19 16:02 707继续研磨设计模式, ... -
研磨设计模式之抽象工厂模式-1(转)
2010-10-28 15:58 780抽象工厂模式(Abstract Factory) 1.1 ... -
研磨设计模式之装饰模式-4(转)
2010-10-19 16:41 7703.3 装饰模式和AOP 装饰模式和A ... -
研磨设计模式之装饰模式-3(转)
2010-10-11 09:35 7123 模式讲解 3.1 认识 ... -
研磨设计模式之装饰模式-2(转)
2010-09-28 15:42 7972 解决方案 2.1 装饰 ... -
研磨设计模式之装饰模式-1(转)
2010-09-26 08:49 814装饰模式(Decorator) 1 ... -
研磨设计模式之桥接模式-4(转)
2010-09-09 19:03 8413.4 广义桥接-Java中无 ... -
研磨设计模式之桥接模式-3(转)
2010-09-09 18:43 5383 模式讲解 3.1 认识 ... -
研磨设计模式之工厂方法模式-5(转)
2010-09-07 20:01 7553.3 平行的类层次结 ... -
研磨设计模式之工厂方法模式-4(转)
2010-09-07 19:26 5833.2 工厂方法模式与Io ... -
研磨设计模式之工厂方法模式-3(转)
2010-09-07 19:03 5873 模式讲解 3.1 认识工厂方法模式 (1)模式 ... -
研磨设计模式之工厂方法模式-2(转)
2010-09-07 18:22 7302 解决方案 2.1 工 ... -
研磨设计模式之工厂方法模式-1(转)
2010-09-03 18:43 595做Java一晃就十年了,最 ... -
研磨设计模式之策略模式-6(转)
2010-09-02 19:04 9443.4 策略模式结合模板方法模式 在实 ... -
研磨设计模式之策略模式-5(转)
2010-09-02 18:46 699接策略模式-4,其实是讲的一个主题,写在一个里面超长了,只 ... -
研磨设计模式之策略模式-4(转)
2010-09-02 18:29 7193.3 Context和Strategy的 ... -
研磨设计模式之策略模式-3(转)
2010-09-02 17:42 6743 模式讲解 3.1 认 ... -
研磨设计模式之策略模式-2(转)
2010-09-02 17:30 6752 解决方案 2.1 策 ...
相关推荐
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
单例模式、工厂方法模式、策略模式、命令模式和桥接模式。
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
研磨设计模式系列,包括: 单例模式、工厂方法模式、策略模式、命令模式和桥接模式
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
接下来想写写另外一个虽然较简单,但是使用很频繁的模式——策略模式策略模式(Strategy)1 场景问题1.1 报价管理向客户报价,对于销售部门的人来讲,这是一个非常重大、非常复杂的问题,对不同的客户要报不同的...
在网上搜到的资源,很详细的介绍了最常用最简单的设计模式--策略模式