设计模式学习笔记——策略模式
2016-02-26 00:30
507 查看
策略模式
问题:商场收银软件,根据单价和数量,得到总价。设计思路:两个输入框,分别代表单价和数量,一个下拉框,选项有:正常,打折,满减等算法
商场有时需要正常收费,有时打折扣,有时满300送100.下面是简单工厂模式下:
所有算法的父类抽象类CashSuper:
public abstract class CashSuper { public abstract double acceptCash(double money); }其下的其他子类,分别代表不同的收费方式
/** * @author xukai 打折收费 */ public class CashRebate extends CashSuper { private double moneyRebate = 1d; public CashRebate(double moneyRebate) { this.moneyRebate = moneyRebate; } @Override public double acceptCash(double money) { return money * moneyRebate; } }
/** * @author xukai 正常收费 */ public class CashNormal extends CashSuper { @Override public double acceptCash(double money) { return money; } }
/** * @author xukai * 满减收费 */ public class CashReturn extends CashSuper { private double moneyCondition = 0.0d; private double moneyReturn = 0.0d; public CashReturn(double moneyCondition, double moneyReturn) { this.moneyCondition = moneyCondition; this.moneyReturn = moneyReturn; } @Override public double acceptCash(double money) { double result = money; if (money > moneyCondition) { // 如果大于返利条件,则要减去返利值 result = money - Math.floor(money / moneyCondition) * moneyReturn; } return result; } }工厂:根据下拉框选的不同,工厂生产不同的收费方式。
public class CashFactory { public static CashSuper createCashAccept(String type) { CashSuper cs = null; switch (type) { case "正常收费": cs = new CashNormal(); break; case "打八折": cs = new CashRebate(0.8); break; case "满300减100": cs = new CashReturn(300.0, 100.0); break; } return cs; } }使用简单工厂模式解决的是对象的创建问题,工厂包括了所有的收费方式,商场更改打折额度和返利额度非常频繁,那么就要经常扩展收费方式,从而修改工厂,需要引进新的设计模式来解决这一问题。
策略模式定义:定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户。
策略模式的实现:
相比简单工厂模式,去掉了包含静态方法的工厂类,添加了CashContext收费上下文类:
public class CashContext { private CashSuper cs; public CashContext(CashSuper cs) { this.cs = cs; } public double getResult(double money) { return cs.acceptCash(money); } }
通过CashContext进行调用,假如,需要添加一个打七折的收费方式,只需要重新写一个CashRebate为0.7的类,不用改CashContext中的实现。
测试方法:
public void btn_submit(double price,double count,String type){ CashContext cc = null; switch (type) { case "正常收费": cc = new CashContext(new CashNormal()); break; case "打八折": cc = new CashContext(new CashRebate(0.8)); break; case "满300减100": cc = new CashContext(new CashReturn(300.0, 100.0)); break; } System.out.println("总费为:" + cc.getResult(price*count)); }这种办法相当于把收费方式由客户端进行判断使用哪个算法。
简单工厂模式和策略模式对比
1.前者在内部创建需要的对象,后者对象已经创建完毕,只是调用不同的实现方法。2.前者进入工厂之前是不存在的,返回的是要使用的对象。后者进入之前是该对象,返回依然是该对象。
3.前者生成算法的判断由工厂决定,后者由客户端决定。
4.前者的客户端需要识别所有算法的父类CashSuper和工厂CashFactory,后者只需要识别CashContext。
简单工厂模式和策略模式结合
将对象的创建转移到CashContext中,客户端不要判断生成那个对象。public class CashContext { private CashSuper cs = null; public CashContext(String type) { switch (type) { case "正常收费": cs = new CashNormal(); break; case "满300返100": cs = new CashReturn("300", "100"); break; case "打八折": cs = new CashRebate("0.8"); break; } } public double getResult(double money) { return cs.acceptCash(money); } }测试:
public class StrategyTest { public static void main(String[] args) { CashContext cc = new CashContext("打八折"); System.out.println(cc.getResult(1000)); cc = new CashContext("满300返100"); System.out.println(cc.getResult(1000)); } }这种结合还是有弊端,新增其他算法,必须修改CashContext的switch分支。
策略模式解析
策略模式是一种定义一系列算法的方法,从概念上来将,这些算法完成的都是相同的工作,只是实现不同。定义算法家族,分别封装起来,让它们之间可以相互转换,此模式让算法的变化,不会影响到使用算法的客户。
策略模式的优点是简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。
*使用场景:只要在分析过程中听到需要在不同时间应用不同的业务规则,可以考虑使用策略模式处理这种变化的可能性,用来封装算法。
相关文章推荐
- Window Event 2008
- 如何下载一些网站本身不希望你下载的文件呢
- math数学部分
- 制作系统安装U盘
- 【慕课笔记】第四章 JAVA中的集合框架(上) 第11节 通过Set集合管理课程
- leetcode 5. Longest Palindromic Substring
- GenyMotion不能启动的问题,Unable to start the virtual device.VirtualBox cannot start the virtual device
- Android Volley完全解析(四),带你从源码的角度理解Volley
- Android Volley完全解析(三),定制自己的Request
- 创业全攻略:从零到开具第一张发票
- Heap和stack有什么区别?
- Leetcode 160:Intersection of Two Linked Lists
- Android Volley完全解析(二),使用Volley加载网络图片
- Disjoint-Set并查集
- Android Volley完全解析(一),初识Volley的基本用法
- UVA 1368(p58)----DNA Consensus String
- jedis 源码阅读三——PipeLine
- Python学习笔记day6
- 自学vim笔记
- UVA 1363(p338)----Joseph's Problem