设计模式之 - 策略模式

栏目: 后端 · 发布时间: 5年前

内容简介:我们来看下策略模式的UML图:

一、什么是策略模式

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

我们来看下策略模式的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个左右;

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


以上所述就是小编给大家介绍的《设计模式之 - 策略模式》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

马化腾自述-我的互联网思维

马化腾自述-我的互联网思维

赵黎 / 石油工业出版社 / 2014-8-1 / 35

马化腾自述:我的互联网思维》讲述了些人说移动互联网就是加了“移动”两个字,互联网十几年了,移动互联网应该是个延伸。我的感受是,移动互联网远远不只是一个延伸,甚至是一个颠覆。互联网是一个开放交融、瞬息万变的大生态,企业作为互联网生态里面的物种,需要像自然界的生物一样,各个方面都具有与生态系统汇接、和谐、共生的特性。开放和分享并不是一个宣传口号,也不是一个简单的概念。开放很多时候被看作一种姿态,但是我......一起来看看 《马化腾自述-我的互联网思维》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

在线进制转换器
在线进制转换器

各进制数互转换器

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换