博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式之 - 策略模式
阅读量:5897 次
发布时间:2019-06-19

本文共 3175 字,大约阅读时间需要 10 分钟。

一、什么是策略模式

策略模式:它定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式的变化,不会影响到使用算法的客户。

我们来看下策略模式的UML图:

二、策略模式的构成

  • 公共策略:定义一个接口作为公共策略,所有的算法规则实现该接口;

  • 具体策略:封装了具体的算法和行为,继承于公共策略;

  • 封装类:进行二次封装,维护对公共策略对象的引用;

三、实例演示

业务场景:现在我们在做一个商场的优惠活动,这个活动根据节日的不同也会调整相应的活动规则,比如五一黄金周我们是所有会员商品一律8折,节日过后恢复原价不再优惠,等到了国庆商场有有了新的促销活动,满300减150,那么根据这样的业务需求我们来看看使用策略模式到底应该怎么做?

首先我们需要创建一个公共的策略类

public interface Strategy {   // 算法规则   double regulation(double money);}复制代码

接下来我们分别定义三种活动规则,首先是没有优惠活动的收费方式

public class NormalStrategy implements Strategy {   @Override   public double regulation(double money) {       System.out.println("正常收费 : " + money);       return money;   }}复制代码

打折

public class DiscountStrategy implements Strategy {   private double moneyDiscount = 1D;   public DiscountStrategy(String discount) {       this.moneyDiscount = Double.parseDouble(discount);   }   @Override   public double regulation(double money) {       System.out.println("打折优惠 : " + money * moneyDiscount);       return money * moneyDiscount;   }}复制代码

满300返150

public class RebateStrategy implements Strategy {   // 满多少   private double moneyCondition = 0.0D;   // 减多少   private double moneyRebate = 0.0D;   public RebateStrategy(String moneyCondition, String moneyRebate) {       this.moneyCondition = Double.parseDouble(moneyCondition);       this.moneyRebate = Double.parseDouble(moneyRebate);   }   @Override   public double regulation(double money) {       // 判断是否满足返利条件       if (money > moneyCondition) {           System.out.println("折扣返现 : " + (money - Math.floor(money / moneyCondition) * moneyRebate));           return money - Math.floor(money / moneyCondition) * moneyRebate;       }       System.out.println("不够返现条件 : " + money);       return money;   }}复制代码

接下来,我们需要创建一个封装类也可以叫上下文的类,对我们的活动规则进行一个维护

public class Context {   private Strategy strategy;   public Context(String type,double money) {       switch (type) {           case "正常收费":               Strategy normalStrategy = new NormalStrategy();               strategy = normalStrategy;               strategy.regulation(money);               break;           case "打5折":               Strategy discountStrategy = new DiscountStrategy("0.5");               strategy = discountStrategy;               strategy.regulation(money);               break;           case "满300减150":               Strategy rebateStrategy = new RebateStrategy("300", "150");               strategy = rebateStrategy;               strategy.regulation(money);               break;       }   }}复制代码

最后我们分别来测试看下结果是否正确:

public class Main {   public static void main(String[] args) {       new Context("打5折", 500);       new Context("正常收费", 500);       new Context("满300减150", 500);   }}复制代码

可能有读者就存在疑问了,这跟简单工厂模式又有什么区别呢?

第一:首先在我们的封装类中其实已经使用到了简单工厂模式,我们使用简单工厂模,我们通过这种方式的封装将判断是什么优惠的过程从客户端转移到了我们的程序中,客户不需要再去关系;

第二:我们来看下我们昨天的简单工厂模式客户端事怎么调用的,再来看看我们今天使用策略模式是怎么调用的

通过上面我们可以看到,简单工厂模式需要客户端认识两个类,也就是CarFactory和Product,而简单工厂模式只需要客户端认识一个类,也就是Context,这样就降低了我们代码的耦合性。

四、策略模式的优点

  • 策略模式之间可以自由的切换;

  • 增加了程序的扩展性,如果想要增加新的策略,只需要实现公共的策略即可;

  • 避免使用多重条件,当所有的算法都堆积在一个类中,那么就不可避免的要使用条件判断来选择合适的算法;

五、策略模式的缺点

  • 如果有新的策略确实很容易进行扩展,但是当策略多了之后维护就变得比较艰难,所以一般策略的数量一般维护在3个左右;

  • 必须把所有的策略暴露给用户,用户好知道知道使用哪种策略;

转载于:https://juejin.im/post/5bdb9f965188257f45456e1c

你可能感兴趣的文章
react性能优化
查看>>
关于如何在部署环境修改process.env & 本地测试
查看>>
使用 js 修饰器封装 axios
查看>>
使用JPA + Eclipselink操作PostgreSQL数据库
查看>>
QuickBI助你成为分析师——数据源FAQ小结
查看>>
Git的基本使用
查看>>
[机器学习][异常检测算法]
查看>>
https是如何加密的 (知道了原理之后,希望自己能用代码实现一下,还有用于对个人信息和公钥进行加密的哈希算法,有时间也去查一下)...
查看>>
晋大科技完成2亿元B轮融资,持续投入研发及量产
查看>>
DRF-权限源码流程和基本使用
查看>>
深入浅出浏览器渲染原理
查看>>
科学家发现4起黑洞相撞事件,其中最大的一起或为“双重”碰撞
查看>>
WPF程序中的弱事件模式
查看>>
Android开发 - 掌握ConstraintLayout(六)链条(Chains)
查看>>
java基本数据类型
查看>>
BAT自动驾驶:大致相同的生态链,截然不同的生意经
查看>>
WPF Touch操作滚动条,Window弹跳
查看>>
java源码-vector
查看>>
Android 获取系统信息
查看>>
如何持续写文章?
查看>>