粗糙分析设计模式-策略模式

Posted Sun_TTTT

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了粗糙分析设计模式-策略模式相关的知识,希望对你有一定的参考价值。

    在软件开发的过程中,经常会碰见一种情况:实现一个功能可以有多种算法或者策略,我们根据实际情况来选择不同的算法或者是策略。比如说我们上班途中计算路费,如果乘公交是一种算法,乘出租车是一种算法。如果我们按照常规的写法,将这些算法都写在一个类里,通过switch 或者是if...else...进行判断来选择不同的算法,这样也不是不可以,但是仔细想一想,如果我们添加一个新的上班方式,我们就要对这个类进行修改,添加上一个新的通勤方式,这就破坏了我们要求的对修改封闭,对扩展开放的原则了。如果我们把这些算法抽象出来,提供一个统一的接口来计算路费,这样如果添加一个新的通勤方式,就不会修改源代码了。好的废话不多说,先来歌源代码。

我们先看一下常规的写法:

package com.example.kaileen.field;

/**
 * Created by kaileen on 2017/3/21.
 */
public class CalculatorPrice 
    private static final int BUS = 1;
    private static final int TAXI = 2;

    public int calculatePrice(int km,int type)
        switch (type)
            case BUS:
                return busPrice(km);

            case TAXI:

                return taxiPrice(km);
        
        return 0;
    
    private int busPrice(int km)

        return 2;
    
    private int taxiPrice(int km)
        if (km<3)
            return 10;
        else if (km>=3)
            return 10+(km-3)*3;
        
        return 0;
    
    public static void main(String[] args)
        CalculatorPrice mCalculatorPrice = new CalculatorPrice();
        System.out.println("坐公交车上班需花费:"+mCalculatorPrice.calculatePrice(16,BUS));
        System.out.println("坐出租车上班需花费:"+mCalculatorPrice.calculatePrice(16,TAXI));
    

如果我们添加一个新的通勤方式,骑自行车,按照常规方式,我们就要修改源代码了,经过一系列很容易发生错误的复制粘贴,源代码变成了以下方式:

package com.example.kaileen.field;

/**
 * Created by kaileen on 2017/3/21.
 */
public class CalculatorPrice 
    private static final int BUS = 1;
    private static final int TAXI = 2;
private static final int BIKE = 3;//新添加

    public int calculatePrice(int km,int type)
        switch (type)
            case BUS:
                return busPrice(km);

            case TAXI:

                return taxiPrice(km);

            //新添加
            case BIKE:

                return bikePrice(km);
        
        return 0;
    
    private int busPrice(int km)

        return 2;
    
    private int taxiPrice(int km)
        if (km<3)
            return 10;
        else if (km>=3)
            return 10+(km-3)*3;
        
        return 0;
    
    //新添加
    private int bikePrice(int km)
        return 1;
    
    public static void main(String[] args)
        CalculatorPrice mCalculatorPrice = new CalculatorPrice();
        System.out.println("坐公交车上班需花费:"+mCalculatorPrice.calculatePrice(16,BUS));
        System.out.println("坐出租车上班需花费:"+mCalculatorPrice.calculatePrice(16,TAXI));
        System.out.println("坐自行车车上班需花费:"+mCalculatorPrice.calculatePrice(16,BIKE));
    

这就有点麻烦了,是不是,修改的过程中总是会发生错误,还是那句话 我们要时刻记着那一句话:对修改要保持封闭,对扩展要保持开放。下面我们用策略模式对这个案例进行一下小小的修正。
我们将计算价格提取出来,让公交车、出租车、自行车都实现同一个Strategy接口,如下

public interface Strategy
    int calculatePrice(int km);

出租车计价策略

public class TaxiStrategy
    @Override
    public int calculatePrice(int km)
          if (km<3)
                return 10;
            else if (km>=3)
                return 10+(km-3)*3;
            
        return 0;
    

公交车计价方式:

public class BusStrategy
    @Override
    public int calculatePrice(int km)
        return 2;
    

我们再实现一个扮演统计角色的类:

public class Calculator
    private Strategy mStrategy;
    public void setStrategy(Strategy s)
        this.mStrategy = s;
    
    public int  calculatePrice(int km)
        if(mStrategy == null)
             throw new NullPointerException("Strategy is not set");
             return0;
        else
            return mStrategy.calculatePrice(km);
        

    
    public static void main(String[] args)
        Calculator mCalculator = new Calculator();
        mCalculator.setStretegy(new BusStretegy());
        System.out.println("乘坐公交车的花费为:"+mCalculator.calculatePrice(6));
    

你看,当我们使用策略模式进行修改之后,是不是变得一目了然,如果我们增加新的通勤方式,我们只要继承Stretegy接口即可,不用再修改源代码。同时,也保持了类的专一性。

以上是关于粗糙分析设计模式-策略模式的主要内容,如果未能解决你的问题,请参考以下文章

23种设计模式---策略设计模式

粗糙分析设计模式——单例模式

粗糙分析设计模式——单例模式

粗糙分析设计模式-原型模式

粗糙分析设计模式-原型模式

NOIP模拟 17.9.28