1. 前文汇总

「补课」进行时:设计模式系列

2. 游戏中的策略模式

我是一个很喜欢玩游戏的人,周末在家打打游戏是真的很开心。

回想起来当年上大学的往昔峥嵘岁月,那时候基本上是一个人在玩游戏,背后围着好几个人看,一个个的充当着狗头军师的作用。

时间长了就能发现,喜欢看别人打游戏的人,往往自己玩的都不怎么样,但是当起狗头军师来那是一套一套的,难道这就是旁观者清?

当年在大学宿舍玩的最多还是「英雄联盟」,当年还是 AP 剑圣横行天下,然而每次排位遇到的都是别人家的剑圣和我方剑圣。

这时候,一般就是狗头军师上线的时候,你出这个 xxx ,保证你如何如何牛皮,哎呀,你先打谁谁谁啊,为啥老要追着一个肉砍。

如果把上面这个场景转化成写程序,基本上是这样的:

首先定义一个 LOL 的接口:

public interface LOL {void playMethod();
}

然后再来两个狗头军师实现这个接口,每个狗头军师都有自己的玩法:

public class DogStrategistA implements LOL{@Overridepublic void playMethod() {System.out.println("先出攻击装,刚正面,不怂");}
}public class DogStrategistB implements LOL {@Overridepublic void playMethod() {System.out.println("先出防御装,站得住才有输出");}
}

接着,我们开启一局游戏:

public class LOLGame {private LOL lol;public LOLGame(LOL lol) {this.lol = lol;}public void play() {this.lol.playMethod();}
}

然后下面是一个测试类:

public class Test {public static void main(String[] args) {LOLGame game;System.out.println("狗头军师A的点子--------------");game = new LOLGame(new DogStrategistA());game.play();System.out.println("狗头军师B的点子--------------");game = new LOLGame(new DogStrategistB());game.play();}
}

最后的执行结果如下:

狗头军师A的点子--------------
先出攻击装,刚正面,不怂
狗头军师B的点子--------------
先出防御装,站得住才有输出

是不是感觉上面这串代码好像和平时写的没啥区别,然而你并没有猜错,这就是策略模式。

3. 策略模式

3.1 定义

策略模式(Strategy Pattern)是一种比较简单的模式,也叫做政策模式(PolicyPattern)。其定义如下:

Define a family of algorithms,encapsulate each one,and make theminterchangeable.(定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。)

  • Context: 封装角色,起承上启下封装作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。
  • Strategy: 抽象策略角色,策略、算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性。
  • ConcreteStrategy: 具体策略角色。

通用代码如下:

public interface Strategy {void doSomethinging();
}public class ConcreteStrategy1 implements Strategy {@Overridepublic void doSomethinging() {System.out.println("具体策略1");}
}public class ConcreteStrategy2 implements Strategy {@Overridepublic void doSomethinging() {System.out.println("具体策略2");}
}public class Context {private Strategy strategy;public Context(Strategy strategy) {this.strategy = strategy;}public void doAnything() {this.strategy.doSomethinging();}
}public class Test {public static void main(String[] args) {Strategy strategy = new ConcreteStrategy1();Context context = new Context(strategy);context.doAnything();}
}

3.2 优点

  • 算法可以自由切换:这是策略模式本身定义的,只要实现抽象策略,它就成为策略家族的一个成员,通过封装角色对其进行封装。
  • 避免使用多重条件判断:如果没有策略模式,那么我们只能选择使用多重条件判断语句,多重条件语句不易维护,而且出错的概率大大增强。使用策略模式后,可以由其他模块决定采用何种策略,策略家族对外提供的访问接口就是封装类,简化了操作,同时避免了条件语句判断。
  • 扩展性良好:这甚至都不用说是它的优点,在现有的系统中增加一个策略太容易了,只要实现接口就可以了。

3.3 缺点

  • 策略类数量增多:每一个策略都是一个类,复用的可能性很小,类数量增多。
  • 所有的策略类都需要对外暴露:上层模块必须知道有哪些策略,然后才能决定使用哪一个策略,这与迪米特法则是相违背的,我只是想使用了一个策略,我凭什么就要了解这个策略呢?那要你的封装类还有什么意义?这是原装策略模式的一个缺点,幸运的是,我们可以使用其他模式来修正这个缺陷,如工厂方法模式、代理模式或享元模式。

如果系统中的一个策略家族的具体策略数量超过 4 个,则需要考虑使用混合模式,解决策略类膨胀和对外暴露的问题。

您的扫码关注,是对小编坚持原创的最大鼓励:)

「补课」进行时:设计模式(11)——游戏中的策略模式相关推荐

  1. 「补课」进行时:设计模式(5)——从 LOL 中学习代理模式

    1. 前文汇总 「补课」进行时:设计模式系列 2. 从 LOL 中学习代理模式 我是一个很喜欢玩游戏的人,虽然平时玩游戏的时间并不多,但我也是一个忠实的 LOL 的爱好者,就是段位有点惨不忍睹,常年倔 ...

  2. 「补课」进行时:设计模式(15)——观察者模式

    1. 前文汇总 「补课」进行时:设计模式系列 2. 观察者模式 2.1 定义 观察者模式(Observer Pattern)也叫做发布订阅模式(Publish/subscribe),它是一个在项目中经 ...

  3. 「补课」进行时:设计模式(6)——郭靖大侠带你学原型模式

    1. 前文汇总 「补课」进行时:设计模式系列 2. 找工作 这一天,郭靖大侠因为在桃花岛调戏侍女被黄蓉打出了桃花岛,这下可玩大了,从桃花岛被赶出来吃啥喝啥啊,得赶紧找份工作,西北风可喝不饱肚子哇~~~ ...

  4. 「补课」进行时:设计模式(20)——解释器模式

    1. 前文汇总 「补课」进行时:设计模式系列 2. 解释器模式 解释器模式这个模式和前面的访问者模式比较像,当然,我说的比较像是难的比较像,以及使用率是真的比较低,基本上没有使用的场景,访问者模式还有 ...

  5. 游戏设计模式思考:“穿越火线”中的“策略模式”

    前言:在前段时间陆陆续续在博客园更新了一系列关于重构的文章.在重构我们既有的代码时,往往会用到设计模式.在之前重构系列的文章中,我们在重构时用到了"工厂模式"."策略模式 ...

  6. 有赞前端 UI框架「Vant」在离线无网络环境中使用 icon 无法显示的问题

    有赞前端 UI框架「Vant」在离线无网络环境中使用 icon 无法显示的问题 第一次使用这个框架.UI组件中规中矩,很简洁,不是特别多,基本够用.Vant 官网 在内网中部署 Vue+Vant的项目 ...

  7. 设计模式随笔系列:鸭子-策略模式(Strategy)[原]

    原文地址为: 设计模式随笔系列:鸭子-策略模式(Strategy)[原] 鸭子-策略模式(Strategy) 前言 万事开头难,最近对这句话体会深刻!这篇文章是这个系列正式开始介绍设计模式的第一篇,所 ...

  8. Java设计模式(十二) 策略模式

    策略模式介绍 策略模式定义 策略模式(Strategy Pattern),将各种算法封装到具体的类中,作为一个抽象策略类的子类,使得它们可以互换.客户端可以自行决定使用哪种算法. 策略模式类图 策略模 ...

  9. 设计模式(一):“穿越火线”中的“策略模式”(Strategy Pattern)

    在前段时间呢陆陆续续的更新了一系列关于重构的文章.在重构我们既有的代码时,往往会用到设计模式.在之前重构系列的博客中,我们在重构时用到了"工厂模式"."策略模式" ...

最新文章

  1. 修正本地乱码(待补充)
  2. bootstrap配置Nacos出现Param ‘serviceName‘ is illegal, serviceName is blank
  3. Python基础day05【函数应用:学生管理系统、拆包、今日总结】
  4. React Native中pointerEvent属性
  5. 秋风到,ModelArts“ AI市场算法Fast-SCNN指南”秋膘贴起来
  6. 免费ftp网站服务器软件,免费ftp服务器软件,免费ftp服务器软件有哪些呢?好用推荐...
  7. python模拟键盘输入+切换键盘布局
  8. [转]sqlserver 创建分区表
  9. markdownpad 2 的使用
  10. .Net资源文件全球化
  11. idea新建一个springboot项目_SpringBoot(二):第一个Spring Boot项目
  12. httphandler java_java – 使用HTTPHandler上传文件
  13. cmd命令—windows7
  14. 新媒体推广之标题写作的4项原则+6大元素,爆款标题一招就够了! | 黎想
  15. 9gag for android,GitHub - Mixiaoxiao/9GAG: 9GAG-Android (unofficial), Android Design.
  16. cass生成里程文件桩号不全_怎样用CASS生成里程文件,带桩号的
  17. java网络编程--URLEncode和URLDecoder
  18. PhpSpreadsheet导入
  19. EXCEL中文本和数字的相互转换方法
  20. 遵义微红科技微商分佣返利系统开发,助力香港微商企业全方位拓客!

热门文章

  1. C语言中函数和指针的参数传递
  2. 底层移植之RBL, UBL, Uboot的关系
  3. Deep Multi-view Stereo for Dense 3D Reconstruction from Monocular Endoscopic Video
  4. 【浅析三元锂与磷酸铁锂电池】
  5. 九龙证券|磷酸亚铁锂是什么?磷酸亚铁锂的特点和性能介绍
  6. java jdk win2003_windows java jdk安装
  7. 华为防火墙做单臂路由_防火墙做单臂路由实现VLAN间通信
  8. 3287亿!我用20行Python代码预测双十一成交额
  9. 【TA-霜狼_may-《百人计划》】2.2 模型与材质空间
  10. linux攻击智能手机,基于嵌入式Linux的智能手机省电设计