设计模式(六):控制台中的“命令模式”(Command Pattern)
今天的博客中就来系统的整理一下“命令模式”。说到命令模式,我就想起了控制台(Console)中的命令。无论是Windows操作系统(cmd.exe)还是Linux操作系统(命令行式shell(Command Line Interface shell ,即CLI shell)都有命令行程序。说白了就是你输入你要执行的命令提示符,然后计算机就还是根据你所下达的命令来执行。你最终看到的是命令执行后的结果,具体的执行细节不需要你一步步的去下达命令。(与之前博客保持一致,我们仍然使用Swift语言来进行实现)
进一步说,你下达的命令是一个总的命令,而计算机执行时是讲该命令分为不同的阶段来执行的。举个简单的例子,当你打开计算机是,你只需按一下开机键,也就是下达你的Start命令。此时计算机收都命令后就会执行硬盘启动、点亮屏幕、加载系统等等一系列的操作,而这些操作都是你下达Start命令后其自动完成的。再比如,你使用Linux系统下的Shell时,你会在Shell中输入各种命令,然后计算机就会根据你的命令来执行系列的操作,具体哪些操作是对外隐藏的。这也就是对具体的实现细节进行了封装,并对外留出调用接口。
看完上面的描述,是时候回到今天的主题“命令模式”上了。命令模式简单的说就是将一些列的命令(函数或者方法)进行封装,隐藏内部执行细节,并对外留出调用的接口。命令模式是支持撤销操作的,撤销所做的事情就是与你刚才下达的命令相反。下方就是命令模式的定义了,说白了命令模式就是进一步对命令进行封装,简化命令的执行。这些命令在编程中就是一个个的函数。也可以说“命令模式”是对函数调用的封装,简化了函数调用的方式,隐藏了函数调用的细节。
命令模式:将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。
今天博客中会通过命令模式来实现控制台是示例,也就是我们可以通过给控制台下达不同的命令来进行不同的操作。
一、控制台命令模式的类图
下方就是我们将要实现的控制台“命令模式”的示例的类图。下方的类图还是比较简单的,红框上方是具体的类(计算机和电灯)。这些具体的类中有属于自己的不同的命令(对应着不同的函数函数),比如Computer类(计算机)中有Start、ScreenLight、Load、StartOver、Off等命令,而Light(电灯)类中有On、Off命令。
而红框中是我们示例的核心,也就是对命令的上述具体命令的封装。在封装命令时我们会实现一个接口(该示例中是Command协议),该接口就是外部执行命令( execute() 函数)的接口。封装的不同的命令都会遵循Command协议,所以我们封装的命令都会对外暴漏一个execute()函数,用来执行我们封装的命令。在封装命令时,我们会根据封装的命令的特点来执行特定的命令。比如下方的ComputerStartCommand命令中的就会包括Start、ScreenLight、Load、StartOver等子命令。也就是说在ComputerStartCommand命令中调用了Computer中的部分命令(函数),也就是对Computer类中的函数的调用做了进一步的封装,所以ComputerStartCommand命令要依赖于Computer类的。
红框下方就是我们的Console(控制台)类,Console是依赖于命令的接口而不依赖于命令的具体实现,这对模块间的解耦是非常有用的。在Console类中的command属性就是我们所依赖的命令接口,我们可以给command赋值不同的具体命令的实现,然后在Action函数中去执行具体的命令。请参加下方的类图。

二、根据上述类图进行代码实现
上一部分对类图进了详细的介绍,接下来我们对上述类图进行代码实现就不是什么难事了。我们实现的步骤是与上面分析的步骤是一致的,自上而下。首先我们会给出Computer与Light的实现,然后是红框中的命令集合的实现,最后是Console的实现。如下所示:
1、具体命令执行对象的实现
首先我们要对真正去执行命令的对象进行代码实现,在该实例中就是Computer类和Light类。当然从上述示例中,我们不难看出这两个类要包括哪些命令(方法)。下方就是我们Computer类和Light类的具体实现,因为代码较为简单,在此就不做过多的赘述了。具体代码实现如下所示:

2.对上述设备的命令进行封装
下方代码段就是上面类图中的红框部分的代码的具体实现。我们将Command声明为协议(命令对外的接口),而LightOnCommand、LightOffCommand、ComputerStartCommand具体的命令集合都遵循与这个协议。也就是说着三种不同的命令实现对外都有统一的接口,LightOnCommand与LightOffCommand都依赖于Light类,并且根据自己的命令种类来调用Light不同的方法,这也符合面向对象设计的单一职责。ComputerStartCommand命令类则依赖于Compute外设,会调用Computer中与启动相关的具体子命令。具体代码如下所示:

3. 控制台的具体实现
上面我们实现了类图上面的两个模块,紧接着我们要实现类图最下方的那个类,也就是Console类。Console类也是比较简单的,Console类依赖于Command接口,其中的command存储属性就是用来存储那些遵循Command协议的类的对象的。在Console类中的action()方法是用来执行命令的。具体实现如下。

三、测试用例
经过上面的类图的介绍与具体的代码实现,相比对“命令模式”有点概念了吧。最后一部分我们要对上述代码的实现进行测试,看一下我们的代码实现是否有问题。下方代码截图就是我们的测试用例以及该测试用例执行后输出的结果。首先我们创建了一个控制台的对象(类似于我们打开了一个Shell窗口),然后输出不同的命令(setCommand()),最后进行执行(调用action())。测试用例具体如下所示:

至此我们的“命令模式”的一个完整示例就执行完了,最后用一句话来总结一下命令模式,那就是“命令模式是对一些列函数的调用的封装,然后留出执行的接口”。
同样今天的Demo也会在github上进行分享,分享地址为:https://github.com/lizelu/DesignPatterns-Swift
设计模式(六):控制台中的“命令模式”(Command Pattern)的更多相关文章
- 乐在其中设计模式(C#) - 命令模式(Command Pattern)
原文:乐在其中设计模式(C#) - 命令模式(Command Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 命令模式(Command Pattern) 作者:webabcd ...
- 设计模式 - 命令模式(command pattern) 多命令 具体解释
命令模式(command pattern) 多命令 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考命令模式: http://blog.csdn.ne ...
- 设计模式 - 命令模式(command pattern) 具体解释
命令模式(command pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 命令模式(command pattern) : 将请求封装成对 ...
- 设计模式 - 命令模式(command pattern) 宏命令(macro command) 具体解释
命令模式(command pattern) 宏命令(macro command) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考: 命名模式(撤销) ...
- 设计模式 - 命令模式(command pattern) 撤销(undo) 具体解释
命令模式(command pattern) 撤销(undo) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 參考命令模式: http://blog.cs ...
- 二十四种设计模式:命令模式(Command Pattern)
命令模式(Command Pattern) 介绍将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可取消的操作. 示例有一个Message实体类,某个 ...
- 设计模式-15命令模式(Command Pattern)
1.模式动机 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使 ...
- 设计模式----行为型模式之命令模式(Command Pattern)
下面来自head first设计模式的命令模式一章节. 定义 将"请求"封装成对象,以便使用不同的请求.队列或者日志来参数化其他对象.命令模式也支持可撤销的操作. 类图 注: 1. ...
- C#设计模式——命令模式(Command Pattern)
一.概述通常来说,“行为请求者”与“行为实现者”是紧耦合的.但在某些场合,比如要对行为进行“记录.撤销/重做.事务”等处理,这种无法抵御变化的紧耦合是不合适的.在这些情况下,将“行为请求者”与“行为实 ...
随机推荐
- Content Security Policy 入门教程
阮一峰文章:Content Security Policy 入门教程
- CSS 特殊属性介绍之 pointer-events
首先看一下 MDN 上关于 pointer-events 的介绍: CSS属性 pointer-events 允许作者控制特定的图形元素在何时成为鼠标事件的 target.当未指定该属性时,SVG 内 ...
- 源码分析netty服务器创建过程vs java nio服务器创建
1.Java NIO服务端创建 首先,我们通过一个时序图来看下如何创建一个NIO服务端并启动监听,接收多个客户端的连接,进行消息的异步读写. 示例代码(参考文献[2]): import java.io ...
- C++随笔:.NET CoreCLR之GC探索(4)
今天继续来 带大家讲解CoreCLR之GC,首先我们继续看这个GCSample,这篇文章是上一篇文章的继续,如果有不清楚的,还请翻到我写的上一篇随笔.下面我们继续: // Initialize fre ...
- 小兔Java教程 - 三分钟学会Java文件上传
今天群里正好有人问起了Java文件上传的事情,本来这是Java里面的知识点,而我目前最主要的精力还是放在了JS的部分.不过反正也不麻烦,我就专门开一贴来聊聊Java文件上传的基本实现方法吧. 话不多说 ...
- JAVA面试题
在这里我将收录我面试过程中遇到的一些好玩的面试题目 第一个面试题:ABC问题,有三个线程,工作的内容分别是打印出"A""B""C",需要做的 ...
- XAMARIN ANDROID 二维码扫描示例
现在二维码的应用越来越普及,二维码扫描也成为手机应用程序的必备功能了.本文将基于 Xamarin.Android 平台使用 ZXing.Net.Mobile 做一个简单的 Android 条码扫描示 ...
- Hadoop 2.x 生态系统及技术架构图
一.负责收集数据的工具:Sqoop(关系型数据导入Hadoop)Flume(日志数据导入Hadoop,支持数据源广泛)Kafka(支持数据源有限,但吞吐大) 二.负责存储数据的工具:HBaseMong ...
- 关于Hadoop用户体系的设想(胡思乱想)
关于Hadoop的用户体系设计设想 Hadoop并没有一个完整的用户体系,其权限控制的对象,主要是Linux的其它用户(即非安装Hadoop的用户),控制方式也和Linux的文件权限很像,目前权限控制 ...
- 我叫Twenty,我是要成为博客王的博客框架
标题套用了路飞的格式,其实我想说的是大多数都不相信你的梦想,直到你快走到了. 不废话了,介绍一下twenty: 这是基于CMS框架 zerojs打造一个博客.zerojs 的架构介绍在这里http:/ ...