0x00 前言
试问,哪个帝王不想开疆拓土,成就万世之霸业,流传千古?!
朕,虽坐享盛世,仍不忘对外扩张以彰显国威。
近日上朝,有大臣上奏,近邻女儿国因缺乏壮丁,国力衰弱,正是入侵的最好时机。朕当然批准出兵讨伐。
这下可坏事了,朕的皇后听闻此事后,大怒!!!不再与朕言语。晚上都不让进屋了......
朕虽不才,但麾下谋士无数。找来国师gg商议。国师倒也给力,赠与朕妙计三方。依时机使用即可。
这三个妙计分别是:
- 夸皇后漂亮
- 给皇后送礼物
- 带皇后去看戏剧
想想看,这三个妙计有什么相似之处?这些妙计都需要朕去做些什么,也就是说,三个妙计都需要一个执行方法。至于执行方法的的内容,则由妙计决定。
0x01 论怎样哄女孩儿之策略模式
先上一个类图看看。三个妙计都实现了IStrategy接口,每一个妙计都有一个operate方法,里面是具体的妙计内容。
光有妙计还不行,我们还需要一个地方来承载妙计,这就是锦囊。下面的Context就是一个锦囊类。它负责承载和执行锦囊。
1. 代码清单 IStrategy 接口
接口很简单,就一个方法。
public interface IStrategy {
public void operate() ;
}
2. 代码清单 PraiseStrategy类
朕来对付皇后的三个策略:夸奖、送礼、陪玩。
下面写出来一个,剩下的就不再列代码了。详细代码可以看github。
public class PraiseStrategy implements IStrategy{
@Override
public void operate() {
System.out.println("yyj,你是天下第一美人~");
}
}
3. 代码清单 Context类
这是锦囊类,代码也很简单。它主要来承载妙计。
public class Context {
private IStrategy strategy;
public Context(IStrategy strategy) {
this.strategy = strategy;
}
public void operate() {
this.strategy.operate();
}
}
4. 代码清单 Emperor类
最后来看一下朕的动作。每次拿出来一个锦囊,然后执行其中妙计。
public class Emperor {
public static void main(String[] args) {
//拿出朕的锦囊
Context context;
System.out.println("------皇后十分不高兴,正在扔瓶子。拆开第一个锦囊!------");
//拿出妙计
context = new Context(new PraiseStrategy());
//实施妙计
context.operate();
System.out.println("------皇后依旧不高兴,不理朕。拆开第二个锦囊!------");
//拿出妙计
context = new Context(new SendGiftStrategy());
//实施妙计
context.operate();
System.out.println("------皇后态度稍缓,但仍一脸寒霜。拆开第三个锦囊!------");
//拿出妙计
context = new Context(new WatchDramaStrategy());
//实施妙计
context.operate();
System.out.println("------皇后总算好了,不再生气了。朕可以发兵打仗了!!!------");
}
}
看一下执行结果。看看,一个妙计不行,就上俩,俩还不行,就来仨。最后把皇后哄开心了吧!
女孩子就是这样哄才行嘛。
------皇后十分不高兴,正在扔瓶子。拆开第一个锦囊!------
yyj,你是天下第一美人~
------皇后依旧不高兴,不理朕。拆开第二个锦囊!------
yyj,我摘了个小一点的太阳当礼物送给你暖暖手~
------皇后态度稍缓,但仍一脸寒霜。拆开第三个锦囊!------
走!朕带你去看戏!
------皇后总算好了,不再生气了。朕可以发兵打仗了!!!------
0x02 扩展型策略模式(策略枚举)
上面已经描述了策略模式长什么样子,但是呢,这个用起来毕竟不是那么顺手,朕用一个妙计,还得先弄一个锦囊,再弄出来妙计,再执行,而且每个妙计都得写一个类,反正不管怎么样就是看着没那么爽。
下面呢,要对它做一些扩展,让它看起来更厉害一点。这就是策略枚举了
1. 代码清单 Strategies枚举
这个看代码就能看出来。我们把所有的策略都写到了枚举中。相当于每个枚举成员就成了一个具体的策略。而且读起来也更容易让人理解。
public enum Strategies {
WatchDrama {
public void operate() {
System.out.println("走!朕带你去看");
}
},
SendGift {
public void operate() {
System.out.println("yyj,我摘了个小一点的太阳当礼物送给你暖暖手~");
}
},
Praise {
public void operate() {
System.out.println("yyj,你是天下第一美人~");
}
};
public abstract void operate();
}
2. 代码清单 Emperor类
看,执行类是不是也简单了,这样子更像是拿出来今年,然后执行了妙计。运行结果和之前一样,就不再贴出来了。
System.out.println("------皇后十分不高兴,正在扔瓶子。拆开第一个锦囊!------");
//拿出妙计,实施妙计
Strategies.Praise.operate();
System.out.println("------皇后依旧不高兴,不理朕。拆开第二个锦囊!------");
//拿出妙计,实施妙计
Strategies.SendGift.operate();
System.out.println("------皇后态度稍缓,但仍一脸寒霜。拆开第三个锦囊!------");
//拿出妙计,实施妙计
Strategies.WatchDrama.operate();
System.out.println("------皇后总算好了,不再生气了。朕可以发兵打仗了!!!------");
3. 注意
策略枚举是一个非常优秀和方便的模式,但是它受枚举类型的限制,每个枚举项都是public、final、static的,扩展性受到了一定的约束,因此在系统开发中,策略枚举一般担当不经常发生变化的角色。
网友评论