本文出自 http://blog.csdn.net/shuangde800
走进命令模式
在餐厅的情境中,我们看看餐厅是怎样工作的:
1、顾客走进餐厅,点好菜后,生成订单交给女服务员。
2、女服务员把订单拿到厨房工作室,大喊一声:“订单来了!”
3、厨师订单准备餐点。
上面情境各角色职责:
1、订单封装了顾客的请求。 和一般的对象一样,订单可以被传递,订单内包含一个方法 orderUp(), 这个方法封装了准备餐点所需的动作。订单内有厨师的引用。这些都被封装起来。
2、女服务员的工作就是接受订单,然后调用订单的orderUp( )方法。这里的orderUp具体内容就是把订单交给厨师。
女服务员不必知道订单的内容是什么,只需要知道订单中有一个orderUp( )的方法可以调用就够了。
3、厨师具备准备餐点的知识
厨师是一种对象,他真正知道如何准备餐点。一旦女服务员调用orderUp( )方法,厨师就接手马上做好餐点。
女服务员和厨师之间的关系是彻底解耦的,请注意,女服务员的订单封装了餐点的细节,她只要调用订单的方法即可,而厨师看了订单就知道该做什么餐点,厨师和女服务员之间从来不用直接沟通。
从餐厅到命令模式
把餐厅想象成OO设计模式中的一种模型,这个模型允许将“发出的请求的对象”和“接受与执行这些请求的对象”分隔开来。
比方说,对于遥控器的例子:
有一个遥控器
上面有不同功能的卡槽,旁边对应卡槽的开关按钮,遥控器厂商提供了相关卡槽功能的类。如何设计这个遥控器的API?
对于遥控器API,我们需要分隔开“发出请求的的按钮代码”和执行请求的"厂商特定对象"。
假设遥控器插槽上有一个餐厅订单的对象,那么按按钮,就会调用该对象的orderUp()方法,然后就可以等待大餐上来了!
命令模式可以将“动作的请求者”从动作的执行者对象中解耦。上面遥控器是请求者,而执行者对象就是厂商类的其中之一的实例。
利用命令模式把遥控器每个键的请求封装成一个特定对象,所以,每个按钮都存储一个命令对象,那么当按下按钮时,就可以请命令对象做相关的工作。遥控器并不需要知道工作内容是什么,只要有这个命令对象就能和正确的对象沟通,把事情做好就可以了。
第一个命令对象
// 命令接口,所有的命令对象实现这个接口 public interface Command { // 简单! 只需要一个方法:execute() public void execute(); }
2. 实现一个打开电灯的命令
// 实现一个打开电灯的命令 // 要实现Command的接口 public class LightOnCommand implements Command{ Light light; // light是接收者 public LightOnCommand(Light light) { this.light = light; } // 执行接收者的动作 public void execute() { light.on(); } }
3. 使用命令对象
下面是调用者
public class SimpleRemoteControl{ // 有一个插槽持有命令,而这个命令控制着一个装置 Command slot; public SimpleRemoteControl() { } // 这个方法用来设置插槽控制的命令。 // 如果这段代码的客户想要改变 public void setCommand(Command command) { slot = command; } // 当按下按钮时,这个方法就会被调用 // 使得当前命令衔接插槽,并调用他的execute()方法 public void buttonWasPressed() { slot.execute(); } }
4. 遥控器使用的简单测试
下面代码,用来测试上面的简单遥控器
public class RemoteControlTest {//这是命令模式的客户 public static void main(String[] args) { // 遥控器就是调用者,会传入一个命令对象,可以用来发出请求 SimpleRemoteControl remote = new SimpleRemoteControl(); // 创建一个电灯对象,此对象是接收者 Light light = new Light(); // 这里创建一个命令,然后接收者传给他 LightOnCommand lightOn = new LightOnCommand(light); // 把命令传给调用者 remote.setCommand(lightOn); // 模拟按下按钮 remote.buttonWasPressed(); } }
定义命令模式
命令模式将“请求”封装成对象,以便使用不同的请求,队列或者日志来参数化其他对象。命令模式也支持可撤销的操作
1.命令模式的本质是对命令进行封装,将发出命令的责任和执行命令的责任分割开。
2.每一个命令都是一个操作:请求的一方发出请求,要求执行一个操作;接收的一方收到请求,并执行操作。
3.命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否被执行、何时被执行,以及是怎么被执行的。
4.命令模式使请求本身成为一个对象,这个对象和其他对象一样可以被存储和传递。
5.命令模式的关键在于引入了抽象命令接口,且发送者针对抽象命令接口编程,只有实现了抽象命令接口的具体命令才能与接收者相关联。
撤销命令模式
要在遥控器加上撤销功能很简单,它的功能是这样的:比如说是电灯关闭的,你按下了开启按钮,电灯就亮了,然后你按下撤销按钮,灯就又不亮了。相当与撤销上一次的命令。
1. 在Command接口上加上undo()方法
public interface Command { public void execute(); public void undo(); }
2. 如果是开灯的命令,那么他的撤销命令就是关灯。同理,如果是关灯的命令,那么他的撤销命令就是开灯。
// 开灯命令 public class LightOnCommand implements Command{ Light light; public LightOnCommand(Light light) { this.light = light; } public void execute() { light.on(); } // 实现了撤销功能:变成关灯 public void undo(){ light.off(); } }
// 关灯命令 public class LightOffCommand implements Command{ Light light; public LightOffCommand(Light light) { this.light = light; } public void execute() { light.off(); } // 关灯的撤销命令是开灯 public void undo(){ light.on(); } }
要实现命令模式的撤销功能,还是很简单的,只要学会了保存上一次的命令,那么随便就可以写出来了
宏命令模式
如果遥控器拥有一个功能,按下一个按钮,就可以实现很多功能,要怎么做?
也很简单,用一个数组存下所有命令即可
public class MacroCommand implements Command { Command[] commands; public MacroCommand(Command[] commands) { this.commands = commands; } public void execute() { for(int i = 0; i < commands.length; i++) commands[i].execute(); } public void undo() { for(int i = 0; i < commands.length; ++i) commands[i].undo(); } }
如果要可以撤销很多次怎么做?
也很简单,不只是记录最后一个被执行的命令,而使用一个堆栈记录操作过程的没一个命令。然后不管什么时候按下了撤销按钮,你都可以从堆栈中取出最上层的命令,然后调用它的undo()方法。
命令模式的更多用途: 队列请求
命令可以将运算块打包,然后把它传来传去,就像是一般的对象一样。即使命令对象被创建许久之后,运算依然可以被调用。
事实上,它甚至可以在不同的线程中被调用。我们利用这样的特性衍生出一些应用,例如:日程安排(Scheduler),线程池,工作队列等。
命令模式的更多用途:日志请求
某些应用需要把所有动作都记录在日志中,并能在系统死机后,重新调用这些动作恢复到之前的状态。
通过新增两个方法(store(), load() ),命令模式就能够支持这一点。
在只要当我们执行命令时,将历史记录存储在磁盘中,一旦系统死机,就可以将命令对象重载,并成批地一次调用这些
对象的execute()方法。
相关推荐
这里我们聚焦于C#语言中的设计模式学习笔记,涵盖了多种经典的设计模式,如合成模式、桥梁模式、装饰模式、享元模式、门面模式、命令模式、工厂方法、策略模式、代理模式以及状态模式。下面将对这些模式逐一进行详细...
命令模式是一种行为设计模式,它的主要目的是将请求封装为对象,以便于参数化不同请求、队列请求、记录请求日志以及支持撤销和重做操作。在软件开发中,它帮助解耦了请求发起者(调用者)和请求执行者(接收者),...
2. 命令模式(Command):将请求封装为一个对象,以便使用不同的请求、队列请求或支持撤销操作。 3. 解释器模式(Interpreter):给定语言的文法表示,并提供一个解释器来处理该语言中的句子。 4. 迭代器模式...
"GoF 23种设计模式学习笔记" 是一个深入探讨这23个经典设计模式的资源,这些模式最初由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四位作者在1994年的著作《设计模式:可复用面向对象软件的基础》中...
在这个“设计模式之美”的学习笔记中,我们将探讨一些主要的设计模式,以及它们在实际开发中的应用。 首先,我们从创建型模式开始。这类模式主要用于对象的创建,如单例模式(Singleton)、工厂模式(Factory ...
以下是一些在尚学堂300Java设计模式部分学习笔记中涉及的设计模式的知识点: 创建型模式: 创建型模式主要解决对象创建的问题,确保系统的灵活性和封装创建细节。学习笔记中提到了5种创建型模式: 1. 单例模式...
### 23种设计模式学习笔记 #### 一、软件设计模式的概念与意义 **概念:** 软件设计模式(Software Design Pattern),又称设计模式,是一套被广泛采用、经过整理和分类的代码设计经验总结。它针对软件设计过程中...
### 设计模式学习笔记 #### 引言 设计模式(Design Patterns)是在软件设计领域内广泛应用的一种实践指南,它提供了一系列解决常见问题的方案。设计模式可以被理解为面向对象软件设计的经验总结,是对特定面向对象...
- **命令模式**(Command):将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。 - **迭代器模式**(Iterator):提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。 ...
17. 命令模式(Command):将请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。 每个模式都有其特定的应用场景和优势,理解并掌握这些模式有助于...
命令模式是一种行为设计模式,它的主要目的是将请求的发起者(发送者)与请求的执行者(接收者)解耦,使得系统更加灵活,易于扩展。这种模式通过将请求封装为一个对象,允许我们参数化不同请求,以及支持可撤销的...
- 命令模式(Command):将命令封装为一个对象,以便使用不同的请求、队列请求或支持撤销操作。 - 解释器模式(Interpreter):提供一种方式来表达语言或计算公式。 - 迭代器模式(Iterator):提供一种方法顺序...
在《23个设计模式图解--学习笔记》中,我们探讨了这些模式,以便于理解和应用到实际开发中。以下是这23个设计模式的详细说明: 1. **工厂方法**(Factory Method):定义一个用于创建对象的接口,让子类决定实例化...
文档中的“23种设计模式学习笔记.doc”可能包含了对这23种模式的详细解释和实例,而“设计模式之我爱我家.doc”可能从一个更生活化的角度来阐述设计模式的概念。“软件23种设计模式,超级经典的.pdf”可能是对这些...
通过阅读这份笔记,读者不仅可以学习到设计模式的基本概念,还能了解到如何在Java环境中实际运用这些模式,提升编程技能。设计模式的学习和掌握是成为一名优秀程序员的必经之路,它们能帮助我们写出更高效、更灵活、...
### 设计模式笔记 #### 一、引言 设计模式是一种在特定情境下解决软件设计问题的标准化解决方案。它是从无数编程实践中提炼出来的精华,帮助开发者更好地理解和应对复杂的问题。在学习设计模式的过程中,我们通常...
其中包含了个人的学习笔记和Eclipse环境下实现的源码,方便读者导入后直接运行,进行实践操作。 1. **单例模式**:确保一个类只有一个实例,并提供全局访问点。在Java中,单例模式通常通过私有构造器、静态工厂方法...
在本篇STM32 F103C8T6的学习笔记中,我们将深入探讨如何使用0.96英寸单色OLED显示屏进行自由取模显示,并实现汉字的显示。STM32系列微控制器是由意法半导体(STMicroelectronics)推出的基于ARM Cortex-M3内核的高...
本资料“图解Java设计模式笔记总结word版本”聚焦于通过图文并茂的方式,深入浅出地解析各种设计模式。以下是基于这个主题的详细知识点讲解: 1. **设计模式的分类** - **创建型模式**:如单例(Singleton)、工厂...
行为型模式:如策略模式(Strategy)、模板方法模式(Template Method)、观察者模式(Observer)、迭代器模式(Iterator)、访问者模式(Visitor)、责任链模式(Chain of Responsibility)、命令模式(Command)、...