在前段时间呢陆陆续续的更新了一系列关于重构的文章。在重构我们既有的代码时,往往会用到设计模式。在之前重构系列的博客中,我们在重构时用到了“工厂模式”、“策略模式”、“状态模式”等。当然在重构时,有的地方没有点明使用的是那种设计模式。从今天开始,我们就围绕着设计模式这个主题来讨论一下我们常用的设计模式,当然“GoF”的23种设计模式不会全部涉及到,会介绍一些常见的设计模式。在接下来我们要分享的设计模式这个系列博客中,还是以Swift语言为主来实现每种设计模式的Demo。并且仍然会在GitHub上进行Demo的分享,希望与大家相互交流,相互学习,有不足之处还望批评指正。

今天博客的主要思路是先围绕着“穿越火线”中的角色与武器的关系,通过策略模式来设计实现这种关系,整体的来整体感受一下“策略模式”的优点。然后再参考《Head First Design Patterns》这本书中的鸭子的示例,来一步步使用Swift来实现策略模式的案例。当然我们只是参考《Head First Design Patterns》中的示例,本篇博客中的示例与其中的示例还是有所区别的。大部分设计模式的案例都是使用Java实现的,我们依然会使用Swift来实现。还是那句话,设计模式是针对面向对象编程语言的,而不是针对某一种编程语言,Swift是面向对象的语言,所以设计模式用于Swift编程中是没有问题的。废话少说,进入今天博客的主题。

一、穿越火线中的“策略模式”(Strategy Pattern)

当然,这个示例是我YY出来的示例,不是“穿越火线”这个游戏的设计方案呢。说到"穿越火线"如果你没有玩过,那应该听过吧,就是“CrossFire”。我平时不怎么玩游戏,穿越火线之前体验过,不过只有被爆头的份儿。听说那些游戏玩家现在不怎么玩儿“CF”啦,改玩儿Dota,LOL啦,真的是这样吗?我个人对于游戏而言是外行了,不过玩个超级玛丽、魂斗罗、植物大战僵尸、节奏大师还是可以的(坏笑)。

言归正传,今天我们就模拟穿越火线中角色和武器的关系,使用“策略模式”来实现。首先我们先分析一下这个场景,穿越火线中角色分为不同的等级,也就是“军衔”了,简单的说几个吧,由高到底对应着“军师旅团营连排小工兵”,上面的是组织,军衔莫过于各种级的士官,少中上尉,少中上校,少中上将(应该对吧,本人不太专业呢,不过用于咱们要实现的例子是够了)。我虽然不怎么会打CF,可是我会玩军棋呢。

我是不是刷知乎刷多了,不能在这儿“一本正经的胡说八道”了。言归正传,不同的角色所配备的武器装备也不同,等级越高所使用的武器装备也就越厉害。我们如何使用面向对象来表达这种角色与武器之间的关系呢?我们先看一下下方的类“类图”。

上面是一个简化的类“类图”,上面这种形式可以表达我们之前的那种场景。“军人”是一个父类,其他具体等级的军官都继承自“SuperClass”。那么问题来了,在上面那种模式下,如果只有“少尉”和“中尉”配备某种武器,其他军官不配备,我们就要在“少尉”和中尉的类中分别添加要实现的武器,那么这样会产生冗余的代码。还有个问题是上面的设计形式不利于扩展,比如“少尉”也要配备狙击步枪,岂不是得从“中尉”中的狙击步枪的方法复制到“少尉”中。这样也会产生重复代码的。那么我们该怎样去解决这个问题呢?

有童鞋说了,在Swift中的Protocol(协议,也就是Java中的接口)可以提供默认的实现。也就是声明一个protocol,然后通过extension来为协议添加默认实现,只要是类遵循该协议,那么这个类就拥有了这个默认实现(当然,Java中的接口是不能通过后期的延展来为其添加默认实现的)。如果在Swift中使用接口的默认实现的话,如果要对上述军官扩充装备的话,设计中的类“类图”(不是类图,但与类图相似)实现如下所示:

上面这种设计模式虽然不会产生重复的代码,但是如果给“军官”添加的武器过多的话,那么会导致相应的类中实现的接口过多,这并不是我们想要的。下方将会给出一个良好的解决方案,也就是使用策略模式。

二、使用“策略模式”(Strategy Pattern)对上述关系进行设计

“策略模式”的定义大概是:策略模式,将不同的策略(算法)进行封装,让他们之间可以相互的替换,此模式让策略的变化独立于使用策略的用户。在设计模式中有不同的设计原则,其中有一条就是“找出程序中可能需要变化的地方,并且把它吗独立出来,不要和不变的代码混在一起”。根据这条设计原则,然后结合着上述示例不难分析出来,在上述示例中,使用军官使用的不同武器是可以变化的,使用不同的武器正是采取不同的策略呢。

所以经过上述讨论,我们可以使用“策略模式”来重新设计上面的结构。简单的说就是把变化的“武器”部分进行提取,然后在军官中进行使用,不同的军官可以采取不同的策略,并且可以随时替换。下面是我们使用“策略模式”重新设计后的关系,具体请看下图。

在上面的类“类图”中我们对可变的“武器策略进行了提取”。我们使用了WeaponBehavior协议来规定武器的策略,使得不同的武器对外有统一的接口,在此就是使用武器,也就是开火。不同的武器使用不同的的“开火策略”,但是对外的接口都是一样的。设计原则中有一条是“面向接口编程,而不是面向实现编程”。这里所指的接口可以是协议,可以是抽象类,也可以是超类,其实就是利用面向对象的“多态”特性。上面的红框中实现的就是所有不同的策略。

而绿框中是我们的用户,也就是军官的定义,是我们不变的部分。在军官中也有一个基类,在基类中定义了军官的共性,其中依赖于“武器策略”的接口。在军官超类中使用“武器策略”的协议声明了一个对象,该对象就是该军官所采取的武器策略。在军官的超类中可以通过setWeapon()方法采取不同的策略,其中fire()方法就是使用该“武器策略”进行开火。在具体的军官中的changeXXX()方法就是调用setWeapon()方法进行策略切换的方法。具体内容请看下方的具体实现。

三、上述“策略模式”(Strategy Pattern)的具体实现

上面给出了“武器策略模式”的个个部分之间的关系,并给出了相应的解释。如果对此你感觉到抽象的话,那么我们接下来就用相应的Swift代码去实现上述示例。也就是将上面的理论部分进行具体实现,当然在此我们用的是Swift语言,但是,你完全可以使用其他的面向对象编程语言。下面就是我们具体的代码实现。

下方就是我们对“武器策略”的实现,红框中对应的就是上面图中的WeaponBehavior(协议)接口,下方绿框中就是不同武器的策略,每个武器策略都遵循了WeaponBehavior协议。并且实现了相应的useWeapon()方法。

对“武器策略”模块实现完毕后,接下来我们就得实现军官模块了。也是根据上面我们所画的“模式结构图”来实现我们的“军官模块”,下方Character就是所有军官的基类,其中默认的武器策略weapon就是手枪(PistolBehavior),其中有设置策略和改变策略的方法,并且还有使用策略的方法(fire())。下方的红框就是实现的不同的军官了,不同的军官可以有不同的切换策略的方法。具体如下所示:

上面就是我们全部实现的代码,下方是我们的测试用例和输出结果。下方我们创建了一个“中尉”军官----lieutenant,军官默认的是开的手枪。但是可以调用相应的changeXXX()方法来切换武器策略。开手枪时,发现火力不行,然后就调用changeHK()方法切换到HK48步枪。这种关系使用“策略模式”就比较灵活,并且便于扩展。比如中尉现在也要配备大狙,因为现在已经有大狙这个武器策略了,所以我们现在只需在中尉中添加相应的change方法,传入大狙的武器策略即可,具体的就不在演示了。

设计模式(一):“穿越火线”中的“策略模式”(Strategy Pattern)相关推荐

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

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

  2. 解读设计模式----策略模式(Strategy Pattern)

    一.模式概述      策略模式(Strategy Pattern)在外形上与状态模式很相似,但在意图上有些不同.其意图是使这些算法可以相互替换,并提供一种方法来选择最合适的算法.       在我应 ...

  3. 8.6 GOF设计模式四: 策略模式… Strategy Pattern

    策略模式- Strategy Pattern  在POS系统中,有时需要实行价格优惠, 该如何处理?  对普通客户或新客户报全价  对老客户统一折扣5%  对大客户统一折扣10%  注:课件 ...

  4. 二十四种设计模式:策略模式(Strategy Pattern)

    策略模式(Strategy Pattern) 介绍 定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换.本模式使得算法的变化可独立于使用它的客户. 示例 有一个Message实体类,对它的操 ...

  5. 「补课」进行时:设计模式(11)——游戏中的策略模式

    1. 前文汇总 「补课」进行时:设计模式系列 2. 游戏中的策略模式 我是一个很喜欢玩游戏的人,周末在家打打游戏是真的很开心. 回想起来当年上大学的往昔峥嵘岁月,那时候基本上是一个人在玩游戏,背后围着 ...

  6. 设计模式实战-策略模式(Strategy Pattern)

    0 联系我 图片标题 1.Q群[Java开发技术交流]:jq.qq.com/?_wv=1027&a- 2.完整博客链接:www.shishusheng.com 3.知乎:www.zhihu.c ...

  7. 锈才学设计模式之 —— 策略模式(Strategy Pattern)

    锈才学设计模式之  -- 策略模式 策略模式:把功能提供者单独封装成类,使它们可以互相替换使用,让功能提供者独立于使用者(调用者). 说明: 在面向对象编程中,我们尽量将功能(类)设计成复用,以符合O ...

  8. 关于设计模式——策略模式-Strategy Pattern

    文章目录 1 策略模式 1.1 模拟鸭子 1.2 设计原则 1.3 整合行为 1.4 模拟鸭子代码的代码 1.5 动态设定行为 1.6 重新查看整体 1.7 继承和组合 1.8 总结 1.9 优劣期间 ...

  9. 设计模式——策略模式( Strategy Pattern )

    写代码超过千行,自定义类10个以上,往往写着写着就觉的乱,最终决定抽空补习下设计模式方面的知识.本来AS3出了本关于设计模式的书的,国人也翻译了.我同事也早早买了一本,但前些天我借来看了几页,翻译的太 ...

最新文章

  1. 如何避开项目管理陷阱?
  2. 正则表达式的匹配模式
  3. gc()两分钟了解JDK8默认垃圾收集器(附英文)
  4. 《3D Math Primer for Graphics and Game Development》读书笔记1
  5. JeecgBoot Minio版本6.0.13升级到8.0.3修改方法
  6. 【Java】计算1!+2!+.....+20!的值
  7. 二进制(1):无符号编码和补码编码
  8. Codeforces Beta Round #61 (Div. 2)
  9. 全网最全console命令解析总结
  10. 2021SC@SDUSC Zxing开源代码(九)Wifi 二维码结果处理
  11. python算方差_python计算方差
  12. Android任务栈简介
  13. ttk python_python GUI ttk库 -- Apple的学习笔记
  14. 利用函数进行ip地址转换
  15. 用c语言编写5颗骰子任意投掷总数为15 的概率,大工15春《应用统计》开卷考试期末复习题...
  16. cad记忆口诀_42条简单易记的CAD口诀,一天精通入门,七天上手绘图!
  17. 哈尔滨新发屯双星计算机学院,家校合作,助力成长——计算机与信息工程学院召开2019级新生家长见面会...
  18. ipad怎么和mac分屏_iPad如何进行分屏多任务操作【详细介绍】
  19. 计算机一级excel操作题百分比,计算机一级excel操作练习题
  20. 【M365运维】扩充OneDrive存储空间

热门文章

  1. IOS11使用IQKeyboardManager导致tableview位置变形
  2. NodeMcu开发环境配置Arduino IDE
  3. 在iphone中添加铃音
  4. Android 全景照片查看,Android图片处理教程之全景查看效果实现
  5. 基于Java毕业设计新城街道社区的健康档案管理平台源码+系统+mysql+lw文档+部署软件
  6. MySQL 5.7 安装教程(全步骤图解教程)
  7. NeurIPS 2022 | ​NAS-Bench-Graph: 图神经网络架构搜索Benchmark
  8. 研报精选230207
  9. 安卓开发个人小作品(2)- QQ简仿
  10. 零基础如何学习优达学城的《无人驾驶入门》?