1、前言java
什么是策略模式?算法
策略这个词应该怎么理解呢,打个比方说,咱们出门的时候选择不一样的出行方式,好比步行、骑自行车、坐公交、坐火车、坐飞机、坐火箭等等,这些出行方式,每一种都是一个策略。设计模式
再好比咱们去逛商场,商场如今正在搞活动,有打折的、满减的、返利的等等,其实无论商场如何进行促销,说到底都是一些算法,这些算法自己就是一种策略,而且这些算法是随时可能互相替换的,好比针对同一件商品,今天打八折、明天满100减30,这些策略间是能够互换的。ide
策略模式(Strategy),定义了一组算法,将每一个算法都封装起来,而且使它们之间能够互换。布局
2、策略模式的应用学习
一、什么时候使用this
对于业务开发来讲,业务逻辑的复杂是必然的,随着业务发展,需求只会愈来愈复杂,为了考虑到各类各样的状况,代码中不可避免的会出现不少if-else。spa
一旦代码中if-else过多,就会大大的影响其可读性和可维护性,并且代码显得很low。.net
策略模式完美的解决了ifelse的烦恼!设计
二、方法
将这些算法封装成一个一个的类,任意的替换
三、优势
四、缺点
五、应用实例
六、注意事项
若是一个系统的策略多于四个,就须要考虑使用混合模式解决策略类膨胀的问题
3、策略模式的实现
下面就以商场促销为例使用策略模式实现商场促销算法。UML图以下:
一、上下文类
首先声明一个 CashSuper 对象,经过构造方法,传入具体的收费策略, getResult() 方法的功能为根据收费策略的不一样获取计算结果。
package designMode.strategy; public class CashContext { private CashSuper cashSuper; public CashContext(CashSuper cashSuper) { this.cashSuper = cashSuper; } public double getResult(double money){ return cashSuper.acceptCash(money); } }
二、现金收费抽象类
策略类,为抽象类,抽象出收费的方法供子类实现。
package designMode.strategy; public abstract class CashSuper { public abstract double acceptCash(double money); }
三、正常收费子类
package designMode.strategy; public class CashNormal extends CashSuper { @Override public double acceptCash(double money) { return money; } }
四、打折收费子类
package designMode.strategy; public class CashRebate extends CashSuper { private double moneyRebate = 0.8; public CashRebate(double moneyRebate) { this.moneyRebate = moneyRebate; } @Override public double acceptCash(double money) { return money*moneyRebate; } }
五、返利收费子类
package designMode.strategy; public class CashReturn extends CashSuper { private double moneyConditation = 0.0; private double moneyReturn = 0.0d; public CashReturn(double moneyConditation, double moneyReturn) { this.moneyConditation = moneyConditation; this.moneyReturn = moneyReturn; } @Override public double acceptCash(double money) { double result = money; if(money>moneyConditation){ result = money-Math.floor(money/moneyConditation)*moneyReturn; } return result; } }
六、client客户端
package designMode.strategy; import java.util.Scanner; public class Client { public static void main(String[] args) { CashContext cashContext = null; Scanner scanner = new Scanner(System.in); System.out.println("请输入打折方式(1/2/3):"); int in = scanner.nextInt(); String type = ""; switch (in){ case 1: cashContext = new CashContext(new CashNormal()); type += "正常收费"; break; case 2: cashContext = new CashContext(new CashReturn(300,100)); type +="满300返100"; break; case 3: cashContext = new CashContext(new CashRebate(0.8)); type += "打八折"; break; default: System.out.println("请输入1/2/3"); break; } double totalPrices = 0; System.out.print("请输入单价:"); double price = scanner.nextDouble(); System.out.println("请输入数量:"); double num = scanner.nextDouble(); totalPrices = cashContext.getResult(price * num); System.out.println("单价:" + price + ",数量:" + num + ",类型:" + type + ",合计:" + totalPrices); scanner.close(); } }
七、运行结果
4、策略模式与工程模式的区别
一、策略模式是行为性模式,适应行为的变化 ,强调父类的调用子类的特性 。
工厂模式是建立型模式,适应对象的变化,强调统一接口 。
二、策略模式封装行为,调用的时候必须先制定实例化具体的类,再调用抽象的方法; 策略模式的做用是让一个对象在许多行为中选择一种行为。
工厂模式封装对象,实例化对象后调用的时候要知道具体的方法。
三、策略模式是调用不一样类方法, 工厂模式是对父类进行重写。
这俩个模式原本就是解决相似的问题,能够说是孪生兄弟,且内部实现都差很少,都是经过子类来覆盖父类而已,不过简单工厂是把父类直接摆在客户端,而策略模式是将父类隐藏在Context里面,这样封装更好。
四、举个例子
(1)产品之于加减乘除,水果之于苹果梨橘子香蕉,文具之于笔尺刀,这时产品比较具体、有限和没有多个算法重叠,这时实用简单工厂模式。
(2)产品之于商场促销中的返利(可为300返100、500返200、10000返500等等无数)、折扣(2折、2.5折、6折、9折、9.1折等等无数)、正常购买、消费积分(100元10积分、200元30积分等等无数),这时产品构造又屡次重叠,且有在不一样时刻应用不一样的规则时使用策略模式。
五、总结
简单工厂模式只是解决了对象的建立问题,工厂须要包括全部的产品对象的建立,若是产品对象形式常常变化,就须要常常改动工厂,以至代码从新编译。因此策略模式就诞生了,策略模式---它定义了算法家族,分别封装起来,而不是像简单产品模式同样定义全部的产品类,让他们之间能够互相替换,此模式让算法的变化,不会影响到使用算法的客户,使客户拥有相同的访问过程。
简单工厂模式的核心是“简单工厂模式就是用来封装全部的产品对象的”。
策略模式理解核心是“策略模式就是用来封装算法的,但在实践中,咱们发现能够用它来封装几乎任何类型的规则,只要在分析过程当中遇到须要在不一样时间应用不一样的业务规则,就能够考虑使用策略模式处理这种变化的可能性”。
在基本的策略模式中,选择所用的具体实现的算法的职责由客户端对象承担,并转给策略模式的Context对象。这是策略模式自己纯粹的定义,因此,“选择所用最终怎样处理”还有不少文章可作。
看了课本以后对于这两个模式仍是有不少不理解的地方,可是相信随着对设计模式进一步的学习,可以更好地体会到这其中的奥妙,学习是一个按部就班的过程。
推荐博客