[设计模式篇] 命令模式

我时常以为,所谓的“设计模式”,更多像是一种方法论,而不应该算作所谓的“知识点”。这些就像高中数学有专门的解题方法集合,形如“不等式逼等式”(证明一个未知数大于等于一个值,同时又证明这个未知数小于等于这个值,那么这个未知数只能是这个值)这样的方法一般,根本没法说得非常具体。而这才是所谓“知识”大放异彩的地方,没有这些无数人总结出来的具体的方法,让我们通过个人总结对现有的知识点进行链接来形成一套,哪怕只是一个小小的方法,或者模式,都是很难得的。如果将学高中数学的方法论做一个合理的外推,那么程序设计中也就像是用一些知识点(一门或多门变成语言)来串接起来解决一个问题,在解决问题的过程中,通过一系列方法(模式)的运用,来获得一个最佳实践,也可以说是数学难题给出的推荐答案。但程序设计与数学难题不同的地方在于,数学难题的某些步骤可以暂时跳过,或者说,即使你没有完全解出题目,也可以完成你暂时明了的工作,而程序设计是一个“非1即0”的过程,“what you see is what you get”,一个小小的错误,往往可以拖崩整个程序,哪怕只是百分之一的错误,也完全可以让已完成的百分之九十九毫无价值。好在作为一个学习者,目前碰到的问题,往往都有以往的解决方案提供,简言之,因为菜,所以先专注于积累,等到你真的拆了千万轮子,见过各种实现,可以挥洒自如时,自然可以写出自己的感悟,那种高度不知比初学时的钻牛角尖高了多少个level!

命令模式(Command Pattern),在gof中的定义是这样的“Encapsulate a request as an object, thereby allowing for the parameterization of clients with different requests, and the queuing or logging of requests. It also allows for the support of undoable operations.”没错,“将请求分装成对象,然后用不同的请求,队列或日志来参数化对象,同时也支持可撤销的操作”,这里的重点在于“请求”的封装,正如我在上文所提,所有的设计模式(解决方法)都是应用于具体问题的解决过程的,我们参考Head First的案例,开始我们的故事。

假设我们现在要设计一个遥控器,这个遥控器具有多个可编程的插槽,我们希望每一个插槽都能控制一个或一组家电装置(电视,电灯,音响啥的),每一个插槽都对应有一个开关,同时还有一个总的撤销(undo)按钮来进行退回,怎么来设计这个遥控器呢?

这个问题的难点在于,每一个特定的家电装置,其所谓开关都是不一样的,比如电视就是简单的开关,而风扇则涉及到风速的大小(想想我们平时的风扇,开/风速都是设计到一个按钮上),音响就涉及到立体声啊,低重音啊之类的开关... ...在我们这个遥控器中,每一个开关按下去,往往会产生一系列的措施,然而对于我们的遥控器来说,它根本不需要知道这些实现的细节,只要知道,我有一个关于“打开风扇”的“请求”过来,我就执行,即把我们的请求封装成一个特定的对象,当按钮按下时,就可以请求对象来做相关的工作,然后故事就结束了,风扇这个对象和遥控器就这么解耦了,将“动作的执行者”和“动作的请求者”解耦,也就是命令模式的精髓所在。

那么怎么来做呢?我们设计一个Command借口,其只有一个方法,execute(),对应我们的风扇,我们通过一个FanHighCommand来实现这个接口,表示已高速来打开风扇。然后,我们写一个遥控器remote,它有一个setCommand方法和一个buttonWasPressed方法,前者用来设置那个方法,后者表示调用方法。这里可以看出命令模式的思想,也就是,这个遥控器压根就不管command是什么,只要将command封装传进来,然后就执行即可,至于执行的过程,写在的继承自command的方法里(比如这里我们把高速打开风的过程的实现写在了FanHighCommand里);

当要进行一些列操作时(比如一键“轰趴模式”),我们只要将这一系列的执行过程(音响开,低重音起,灯光暗淡,TV开)分别写进每一个电器的执行过程中,然后将这一系列的command封装好未一个HomePartyCommand,传染remote的setCommand中,就可以一键轰趴,有木有比较炫?undo的实现其实比较简单,读者可以自己想想怎么弄。

话说回来,笔者的代码经验还是太少,几乎没有用过命令模式,这种将运算快打包传来传去的方法,似乎用在“队列请求”或“日志请求”中比较合适,一个一个调用,执行只管execute,压根就不管具体怎么玩,是一种不错的解耦吧!

时间: 2024-10-25 15:33:50

[设计模式篇] 命令模式的相关文章

用Java 8 Lambda表达式实现设计模式:命令模式

链接:http://www.importnew.com/16789.html 在这篇博客里,我将说明如何在使用Java 8 Lambda表达式的函数式编程方式时实现命令设计模式.命令模式的目标是将请求封装成一个对象,从对客户端的不同类型请求,例如队列或日志请求参数化,并提供相应的操作.命令模式是一种通用编程方式,该方式基于运行时决策顺序来执行方法.模式的参与者如下: 命令 :声明用于执行操作的接口. 实体命令 :定义接收者对象和动作的绑定. 客户端 :创建实体命令实例并设置它的接收者. 调用者:

入门设计模式之命令模式

学习更多设计模式请参考:入门设计模式之汇总篇 命令模式:把命令包装成对象,将命令发送者和命令接受者的耦合降低 举个例子,皇帝发圣旨招一个大臣入宫. 这里的皇帝就是客户端,而圣旨就是命令,大臣就是命令接受者.那么命令发送者通常都是某个公公对吧.这里就是一个命令模式的实践,为什么这样说呢?平常我们写代码都是一个方法直接调用另一个方法,这样耦合性太高了,你总不能让皇帝跑到大臣家告诉他找他有点事吧,要是都这样皇帝不就累死了.皇帝要做的就是指定命令交个哪一个公公,让公公这个命令发送者带着这个命令去找命令接

每天一个设计模式之命令模式

作者按:<每天一个设计模式>旨在初步领会设计模式的精髓,目前采用javascript和python两种语言实现.诚然,每种设计模式都有多种实现方式,但此小册只记录最直截了当的实现方式 :) 原文地址是:<每天一个设计模式之命令模式> 欢迎关注个人技术博客:godbmw.com.每周 1 篇原创技术分享!开源教程(webpack.设计模式).面试刷题(偏前端).知识整理(每周零碎),欢迎长期关注! 如果您也想进行知识整理 + 搭建功能完善/设计简约/快速启动的个人博客,请直接戳the

设计模式之命令模式

命令模式的核心是把方法调用封装起来,调用的对象不需要关心是如何执行的. 定义:命令模式将"请求"封装成对象,以便使用不同的请求.队列或者日志来参数化其他对象.命令模式也可以支持撤销操作. 先看一个例子,设计一个家电遥控器的API,可以通过遥控器发出命令来控制不同生产商生产的家电,比如关灯.开灯. 以下是一个简单的代码示例. 1 package cn.sp.test05; 2 /** 3 * 电灯类 4 * @author 2YSP 5 * 6 */ 7 public class Lig

设计模式之命令模式20170719

行为型设计模式之命令模式: 一.含义 将请求(命令)封装成一个对象(内部有接收者对象,以及按照具体命令执行接收者操作的方法),传递给调用者,由调用者执行具体命令. 也就是把一个动作的执行分为执行对象(接收者角色).执行行为(命令角色),让两者相互独立而不相互影响,实现对动作解耦 二.代码说明 1.主要有三个角色 1)接收者角色 该角色就是干活的角色,被命令角色调用,其操作按具体命令的要求执行 2)命令角色 需要执行的所有命令都在这里声明,同时接收者所有的对象都在这里(接收者封装在这里,防止高层模

跟我学设计模式视频教程——命令模式vs策略模式,唠嗑

课程视频 命令模式vs策略模式 唠嗑 课程笔记 课程笔记 课程代码 课程代码 新课程火热报名中 课程介绍 跟我学设计模式视频教程--命令模式vs策略模式,唠嗑,布布扣,bubuko.com

设计模式 ( 十三 ) 命令模式Command(对象行为型)

设计模式 ( 十三 ) 命令模式Command(对象行为型) 1.概述 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活. 例子1:电视机遥控器 : 遥控器是请求的发送者,电视机是请求的接收者,遥控器上有一些按钮如开,关,换频道等按钮就是具体命令,不同的按钮对应电视机的不同操作. 2.问题

设计模式(6)--命令模式

关键词 :空对象 有人称为设计模式 三层调用 1. 封装调用  , 把封装带到一个全新的境界: 把方法调用(method invocation) 封装起来. 2. 命令模式可将"动作的请求者" 从"动作的执行者" 对象中解耦. 3. 当需要将发出的请求和执行请求的对象解耦的时候,使用命令模式. OO原则: (1)封装变化 (2) 多用组合,少用继承 (3)针对接口编程,不针对实现编程 (4)为交互对象之间松耦合设计而努力 (5) 类应该对扩展开放,对修改关闭 (6)

设计模式 7 —— 命令模式

设计模式目录: 设计模式 1 ——观察者模式 设计模式 2 —— 装饰者模式 设计模式 3 —— 迭代器和组合模式(迭代器) 设计模式 4 —— 迭代器和组合模式(组合) 设计模式 5 —— 工厂模式 设计模式 6 —— 单件模式 设计模式 7 —— 命令模式 概述 第1部分 问题引入 第2部分 定义和实现 第3部分 使用宏命令 第1部分 问题引入 首先看下,下面的要求: 实现命令接口 首先,让说有的命令对象实现相同的包含一个方法的接口. 1 /** 2 * 命令接口 3 * @ClassNam