设计模式之策略模式

时间:2022-05-05 00:20:42

在《设计模式之状态模式》中简单对状态模式的概念进行了讲解,其核心思想就是随着状态的变化,导致状态持有者执行不同的行为。比如饥饿状态下,你会去点个外卖;吃饱状态下,你可能会去大街上溜达看妹子等。本篇对另外一个设计模式进行简单分析:策略模式,该模式看UML图的话,咋一看跟状态模式很像,但是还是有很大的区别的。

何为策略?策略就是为达到某种目标而提供的方案集合。且完成某目标需要根据不同的形式而制定不同的方针,具有动态性和可替换性。

策略模式的定义:一个类的行为或其算法可以在运行时更改,策略对象改变目标对象(Context)的执行算法。也就是说不同的策略会决定实现目标的具体方式。查阅各种策略模式的资料,可以知道该模式的主要目的是:动态的切换不同的策略(算法),产出具有共同特质的结果或者行为,且策略的切换不会影响到客户端。比如去旅游,你可以坐高铁、骑车、开车、坐飞机等等不同的方式达到旅游景点。这正是策略模式与状态模式的核心区别:状态模式状态改变了,状态持有者产出的是不同特质的结果或者行为,明显对客户端造成了影响。比如天气状态好的情况下,你会去旅游;天气状态不好的状态下,你的行为可能就是钻被窝里玩手机抑或是睡大觉了。

其实策略模式这玩意儿古人早就发明出来了,著名的《孙子兵法》和《三十六计》不正式策略模式的应用,其思想不就是为了达到克敌制胜的目的而采取不同的策略吗。所谓此计不成,由生一计,策略模式的应用不外如是,比如当年东吴为了获取荆州不也是采取了各种计策吗:现实派鲁肃去刘备出索要,不得;而后采取美人计,赔了夫人又折兵;再后来邀请关于赴宴,为关羽留下单刀赴会的假话;最终吕蒙白衣渡江,最总获取了荆州。

上面说的着实有点啰嗦,因为各种资料里面都有策略模式的UML图,本篇博文就偷懒,以一个小demo来结束本篇博文。
先定义一个获取荆州的策略接口:

public interface GetJingZhouStrategy {
void doOperation();
}

简单的罗列下具体各个接口的具体实现:

 class AskForJingZhou implements GetJingZhouStrategy {
@Override
public void doOperation() {
System.out.println("派遣鲁肃去刘备处索要--->未果");
}
}

//美人计
class BeautyTrapStrategy implements GetJingZhouStrategy {
@Override
public void doOperation() {
System.out.println("将孙尚香嫁给刘备-->未果");
}
}

//鸿门宴
class BanquetStrategy implements GetJingZhouStrategy {
@Override
public void doOperation() {
System.out.println("鸿门宴邀请关羽赴会-->未果");
}
}

//江陵之战
class WarOfJiangLingStrategy implements GetJingZhouStrategy {
@Override
public void doOperation() {
System.out.println("吕蒙白衣渡江-->功成");
}
}

荆州目标类:


public class JingZhou {
private GetJingZhouStrategy strategy;

public JingZhou(GetJingZhouStrategy getJingZhouStrategy) {
strategy = getJingZhouStrategy;
}

public void doAction() {
strategy.doOperation();
}

}

最总吕子明白衣渡江,关羽败走麦城被擒杀,东吴获取了荆州!
其实再平时的开发中也能体会到策略模式的存在,比如一下几种情况:
1、图片缓存策略,不同的缓存算法提供了不同能力的缓存,比如磁盘缓存,内存缓存等等,最终的目的都是缓存图片
2、android 开发中的图片框架,Fresco,ImageLoader,Glide等等框架,这些框架也可以看作是策略模式的应用,你可以选择任意一个框架来完成图片加载的功能。
3、网络请求框架:Volley,Okhttp等等,你可以选择一个请求框架来完成网络访问的功能。
各种例子,不胜枚举。

到此为止,本篇博文结束,至于策略模式的优缺点,在此就不再赘述了。