策略设计模式---透彻讲解
一. 什么是策略设计模式设计模式有三种:创建型, 行为型, 结构型. 策略设计模式属于行为型. 为什么属于行为型呢? 来看看下面解释:
1.1 什么是策略呢?什么是策略呢?
举个例子: 出行方式: 可以骑自行车, 摩托车, 开小汽车, 坐公交车, 坐火车, 轮船, 飞机等等. 这些出行方式都是出行的策略.
再来看商场搞促销: 打8折, 打7折, 满100减30, 购物满500返现50等等, 无论何种打折方式, 其根本都是算法, 这些算法就是一种策略. 策略之间是可以随机互换的. 比如同一件商场,今天可以打8折, 明天可以满100件30.
策略设计模式: 定义【一组】算法, 将【每个】算法进行包装, 并且他们之间可以随意【互换】, 来看一下UML图:
从上图可以看出, 定义一个策略设计模式需要4大步骤
策略接口类: 是对策略, 算法的抽象. 定义了每个策略和算法必须有的算法和属性.
策略实现类: 策略,算法的具体实现. 策略具体有几种类型的实现就定义几个策略类,并实现策略方法
Context上下文类: Context上下文, 起到承上启下的作用. 屏蔽了上层模块对策略,算法的访问, 封装了可能存在的变化.
到底当前要调用那个策略, 通过定义构造函数传参决定, 策略方法可以没有入参, 但必须有构造方法, 构造方法决定类的实际策略. 可扩展性强, 增加新的策略, 不需要动用老代码.
客户端类: 客户端调用Context上下文类, 并指定要调用策略的类. 所以, 就要求用户提前知道有哪些策略类.
以上就是策略设计模式实现的4步骤
二. 策略设计模式代码实现我们就以商场促销为例, 使用策略设计模式来实现.
现在商场要促销, 商品促销方式有: 原价, 折扣(8折, 7折), 满减(满100减30, 满100减20)等. 具体的促销方式就是策略.
根据实现的4个步骤, 一步一步来实现
这里定义了一个促销策略的接口类. 并定义了促销方案.
2.2 第二步: 促销方案的实现类促销方案一共有3种: 第一种:原价, 第二种: 打折 第三种: 满减
先来看看第一种: 原价
原价也就是正常售卖的价格. 所以, 没有任何计算逻辑
第二种, 打折
package com.lxl.; /** * 打折 */ public class DiscountPromotionStrategy implements IPromotionStrategy { @Override public Double promotion(PromotionVo promotionVo) throws Exception { if (promotionVo.getDiscount() < 0 || promotionVo.getDiscount() >=1 ){ throw new Exception("请输入正确的折扣"); } return promotionVo.getOriginPrice() * promotionVo.getDiscount(); } }打折有折扣, 那么折扣必须是0-1范围, 并且最后返回折后价
第三种. 满减
package com.lxl.; /** * 满减折扣 */ public class FullReductionPromotionStrategy implements IPromotionStrategy { /** * 满减 * @return * @throws Exception */ @Override public Double promotion(PromotionVo promotionVo) throws Exception { if (promotionVo.getReduction() == null || promotionVo.getFull() == null) { throw new Exception("请检查满减参数"); } Double price = promotionVo.getOriginPrice(); Double canPromotionPrice=promotionVo.getOriginPrice(); while(canPromotionPrice >= promotionVo.getFull()) { price = price - promotionVo.getReduction(); canPromotionPrice -= promotionVo.getFull(); } return price; } }这里实现 满减逻辑是每满100减30, 要是300就减90.
2.3 第三步: context商场促销类我们商场里的商品到底是什么样的优惠方案呢? 有商场促销类决定
package com.lxl.; import org.springframework.beans.factory.annotation.Autowired; /** * 商场促销 */ public class MallPromotion { @Autowired private IPromotionStrategy promotion; public MallPromotion(IPromotionStrategy promotion) { this.promotion = promotion; } public Double activityPromotion(PromotionVo promotionVo) throws Exception { return this.promotion.promotion(promotionVo); } }促销类定义了一个构造函数, 用来指定当前的促销方案.
2.4 具体商品的实际促销方案 public static void main(String[] args) throws Exception { PromotionVo promotionVo = new PromotionVo(300.0, 0.8, 100.0, 30.0); System.out.println("<br><br>==========正常售卖========="); MallPromotion mallPromotionContext1 = new MallPromotion(new CommonPromotionStrategy()); System.out.println(mallPromotionContext1.activityPromotion(promotionVo)); System.out.println("<br><br>==========8折========="); MallPromotion mallPromotionContext2 = new MallPromotion(new DiscountPromotionStrategy()); System.out.println(mallPromotionContext2.activityPromotion(promotionVo)); System.out.println("<br><br>==========满100减30========="); MallPromotion mallPromotionContext3 = new MallPromotion(new FullReductionPromotionStrategy()); System.out.println(mallPromotionContext3.activityPromotion(promotionVo)); } }我们想要什么样 促销方案都是可以的. 只需要调用商场促销类并传入促销策略即可.
三. 策略设计模式的应用 3.1 什么时候使用?一个系统有许多类,而他们之间的区别是: 行为的不同. 这时候可以使用策略设计模式.
3.2 优点策略模式提供了对 “开闭原则” 的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。
算法可以互相切换, 无需知道算法的具体实现
使用策略模式可以避免多重条件选择语句。多重条件选择语句是硬编码,不易维护。
可扩展性更好, 可以灵活地增加新的算法或行为。也可灵活切换算法或者行为
3.3 缺点