xSong'blog

3设计模式之策略模式

2020-02-28
阅读量

策略模式 Strategy Pattern

  • 介绍:实现某个功能可以有多种算法或者策略,根据实际情况来选择不同的的算法和或者策略来完成该功能。
  • 定义:在策略模式中,定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。
  • 使用场景
    1. 针对同一类问题的多种解决方式,仅仅是具体行为逻辑有差别。
    2. 需要安全地封装多种同一类型的操作;
    3. 在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。
  • 如何使用:实现同一个接口,将这些算法封装成一个一个的类,任意地替换。
  • 生活例子:1.旅行的出游方式,单车地铁飞机;2.游戏锦囊;
  • 在Android中的例子:属性动画的时间插值器;
  • 注意事项:如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。

优点

  1. 结构清晰明了,使用简单直观;
  2. 算法可以自由切换;
  3. 避免使用多重条件判断;
  4. 扩展性良好;

缺点

  1. 随着策略类的增多,子类也会变得繁多;
  2. 所有策略类都需要对外暴露;

策略模式与状态模式的比较

  1. 状态模式的类图和策略模式类似,并且都是能够动态改变对象的行为。
  2. 但是状态模式是通过状态转移来改变 Context 所组合的 State 对象(被动),而策略模式是通过 Context 本身的决策来改变组合的 Strategy 对象(主动)
  3. 状态模式主要是用来解决状态转移的问题,当状态发生转移了,那么 Context 对象就会改变它的行为(开关);而策略模式主要是用来封装一组可以互相替代的算法族,并且可以根据需要动态地去替换 Context 使用的算法(替换)

所谓的状态转移,是指 Context 在运行过程中由于一些条件发生改变而使得 State 对象发生改变,注意必须要是在运行过程中。

简而言之,状态模式就是开关发生变化的时候变化,而策略模式就是方法的替换。

strategy_pattern_uml.jpg


实例代码

1.创建一个接口类

public interface TripMethods {
    public int doTrip(int km);
}

2.创建实现接口的实体类

public class TripBicycle implements TripMethods {
    @Override
    public int doTrip(int km) {
        return 0;
    }
}
public class TripBus implements TripMethods {
    @Override
    public int doTrip(int km) {
        return 2;
    }
}
public class TripTexi implements TripMethods {
    @Override
    public int doTrip(int km) {
        return km * 12;
    }
}

3.创建 Context 类

public class Travel {
    private TripMethods mTripMethods;
    public Travel() {
    }
    public void setTripMethods(TripMethods tripMethods) {
        this.mTripMethods = tripMethods;
    }
    public int GoOut(int km) {
        return mTripMethods.doTrip(km);
    }
}

4.改变策略得实现

public class JanpanTravel {
    public static void main(String[] args) {
        int Spend = 0;
        Travel travel = new Travel();

        travel.setTripMethods(new TripBus());
        Spend = travel.GoOut(12);
        System.out.println("出门去日本旅行花费了" + Spend + "元");

        travel.setTripMethods(new TripBicycle());
        Spend = travel.GoOut(12);
        System.out.println("出门去日本旅行花费了" + Spend + "元");

        travel.setTripMethods(new TripTexi());
        Spend = travel.GoOut(12);
        System.out.println("出门去日本旅行花费了" + Spend + "元");
    }
}

5.输出结果

出门去日本旅行花费了2元 出门去日本旅行花费了0元 出门去日本旅行花费了144元


Similar Posts

Comments