策略模式 Strategy Pattern
- 介绍:实现某个功能可以有多种算法或者策略,根据实际情况来选择不同的的算法和或者策略来完成该功能。
- 定义:在策略模式中,定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。
-
使用场景:
- 针对同一类问题的多种解决方式,仅仅是具体行为逻辑有差别。
- 需要安全地封装多种同一类型的操作;
- 在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。
- 如何使用:实现同一个接口,将这些算法封装成一个一个的类,任意地替换。
- 生活例子:1.旅行的出游方式,单车地铁飞机;2.游戏锦囊;
- 在Android中的例子:属性动画的时间插值器;
-
注意事项:如果一个系统的策略多于四个,就需要考虑使用
混合模式
,解决策略类膨胀的问题。
优点
- 结构清晰明了,使用简单直观;
- 算法可以自由切换;
- 避免使用多重条件判断;
- 扩展性良好;
缺点
- 随着策略类的增多,子类也会变得繁多;
- 所有策略类都需要对外暴露;
策略模式与状态模式的比较
-
状态模式
的类图和策略模式
类似,并且都是能够动态改变对象的行为。 - 但是状态模式是通过状态转移来改变 Context 所组合的 State 对象
(被动)
,而策略模式是通过 Context 本身的决策来改变组合的 Strategy 对象(主动)
。 - 状态模式主要是用来解决状态转移的问题,当状态发生转移了,那么 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元
网友评论