设计模式之策略模式
来源:互联网 发布:护眼灯推荐 知乎 编辑:程序博客网 时间:2024/06/03 13:07
前言:
策略模式(strategy Pattern):定义了算法家族,分别封装;算法之间可以替换,但不会影响使用算法的客户。
一.策略模式的简介:
类的作用:面向对象的过程中,并不是类越多越好,类的划分基础是抽象,类是具有相同属性和功能的对象集合。
策略类的作用:面向对象中,类的作用就是封装变化点,将可变化的算法进行封装,就是策略类。
生活中的策略模式:犹如诸葛亮给赵云的3个锦囊妙计,护送刘备逃离孙权的江东,返回荆州。每一个锦囊,就是一个策略(算法)的封装类,3个锦囊就是就是算法家族。让客户(刘备)根据不同局势,选择不同的锦囊(算法)解决问题,最终成功逃回荆州。
二.策略模式的实例:
案例:电商网站购物订单结算计费,实现正常计费、打折后计费、返利后计费。
1 .UML类图:
2 .策略的抽象父类
package com.pattern.strategy;/** * 收费算法的抽象父类 * @author 葫芦娃 * */public abstract class CashBase { //抽象方法 public abstract double chargeMoney(double money);}
3 .算法家族(各种策略):
正常计费算法:
package com.pattern.strategy;/** * 正常计费类 * * @author 葫芦娃 * */public class CashNormal extends CashBase { @Override public double chargeMoney(double money) { return money; }}
打折计费算法:
package com.pattern.strategy;/** * 打折计费类 * * @author 葫芦娃 * */public class CashDiscount extends CashBase { //折扣 private double discount; //获取折扣的构造方法 public CashDiscount(double discount) { super(); this.discount = discount; } //最终计费 @Override public double chargeMoney(double money) { money = money*discount; return money; }}
返利计费算法:
package com.pattern.strategy;/** * 返利计费类 * * @author 葫芦娃 * */public class CashReturn extends CashBase { //返利消费底线 ,如消费满200返现10元 private double returnCondition; //返现金额 private double returnMoney; //传递参数的构造器 public CashReturn(double returnCondition, double returnMoney) { super(); this.returnCondition = returnCondition; this.returnMoney = returnMoney; } @Override public double chargeMoney(double money) { //如果消费金额满足返现条件,就返现 if (money>=returnCondition) { money = money - returnMoney; } return money; }}
4 .创建策略管理类:
该类实现根据传入的策略,实例化策略对象,调用对象方法的过程。
但为了能够在客户端中隐藏创建策略的过程,实现更好的封装,我们在此处结合了简单工厂模式(点击查看详解),用以根据不同的参数,创建不同的策略对象。如果想完全消除switch-case的条件判断,简化代码的话,可以利用反射来解决,具体实现查看上面的简单工厂模式即可。
package com.pattern.context;import com.pattern.strategy.CashBase;import com.pattern.strategy.CashDiscount;import com.pattern.strategy.CashNormal;import com.pattern.strategy.CashReturn;/** * 策略选择器 * @author 葫芦娃 * */public class CashContext { private CashBase cBase;//收费策略 private int cashType; //计费策略类型,用户拥有优惠特权 private double discount;//折扣 private double returnCondition;//返现条件 private double returnMoney;//返现金额 public CashContext(int cashType, double discount, double returnCondition, double returnMoney) { super(); this.cashType = cashType; this.discount = discount; this.returnCondition = returnCondition; this.returnMoney = returnMoney; } //获取最终付款金额方法(结合简单工厂模式创建策略) public double getResult(double money) { switch (cashType) { case 1: //正常计费 cBase = new CashNormal(); break; case 2: //打折计费 cBase = new CashDiscount(discount); break; case 3: //返利计费 cBase = new CashReturn(returnCondition, returnMoney); break; default: break; } return cBase.chargeMoney(money); }}
5 .客户端:
单一职责:对一个类而言,应只有一个引起它变化的原因。
从客户端代码中可以体会到,通过运用简单工厂模式为策略模式提供创建策略对象的服务,客户端只需要引入一个实体类CashContext,降低耦合度,减轻了客户端的职责,符合面向对象的单一职责原则。
客户端不需要认识(import引用)各个策略类,通过参数即可完成对不同策略的创建,使收费算法和客户端彻底分离。
package com.pattern.client;import com.pattern.context.CashContext;/** * @author 葫芦娃 * */public class Client { /** * @param args */ public static void main(String[] args) { double money = 888.88;// 订单金额 // 正常收费,CashContext(收费策略, 折扣, 返利条件, 返利金额) CashContext nomalContext = new CashContext(1, 0, 0, 0); double realMoney1 = nomalContext.getResult(money); System.out.println("本次消费"+money+"元,实付款:" + realMoney1+ "元,正常收费"); // 打折收费,CashContext(收费策略, 折扣, 返利条件, 返利金额) CashContext discountContext = new CashContext(2, 0.8, 0, 0); double realMoney2 = discountContext.getResult(money); System.out.println("本次消费"+money+"元,实付款:" + realMoney2 + "元,打8折"); // 返利收费,CashContext(收费策略, 折扣, 返利条件, 返利金额) CashContext returnContext = new CashContext(3, 0, 800, 100); double realMoney3 = returnContext.getResult(money); System.out.println("本次消费"+money+"元,实付款:" + realMoney3 + "元,满800元返利100元"); }}
6 .运行结果:
本次消费888.88元,实付款:888.88元,正常收费本次消费888.88元,实付款:711.104元,打8折本次消费888.88元,实付款:788.88元,满800元返利100元
总结:
1 .策略模式是一种定义了一系列算法的方法,所有的算法完成的都是相同的工作(本例中计算消费总价),只是具体的实现不同。
2 .策略模式可以用相同的方式调用所有的算法,减少了定义算法与使用算法之间的耦合。
3 .策略模式的策略层(CashBase抽象类)为Context上下文层(CashContext抽象类)提供了可复用的算法行为(chargeMoney()方法),通过继承提取出公共功能。
4 .策略模式封装算法,避免了用条件判断语句,选择行为。将每个算法进行封装,消除了聚集在一个类中的条件判断。
5 .策略模式还简化了单元测试,每个算法都可以通过自己的接口进行单元测试。
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- 设计模式之策略模式
- linux下使用vim
- sqlserver设计表不允许保存更改,阻止保存要求重新创建表的更改
- javaweb读取配置文件的4种方法
- 十四、备忘录模式——设计模式学习笔记
- 通向架构师的道路(第十七天)IBM Websphere集群探秘-WASND
- 设计模式之策略模式
- MFC中的ArcTo
- 第十一课 类的静态成员
- hdfs文件系统创建文件出错
- Servlet跳转的三种方式
- Solr 安装及配置
- 通向架构师的道路(第十八天)万能框架Spring(一)
- 单片机—数码管静态显示
- 算法题练习系列之(九):部分A+B