策略模式

96
锐_nmpoi
2017.04.19 19:41* 字数 691

在上一篇文章中,介绍了插值器的重用。从源码中我们得知到我们可以为动画设置不同的插值器。最后使用到插值器的功能只是他所提供的统一接口:getInterpolation。

由上面我们我可以把他抽象出来,那么插值器使用就是一个典型的策略者模式。当我们实现一个功能时,可能根据不同的情况,我们将使用不同的算法、策略,我们可以根据实际情况选择不同的算法或者策略来完成这一个功能。

在我们编码的时候,遇到这种多情况的问题,我们通常就会使用 if...else 、 switch ..case 来选择相应的条件,最后根据条件,我们就可以选中要调用的方法。我们通常把这一种的实现的方式称作为 硬编码 。这样编写会使得类变得臃肿,同时也使类的维护成本变高。当我们要增加相应的条件的时候,不得不修改内部的源代码,这样会破坏类的封装性。

但是我们把这些算法或者策略抽象出来,并提供方一个统一的接口,那么使不同的算法和策略有不同的实现类,那么在程序中我们就可以通过注入不同的实现对象来实现不同的算法,实现动态替换的效果。这样既便于扩展也便于维护。

策略模式的定义

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

使用场景

针对同一种问题的多种处理方式,仅仅是具体行为有差别时。

例子

下面的例子是:在距离相同的情况下,根据不同的出行方式,计算所需得到价格

计算接口,提供统一的调用接口

public interface CalculateStrategy {

    int calculatePrice(int km);

}

公交车出行的价格

public class BusStrategy implements CalculateStrategy {

    //十公里以内一元钱,超过十公里后每加一元可多乘 5公里
    @Override
    public int calculatePrice(int km) {
        int extraTotal = km - 10;
        int extraFactor = extraTotal / 5;
        int fraction = extraTotal % 5;
        int price = 1 + extraFactor;
        return fraction > 0 ? ++price : price;
    }

}

地铁出行的价格

public class SubwayStrategy implements CalculateStrategy {

    //地铁乘坐不同公里数,所付钱不同
    @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;
    }

}

出租车出行的价格

public class TaxiStrategy implements CalculateStrategy {

    //出租车的价格
    @Override
    public int calculatePrice(int km) {
        if(km < 10){
            return 10;
        }else{
            int i = km-10;
            return 10 + i*3;
        }
    }

}

用于管理使用具体哪个策略

public class TranficCalculator {

    CalculateStrategy mStrategy ;

    public void setStrategy(CalculateStrategy mStrategy) {
        this.mStrategy = mStrategy;
    }
    
    public int calculatePrice (int km){
        return mStrategy.calculatePrice(km);
    }
}

使用策略模式

public class Main {
    public static void main(String[] args) {
        TranficCalculator tranficCalculator = new TranficCalculator();
        //这里使用不同的类 达到使用不同的策略。
        tranficCalculator.setStrategy(new BusStrategy());
        int busPrice = tranficCalculator.calculatePrice(20);
        tranficCalculator.setStrategy(new SubwayStrategy());
        int subwayPrice = tranficCalculator.calculatePrice(20);
        tranficCalculator.setStrategy(new TaxiStrategy());
        int taxiPrice = tranficCalculator.calculatePrice(20);
        System.out.println("busPrice:"+busPrice);
        System.out.println("subwayPrice:"+subwayPrice);
        System.out.println("taxiPrice:"+taxiPrice);
    }
}

运行结果:

busPrice:3

subwayPrice:5

taxiPrice:40

优缺点

优点

  1. 结构清晰明了、使用简单直观;
  2. 耦合度相对而言较低,扩展方便;
  3. 操作封装也更为彻底,数据更为安全。

缺点

随着策略的增加,子类也会变的繁多。

事件分发