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

    在软件开发的过程中,经常会碰见一种情况:实现一个功能可以有多种算法或者策略,我们根据实际情况来选择不同的算法或者是策略。比如说我们上班途中计算路费,如果乘公交是一种算法,乘出租车是一种算法。如果我们按照常规的写法,将这些算法都写在一个类里,通过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接口即可,不用再修改源代码。同时,也保持了类的专一性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值