23种设计模式(二)---策略设计模式

策略设计模式---透彻讲解

一. 什么是策略设计模式

设计模式有三种:创建型, 行为型, 结构型. 策略设计模式属于行为型. 为什么属于行为型呢? 来看看下面解释:

1.1 什么是策略呢?

什么是策略呢?
举个例子: 出行方式: 可以骑自行车, 摩托车, 开小汽车, 坐公交车, 坐火车, 轮船, 飞机等等. 这些出行方式都是出行的策略.
再来看商场搞促销: 打8折, 打7折, 满100减30, 购物满500返现50等等, 无论何种打折方式, 其根本都是算法, 这些算法就是一种策略. 策略之间是可以随机互换的. 比如同一件商场,今天可以打8折, 明天可以满100件30.

策略设计模式: 定义【一组】算法, 将【每个】算法进行包装, 并且他们之间可以随意【互换】, 来看一下UML图:

23种设计模式(二)---策略设计模式

从上图可以看出, 定义一个策略设计模式需要4大步骤

策略接口类: 是对策略, 算法的抽象. 定义了每个策略和算法必须有的算法和属性.

策略实现类: 策略,算法的具体实现. 策略具体有几种类型的实现就定义几个策略类,并实现策略方法

Context上下文类: Context上下文, 起到承上启下的作用. 屏蔽了上层模块对策略,算法的访问, 封装了可能存在的变化.
到底当前要调用那个策略, 通过定义构造函数传参决定, 策略方法可以没有入参, 但必须有构造方法, 构造方法决定类的实际策略. 可扩展性强, 增加新的策略, 不需要动用老代码.

客户端类: 客户端调用Context上下文类, 并指定要调用策略的类. 所以, 就要求用户提前知道有哪些策略类.

以上就是策略设计模式实现的4步骤

二. 策略设计模式代码实现

我们就以商场促销为例, 使用策略设计模式来实现.
现在商场要促销, 商品促销方式有: 原价, 折扣(8折, 7折), 满减(满100减30, 满100减20)等. 具体的促销方式就是策略.
根据实现的4个步骤, 一步一步来实现

2.1 第一步: 定义商场促销的接口类 package com.lxl.; /** * 促销类 */ public interface IPromotionStrategy { /** * 促销 * * 入参是原价, 出参是促销价格 * @return */ Double promotion(PromotionVo promotionVo) throws Exception; }

这里定义了一个促销策略的接口类. 并定义了促销方案.

2.2 第二步: 促销方案的实现类

促销方案一共有3种: 第一种:原价, 第二种: 打折 第三种: 满减
先来看看第一种: 原价

package com.lxl.; /** * 正常售卖价格 */ public class CommonPromotionStrategy implements IPromotionStrategy { @Override public Double promotion(PromotionVo promotionVo) { return promotionVo.getOriginPrice(); } }

原价也就是正常售卖的价格. 所以, 没有任何计算逻辑

第二种, 打折

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 缺点

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwdzdz.html