持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
设计模式 —— 策略模式
如果你读过《三国》,可能会知道一个“锦囊妙计”的故事,当时刘备娶亲,前往东吴,诸葛亮不能陪在主公的身边,因此给了三个锦囊,里面有他写好的计策,给了陪同刘备前去的赵云,并且一再嘱咐每个锦囊应当在什么时候打开,最终刘备抱得美人归,而周郎则是赔了夫人又折兵
由这个故事引出今天的主角——策略模式,那么,二者的关联何在呢?
客官不要急,听我细细道来~
1. 关键词
首先,我们先画下重点,从故事中找出一些关键的词句:
娶亲、三个、锦囊、写好的计策、适当的时机(总结可得)
娶亲:这是我们要做的事情,目的就是这个,刘备要娶了孙家小姐并且平安回来,这便对应了代码具体需要实现的功能,或者说是客户的需求
三个:这是个量词,说明有多个计策、锦囊备选,对应于代码便是多个类或者功能模块
锦囊:包起来的,不打开你看不到,在代码层面代表的就是对于算法的封装
写好的计策:解决问题的办法,代码层面上解决问题的办法不正是一个个算法吗?
适当的时机:我们经常说看情况而定之类的,其实就是需要根据对应条件或者说环境,使用相应的策略解决问题
好了,经过这么一分析,基本上就已经把策略模式的定义整出来了...
总结一下:
对于解决一类问题我们有多种方案,根据具体的场景而定,对这些解决问题的方案进行封装,彼此间相互独立,可以灵活切换
2. 结构分析
这里给出了策略模式的UML简图,简要的解释一下:
Context在这里代表的是环境,更确切地表述就是你选择某个策略的依据,在你面临具体的问题时做出对应的决策,这需要条件
那么,既然你要做出决策,你的决策与环境间就建立了关联,环境中的条件诱导你做出某种决策,因此提供了stragety成员,代表了持有的关系
Stragety作为一个接口存在,代表的是一种标准和共性,就比如刘备娶亲,它共同的目的就是保证刘备去江东娶到孙家小姐并且平安返回,而具体需要做什么来保证,这便是策略的具体内容了,也是接口实现所需要关注的,下面的三个接口实现类便是做的这件事,当然,策略可以使任意个,只需保证它们的目的一致
3. 代码实现
感觉好像结构捋得差不多了?那就来实践一下
/**
* 妙计接口
* @author 诸葛亮
*/
public interface GoodPlan {
/**
* 保命
*/
void saveLife();
}
妙计用来保命,军师已经想清楚了
/**
* 妙计一: 到江东就打开
* @author 诸葛亮
*/
public class PlanA implements GoodPlan {
@Override
public void saveLife() {
System.out.println("大肆宣扬,让大家伙都知道,尤其是乔国老和吴国太");
// 一段时间后
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("效果拔群,良辰吉日,甘露寺成亲,婚礼现场防护get");
}
}
/**
* 妙计二:年底打开
* @author 诸葛亮
*/
public class PlanB implements GoodPlan {
@Override
public void saveLife() {
System.out.println("告诉主公荆州危机,设法离开");
try {
// 思前想后,想到办法
Thread.sleep(2000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("主公偷偷开溜~~");
}
}
/**
* 妙计三:紧急关头打开
* @author 诸葛亮
*/
public class PlanC implements GoodPlan {
@Override
public void saveLife() {
System.out.println("声情并茂地向孙夫人揭露周瑜的行为,夫人开路");
try {
Thread.sleep(500L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("各路援军陆续赶到救驾,顺便刺激下周瑜脆弱的神经~");
}
}
然后是三条妙计,分别装在三个锦囊中
/**
* 外界的情况
*/
public class Context {
private GoodPlan goodPlan;
public Context(GoodPlan goodPlan) {
this.goodPlan = goodPlan;
}
/**
* 时机到来,需要保命
*/
public void opportunityComes() {
goodPlan.saveLife();
}
}
看情况而定,就做这件事,等待时机
/**
* 历史的舞台
*/
public class Stage {
public static void main(String[] args) {
Context context;
// 时机
System.out.println("到了江东");
context = new Context(new PlanA());
context.opportunityComes();
try {
Thread.sleep(3000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("年底了");
context = new Context(new PlanB());
context.opportunityComes();
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("危急关头");
context = new Context(new PlanC());
context.opportunityComes();
}
}
最终的故事则是在历史的舞台上上演,大致就是这样吧😂
算是策略模式简单的实践吧,如果有什么错误还请多多指正,也欢迎提出建议~~