先看例子:
//灯:有开、关两个操作
public class Light {
public void off(){
System.out.println("off...");
}
public void on(){
System.out.println("on...");
}
}
//命令
public interface Command {
public void execute();
}
public class LightOnCommand implements Command {
Light light;
public LightOnCommand(Light light){
this.light = light;
}
public void execute() {
light.on();
}
}
public class LightOffCommand implements Command {
Light light;
public LightOffCommand(Light light){
this.light = light;
}
public void execute() {
light.off();
}
}
//遥控器
public class RemoteControl {
Command c;
public void setCommand(Command c){
this.c = c;
}
public void pressButton(){
c.execute();
}
}
测试:
public class CommandLoader {
public static void main(String[] args) {
//遥控器对象
RemoteControl src = new RemoteControl();
//灯对象
Light light = new Light();
LightOnCommand lo = new LightOnCommand(light);
//LightOffCommand lo = new LightOffCommand(light);
src.setCommand(lo);
src.pressButton();
}
}
运行结果是:
on...
我们分析下这段代码可知,程序的最终目的是通过“遥控器”控制“灯”打开,效果类似于在RemoteControl类的pressButton()方法里直接:
Light light = new Light();
light.on();
这样很直接,也很好理解,但是灵活性不好,如果我们要换一种“灯”或者给“灯”添加一些新的操作,比如brighter()调高亮度、dim()调低亮度,就必须修改RemoteControl类了,根本原因在于上面RemoteControl类中使用了硬编码,我们把具体的类Light放进了RemoteControl类中,殊不知这个具体的东西以后可能常常有变化。
再分析下,我们上面这种写法,让RemoteControl类针对抽象的Command接口,而将Light的具体操作封装进Command的实现类中,相当于在RemoteControl和Light中间人为的加了一层,RemoteControl针对Command编程,而一个具体的Command实际上就代表了原来Light里的一个操作。
这就是命令模式:请一个请求封装成对象,从而可以使用不同的请求对客户进行参数化。
下面是命令模式的类图模型:
Invoker:命令的调用者,但却不直接与命令的实施者Receiver关联,而是关联一个Command引用;
Command:(一般用接口)表示命令,给所有需要执行的实际操作一个统一的“接口”;
ConcreteCommand: 具体的操作命令,实现Command接口,同时关联一个Receiver,表示作用在哪个实施者上面的操作;
Receiver:命令的实施者,可将它的每一种操作都封装成一个独立的命令对象,比如LightOnCommand、LightOffCommand、LightXXXCommand等,它们都实现Command接口,从而有一个共同的身份Command;
CommandLoader: 负责组装Reveiver和ConceteCommand,实际的客户端操作Invoker对象。
仔细分析命令模式,可以看出它有很多好处:
1、请求的调用者与请求的实施者解耦
Invoker(请求调用者)不用像以前一样知道每一Receiver(请求的实施者),假如我们要扩展Light,例如添加一个dim()方法调低亮度,RemoteControl完全不用修改,只用添加一个LightDimCommand命令,在把它动态组装到ConreteCommand中即可。
2、可实现撤销功能
不使用命令模式时,light.on()就是一个原子操作,执行完了就完了,而命令模式中由于我们把这个操作封装进了一个对象中,而对象是一个实实在在的有状态的东西,我们可以把它保存起来,这样即使操作结束,由于我们之前保存了那个命令对象,我们也就知道它到底干了什么,当然也就可以撤销了。
我们甚至可以多级撤销,只要将命令对象存放进一个stack栈中,之后便可以轻松取出来。
总结:
命令模式的关键点在于:共同的接口Command、用Command对象封装每一个请求。另外,对象有状态、可以保存,以至于我们可以拿这些对象做一些扩展的功能。
分享到:
相关推荐
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统...
非常好的设计模式介绍资料,通俗易懂,适用于编程人员参考。采用了大量图片介绍系统的展示了编程当中常用的各种模式设计
白话说电气_相电压和线电压的分析 白话说明 比较容易理解
白话说电气_电机制动的几种常见方式.pdf
深入浅出设计模式 pdf 深入浅出设计模式 中文版 设计模式 下载说明: 因个人上传资源大小只能是20M,而该书的PDF格式过大,所以只能分开上传。如有不便请谅解。【该书一共13章,在上传的时候我尽量按章节顺序打包...
写在前面 分享一些设计模式的笔记。陆续整理,按照设计模式类型,创建型,结构型,行为型发布 博文会用通俗的话梳理一些自己的理解,结合开发中的实际场景, 理解不足小伙伴帮忙指正,虚心接受 ^_^ 傍晚时分
为了更系统的学习设计模式,特地开了这样一个基于Java的设计模式【集中营】,都是笔者在实际工作中用到过或者学习过的一些设计模式的一些提炼或者总检。慢慢地初见规模,也有几个朋友给我点鼓励,给了star。本文工程...
1、设计模式的一些总结思考, 2、用白话总结了设计模式的精要, 3、帮助大家理解记忆一些常用的设计模式。
java课程设计大作业,java、算法练手项目,适合初学java、数据结构的同学拿来学习研究,基于java、GUI开发的小游戏,程序都经过测试,可以直接运行,资源含程序运行所需的源码、资源文件等全部数据,有需要的可放心...
设计模式中的策略模式,template模式详细讲解。
java课程设计作业——模仿大富翁游戏,使用Java Swing (GUI) 实现的单机游戏,遵循MVC设计模式 A Java Swing (GUI) game. 单机版的大富翁游戏,纯Java实现,采用MVC设计模式。 所有素材来自 大富翁客户端+冒险岛...
白话中台战略-中台是个什么鬼.pdf白话中台战略-中台是个什么鬼.pdf白话中台战略-中台是个什么鬼.pdf白话中台战略-中台是个什么鬼.pdf白话中台战略-中台是个什么鬼.pdf白话中台战略-中台是个什么鬼.pdf白话中台战略-...
作者Eric Freeman 和Elisabeth Freeman,使用白话文的形式在讨论中介绍23中设计模式,有异与原《设计模式》更加通俗易懂。通过实际事例来讲解每一个设计模式,生动有趣,不会感觉到枯燥。
作者Eric Freeman 和Elisabeth Freeman,使用白话文的形式在讨论中介绍23中设计模式,有异与原《设计模式》更加通俗易懂。通过实际事例来讲解每一个设计模式,生动有趣,不会感觉到枯燥。
这本书作者Eric Freeman 和Elisabeth Freeman使用白话文的方式,清楚的介绍了全部23种设计模式。简洁易懂。共13章节。此为封面、目录
白话c++.pdf 个人收集电子书,仅用学习使用,不可用于商业用途,如有版权问题,请联系删除!
作者Eric Freeman 和Elisabeth Freeman,使用白话文的形式在讨论中介绍23中设计模式,有异与原《设计模式》更加通俗易懂。通过实际事例来讲解每一个设计模式,生动有趣,不会感觉到枯燥。
12_其他命令.html
白话windows编程.rar
白话C++编程.rar