「补课」进行时:设计模式(11)——游戏中的策略模式
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)——游戏中的策略模式相关推荐
- 「补课」进行时:设计模式(5)——从 LOL 中学习代理模式
1. 前文汇总 「补课」进行时:设计模式系列 2. 从 LOL 中学习代理模式 我是一个很喜欢玩游戏的人,虽然平时玩游戏的时间并不多,但我也是一个忠实的 LOL 的爱好者,就是段位有点惨不忍睹,常年倔 ...
- 「补课」进行时:设计模式(15)——观察者模式
1. 前文汇总 「补课」进行时:设计模式系列 2. 观察者模式 2.1 定义 观察者模式(Observer Pattern)也叫做发布订阅模式(Publish/subscribe),它是一个在项目中经 ...
- 「补课」进行时:设计模式(6)——郭靖大侠带你学原型模式
1. 前文汇总 「补课」进行时:设计模式系列 2. 找工作 这一天,郭靖大侠因为在桃花岛调戏侍女被黄蓉打出了桃花岛,这下可玩大了,从桃花岛被赶出来吃啥喝啥啊,得赶紧找份工作,西北风可喝不饱肚子哇~~~ ...
- 「补课」进行时:设计模式(20)——解释器模式
1. 前文汇总 「补课」进行时:设计模式系列 2. 解释器模式 解释器模式这个模式和前面的访问者模式比较像,当然,我说的比较像是难的比较像,以及使用率是真的比较低,基本上没有使用的场景,访问者模式还有 ...
- 游戏设计模式思考:“穿越火线”中的“策略模式”
前言:在前段时间陆陆续续在博客园更新了一系列关于重构的文章.在重构我们既有的代码时,往往会用到设计模式.在之前重构系列的文章中,我们在重构时用到了"工厂模式"."策略模式 ...
- 有赞前端 UI框架「Vant」在离线无网络环境中使用 icon 无法显示的问题
有赞前端 UI框架「Vant」在离线无网络环境中使用 icon 无法显示的问题 第一次使用这个框架.UI组件中规中矩,很简洁,不是特别多,基本够用.Vant 官网 在内网中部署 Vue+Vant的项目 ...
- 设计模式随笔系列:鸭子-策略模式(Strategy)[原]
原文地址为: 设计模式随笔系列:鸭子-策略模式(Strategy)[原] 鸭子-策略模式(Strategy) 前言 万事开头难,最近对这句话体会深刻!这篇文章是这个系列正式开始介绍设计模式的第一篇,所 ...
- Java设计模式(十二) 策略模式
策略模式介绍 策略模式定义 策略模式(Strategy Pattern),将各种算法封装到具体的类中,作为一个抽象策略类的子类,使得它们可以互换.客户端可以自行决定使用哪种算法. 策略模式类图 策略模 ...
- 设计模式(一):“穿越火线”中的“策略模式”(Strategy Pattern)
在前段时间呢陆陆续续的更新了一系列关于重构的文章.在重构我们既有的代码时,往往会用到设计模式.在之前重构系列的博客中,我们在重构时用到了"工厂模式"."策略模式" ...
最新文章
- 修正本地乱码(待补充)
- bootstrap配置Nacos出现Param ‘serviceName‘ is illegal, serviceName is blank
- Python基础day05【函数应用:学生管理系统、拆包、今日总结】
- React Native中pointerEvent属性
- 秋风到,ModelArts“ AI市场算法Fast-SCNN指南”秋膘贴起来
- 免费ftp网站服务器软件,免费ftp服务器软件,免费ftp服务器软件有哪些呢?好用推荐...
- python模拟键盘输入+切换键盘布局
- [转]sqlserver 创建分区表
- markdownpad 2 的使用
- .Net资源文件全球化
- idea新建一个springboot项目_SpringBoot(二):第一个Spring Boot项目
- httphandler java_java – 使用HTTPHandler上传文件
- cmd命令—windows7
- 新媒体推广之标题写作的4项原则+6大元素,爆款标题一招就够了! | 黎想
- 9gag for android,GitHub - Mixiaoxiao/9GAG: 9GAG-Android (unofficial), Android Design.
- cass生成里程文件桩号不全_怎样用CASS生成里程文件,带桩号的
- java网络编程--URLEncode和URLDecoder
- PhpSpreadsheet导入
- EXCEL中文本和数字的相互转换方法
- 遵义微红科技微商分佣返利系统开发,助力香港微商企业全方位拓客!
热门文章
- C语言中函数和指针的参数传递
- 底层移植之RBL, UBL, Uboot的关系
- Deep Multi-view Stereo for Dense 3D Reconstruction from Monocular Endoscopic Video
- 【浅析三元锂与磷酸铁锂电池】
- 九龙证券|磷酸亚铁锂是什么?磷酸亚铁锂的特点和性能介绍
- java jdk win2003_windows java jdk安装
- 华为防火墙做单臂路由_防火墙做单臂路由实现VLAN间通信
- 3287亿!我用20行Python代码预测双十一成交额
- 【TA-霜狼_may-《百人计划》】2.2 模型与材质空间
- linux攻击智能手机,基于嵌入式Linux的智能手机省电设计