浅谈Strategy策略模式

1、前言java

什么是策略模式?算法

策略这个词应该怎么理解呢,打个比方说,咱们出门的时候选择不一样的出行方式,好比步行、骑自行车、坐公交、坐火车、坐飞机、坐火箭等等,这些出行方式,每一种都是一个策略。设计模式

再好比咱们去逛商场,商场如今正在搞活动,有打折的、满减的、返利的等等,其实无论商场如何进行促销,说到底都是一些算法,这些算法自己就是一种策略,而且这些算法是随时可能互相替换的,好比针对同一件商品,今天打八折、明天满100减30,这些策略间是能够互换的。ide

策略模式(Strategy),定义了一组算法,将每一个算法都封装起来,而且使它们之间能够互换。布局

2、策略模式的应用学习

一、什么时候使用this

对于业务开发来讲,业务逻辑的复杂是必然的,随着业务发展,需求只会愈来愈复杂,为了考虑到各类各样的状况,代码中不可避免的会出现不少if-else。spa

一旦代码中if-else过多,就会大大的影响其可读性和可维护性,并且代码显得很low。.net

策略模式完美的解决了ifelse的烦恼!设计

二、方法

将这些算法封装成一个一个的类,任意的替换

三、优势

  • 算法能够自由切换
  • 避免使用多重条件判断
  • 扩展性良好,增长一个策略只需实现接口便可

四、缺点

  • 策略类数量会增多,每一个策略都是一个类,复用性很小
  • 全部的策略类都须要对外暴露

五、应用实例

  • 出行方式,自行车、汽车等,每一种出行方式都是一个策略
  • 商场促销方式,打折、满减等
  • java AWT中 LayoutManager ,即布局管理器

六、注意事项

若是一个系统的策略多于四个,就须要考虑使用混合模式解决策略类膨胀的问题

640?wx_fmt=jpeg

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对象。这是策略模式自己纯粹的定义,因此,“选择所用最终怎样处理”还有不少文章可作。
看了课本以后对于这两个模式仍是有不少不理解的地方,可是相信随着对设计模式进一步的学习,可以更好地体会到这其中的奥妙,学习是一个按部就班的过程。

 

推荐博客

素小暖讲设计模式

相关文章
相关标签/搜索