策略模式

1. 概念

定义一系列的算法,把他们一个个封装起来,并且使他们可互相替换。本模式使得算法可独立于使用它的客户端而变化。


image.png

2. 使用场景

一个类定义了多种行为,并且这些行为在这个类的方法中以多个条件语句的形式出现,那么可以使用策略模式避免在类中使用大量的条件语句。

3. 实例

interface AbstractStrategy {
    int calculatePrice(int km);
}
public class BusStrategy implements AbstractStrategy{

    @Override
    public int calculatePrice(int km) {
        int extraTotal = km - 10;
        int extraFactor = extraTotal / 5;
        int faction = extraFactor % 5;
        int price = 1 + extraFactor % 5;
        return faction > 0 ? ++price : price;
    }
}
public class SubwayStrategy implements AbstractStrategy {
    @Override
    public int calculatePrice(int km) {
        if (km <= 6) {
            return 3;
        } else if (km > 6 && km < 12) {
            return 4;
        } else if (km > 12 && km < 24) {
            return 5;
        } else if (km > 24 && km < 32) {
            return 6;
        }
        return 7;
    }
}
public class Context {
    private AbstractStrategy strategy;

    public void setStrategy(AbstractStrategy strategy) {
        this.strategy = strategy;
    }

    public int caculatePrice(int km) {
        return strategy.calculatePrice(km);
    }
}
public class Client {
    public static void main(String[] args) {
        Context calculate = new Context();
        calculate.setStrategy(new BusStrategy());
        System.out.println("公交车20km价格:" + calculate.caculatePrice(20));
    }
}

如果不用到策略模式,而是简单地添加if判断条件:

public class PriceCalculate {
    private static final int BUS = 1;
    private static final int SUBWAY = 2;

    public static void main(String[] args) {
        PriceCalculate priceCalculate = new PriceCalculate();
        System.out.println("做20km公交票价:" + priceCalculate.calculatePrice(11, BUS));
    }

    /**
     * 公交计价,10公里之内1块钱,超过10公里每5公里1块钱
     *
     * @param km
     * @return
     */
    private int busPrice(int km) {
        int extraTotal = km - 10;
        int extraFactor = extraTotal / 5;
        int faction = extraFactor % 5;
        int price = 1 + extraFactor % 5;
        return faction > 0 ? ++price : price;
    }

    /**
     * 地铁售价
     * @param km
     * @return
     */
    private int subwayPrice(int km) {
        if (km <= 6) {
            return 3;
        } else if (km > 6 && km < 12) {
            return 4;
        } else if (km > 12 && km < 24) {
            return 5;
        } else if (km > 24 && km < 32) {
            return 6;
        }
        return 7;
    }

    public int calculatePrice(int km, int type){
        if (type==BUS){
            return busPrice(km);
        } else if (type==SUBWAY){
            return subwayPrice(km);
        }
        return 0;
    }
}

这样当添加新的策略时,不好维护,而且耦合度比较高。

4. 特点

上下文context与具体策略是松耦合关系
策略模式满足“开-闭原则”

5. 在android中的应用

Volley中对于HttpStack的设计

推荐阅读更多精彩内容