策略模式
定义
定义一组算法,将每个算法都封装起来,并且在使用时使它们之间可以自由互换。
通用类图
分析
从策略模式的类图来看,主要有以下三个角色:
- Context,也即策略的持有者。在开发过程有时也没有这个角色,但是通过该角色持有策略,可以使业务逻辑与具体的策略解耦,使代码架构更加灵活。
- IStrategy,策略接口,所有的策略都需要实现该接口,方便在不同策略之间切换。
- ConcreteStrategyA、ConcreteStrategyB等,是具体的策略提供者,实现了具体的算法或业务逻辑。
从类图中可以看出,每个策略算法都互不干扰,且可自由替换。 这个就有点像电动车的换电策略一样。车子没电了,只要接口相同,既可以换锂电池,也可以更换铅酸电池等各种不同类型电池。
练习
假设在android开发过程中,针对不同的图片计算出不同的采样率。 由此可以分析出,根据规则要设计出多个算法,此时就可以使用策略模式。
// 定义采样接口
public interface ISampler {
int getSampler();
}
// 具体的采样策略
public SamplerStrategyA implements ISampler {
public int getSampler() {
// 具体采样规则,比如宽高各大于100时,采样直接设定为2
// if (width > 100 && height > 100) {
// return 2;
// }
}
}
// 同理其他的采样算法策略
// 策略持有类
public class SamplerContext {
public ISampler sampler;
public SamplerContext(ISampler sampler) {
this.sampler = sampler;
}
public int getBitmapSamplerSize() {
return sampler.getSampler();
}
}
// 客户端逻辑
public class Client {
public void static main(String[] args) {
ISampler sampler = new SamplerStrategyA(); // 可以根据业务随时更换此处的策略算法。
SamplerContext context = new SamplerContext(sampler);
int samplerSize = context.getBitmapSamplerSize();
}
}
使用策略模式,可以一定程度上减少if-else的判断,让代码更加容易维护。 在《设计模式之禅》一书中,同时提出了可以使用枚举策略来简化策略模式的代码,即将每个策略都放在一个枚举量中,在需要使用对应的策略时,只需要引用枚举常量就可以了。个人感觉这个有点类似于将策略算法放到map中,然后使用时通过key找到对应的策略算法。具体使用,可以参考《设计模式之禅》。
总结
策略模式,让我想到了电视剧《西游记》中孙悟空对妖怪说的一段台词,“这颗是拜佛求经的诚心、这是普济众生的佛心、这是悲天悯人的善心、这是救苦救难的慈心、这是矢志不渝的衷心、这是降妖除怪的决心,你想要哪颗心?“
具体要啥心(策略),由你(业务)来选。
优点 | 缺点 |
---|---|
1、策略模式符合开闭原则 2、减少了if-else的调用 3、易于扩展和维护。 | 1、客户端必须知道所有的策略,并自行决定需要使用的策略。 2、当策略过多时会产生较多策略类,不易维护。 3、有悖于迪米特法则。 |