8、Android设计模式---(时势造英雄)策略模式

一、介绍,定义

策略模式定义了一系列的算法,并将每一个封装起来,而且使它们可以相互替换。策略模式让算法模式独立于使用它的客户而独立变化。

二、使用场景

针对同一类型的问题的多种处理方式,仅仅是具体行为有差别时。
需要安全地的封装多种同一类型的操作时。
出现同一抽象类有多个子类,而又需要if-else或者switch-case来选择具体子类时。

三、UML类图

Context :用来操作策略的上下文环境;
Stragety:策略的抽象;
StagetyA、StagetyB:具体的策略的实现

四、简单实现

根据公里数,计算公交车和地铁的票价
最初版本:

public class PriceCalculator{
    //公交车
     private static final int BUS = 1;
    //地铁
    private static final int SUBWAY = 2;
    public static void main(String [] args){
        PriceCalculator ca = new PriceCalcluator();
        System.out.println("16公里公交票价:"+ca.calculatePrice(16,SUBWAY ));
        System.out.println("16公里地铁票价:"+ca.calculatePrice(16,BUS));
    }
    //十公里内1元,超过十公里后,每加一元可乘5公里
    private int busPrice(int km){
        int extraTotal = km-10;
        int extraFactor = extraTotal/5;
        int fraction = extraTotal %5'
        int price = 1+extraFactor*1;
        return fraction >0?++price:price; 
    }
    //6公里内3元,6-12公里4元,12-22公里5元,22-32公里6元
    private int subwayPrice(int km){
        if(km<6){
            return 3;
        }else if(km>6&&km<12){
            return 4;
        }else if(km>12&&km<22){
            return 5;
        }else if(km>22&&km<32){
            return 6;
        }
         return 7;//其他简化为7
    }

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

每增加一种出行方式,就要在PriceCalculator中添加一个方法计算出租车出行的价格,并在calculatePrice中添加一个判断,各种if-else缠绕其中。下面用策略模式重构:
定义一个抽象的价格计算接口:

public interface CalculatorStrategy{
    int calculatePrice(int km);
}

每种方式都实现了此接口:

public class BusStrategy implements CalculatorStrategy{
    @Override
    public int calculatePrice(int km){
        int extraTotal = km-10;
        int extraFactor = extraTotal/5;
        int fraction = extraTotal %5'
        int price = 1+extraFactor*1;
        return fraction >0?++price:price; 
    }
}
public class SubwayStrategy implements CalculatorStrategy{
    @Override
    public int calculatePrice(int km){
        if(km<6){
            return 3;
        }else if(km>6&&km<12){
            return 4;
        }else if(km>12&&km<22){
            return 5;
        }else if(km>22&&km<32){
            return 6;
        }
         return 7;//其他简化为7
    }
}

再创建一个扮演Context角色的类

public class TranficCalculator{
    public static void main(String[]args){
        TranficCalculator ca = new TranficCalculator();
        //设置计算策略
        ca.setStrategy(new BusStrategy);
        //计算价格
        System.out.println("16公里公交票价:"+ca.calculatePrice(16));
    }
    CalculatorStrategy mStrategy;
    public void setStrategy(CalculatorStrategy mStrategy){
        this.mStrategy = mStrategy;
    }
    public int calculatePrice(int km){
      return mStrategy.calculatePrice(km);
    }
}

这样当我们有新的方式时,只要添加一个计算类后设置给TranficCalculator 即可。

五、模式的优缺点:

策略模式主要用来分离算法,根据相同的行为抽象来做不同的具体策略实现。很好的实现了开闭原则,也就是定义抽象,注入具体实现,从而达到很好的可扩展性。

优点
使用了组合,使架构更加灵活
富有弹性,可以较好的应对变化(开闭原则)
更好的代码复用性(相对于继承)
消除大量的条件语句

缺点
随着策略的增加,子类也会变得繁多。
选择何种算法需要客户端来创建对象,增加了耦合,这里可以通过与工厂模式结合解决该问题

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章