设计模式之-----命令模式
2015-08-10 09:23
162 查看
今天继续学习设计模式的命令模式,命令模式在生活中算是比较常见的,比如在《大话设计模式》中,“命令模式”一节中举得烤羊肉串的例子,小摊贩烤的羊肉串,由于没有记录,导致人多的时候,很容易忘记哪个顾客要的什么,要了多少,是否给钱了,要不要辣椒,这些都很容易记混的。而在一个正式的店面中,有专门的服务员负责记录,服务员通知后厨去烤羊肉串,顾客不必与厨师亲自打交道,这就体现了一个命令模式的特点,将命令请求者与命令执行者彻底解耦,当然这只是其中一个好处。
在比如电视遥控器的例子,遥控器封装了一系列的功能,用户只要知道这些按键是干嘛的,不需要知道内部是怎么运作的,就可以操作电视开关,换台等操作。
以下是官方的解释:命令模式把一个请求或者操作封装到一个对象中。命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。
我们举个例子,我们都用过记事本,记事本有增加记录,删除记录,撤销操作等等,我们就用命令模式来实现这个功能,来看实现代码
这是包结构
首先是记事本
然后是命令的抽象接口
具体的命令类
然后就是请求者,这里请求者是键盘
最后是测试类
然后来看看结果
最后引用ID为jason0539博客的总结
/article/1367736.html
优点
1.降低对象之间的耦合度。
2.新的命令可以很容易地加入到系统中。
3.可以比较容易地设计一个组合命令。
4.调用同一方法实现不同的功能
缺点
使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。
适用情况
1.系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
2.系统需要在不同的时间指定请求、将请求排队和执行请求。
3.系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。
4.系统需要将一组操作组合在一起,即支持宏命令。
在比如电视遥控器的例子,遥控器封装了一系列的功能,用户只要知道这些按键是干嘛的,不需要知道内部是怎么运作的,就可以操作电视开关,换台等操作。
以下是官方的解释:命令模式把一个请求或者操作封装到一个对象中。命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。
我们举个例子,我们都用过记事本,记事本有增加记录,删除记录,撤销操作等等,我们就用命令模式来实现这个功能,来看实现代码
这是包结构
首先是记事本
package com.command.receiver; /** * 记事本类,负责执行具体的操作 * @author ZHENGWEI * @date 2015-8-10 */ public class NotePad { /** * 在记事本中增加一条记录 */ public void addThing(){ System.out.println("增加一条记录"); } /** * 在记事本中删除一条记录 */ public void removeThing(){ System.out.println("删除一条记录"); } /** * 对当前编辑进行撤销操作 */ public void backOut(){ System.out.println("撤销当前操作"); } }
然后是命令的抽象接口
package com.command.command; /** * 命令的抽象接口 * @author ZHENGWEI * @date 2015-8-10 */ public interface Command { /** * 执行命令 */ public void execute(); }
具体的命令类
package com.command.concrete.command; import com.command.command.Command; import com.command.receiver.NotePad; /** * 增加记录的命令 * @author ZHENGWEI * @date 2015-8-10 */ public class AddThingCommand implements Command{ //具体操作类的对象 private NotePad notePad; public AddThingCommand(NotePad notePad) { super(); this.notePad = notePad; } /** * 增加记录的命令执行的入口 */ public void execute() { //调用真正的操作类来实现具体功能 notePad.addThing(); } }
package com.command.concrete.command; import com.command.command.Command; import com.command.receiver.NotePad; /** * 删除记录的命令 * @author ZHENGWEI * @date 2015-8-10 */ public class RemoveThingCommand implements Command{ //具体操作类的对象 private NotePad notePad; public RemoveThingCommand(NotePad notePad) { super(); this.notePad = notePad; } /** * 删除记录的命令执行的入口 */ public void execute() { //调用真正的操作类来实现具体功能 notePad.removeThing(); } }
package com.command.concrete.command; import com.command.command.Command; import com.command.receiver.NotePad; /** * 撤销操作的命令 * @author ZHENGWEI * @date 2015-8-10 */ public class BackOutCommand implements Command{ //具体操作类的对象 private NotePad notePad; public BackOutCommand(NotePad notePad) { super(); this.notePad = notePad; } /** * 撤销操作命令执行的入口 */ public void execute() { //调用真正的操作类来实现具体功能 notePad.backOut(); } }
然后就是请求者,这里请求者是键盘
package com.command.invoker; import com.command.command.Command; /** * 请求者,这里由键盘扮演 * 对于记事本而言,只有键盘请求它才能做出相应,如果我们对它说句话,记事本是不会有反应的 * 所以对于记事本,真正的请求者是键盘,而人类是去操作键盘的 * 记事本不会在意是谁敲的键盘,它只是负责响应键盘请求 * @author ZHENGWEI * @date 2015-8-10 */ public class KeyBoard { private Command addThingCommand; private Command removeThingCommand; private Command backOutCommand; public void setAddThingCommand(Command addThingCommand) { this.addThingCommand = addThingCommand; } public void setRemoveThingCommand(Command removeThingCommand) { this.removeThingCommand = removeThingCommand; } public void setBackOutCommand(Command backOutCommand) { this.backOutCommand = backOutCommand; } /** * 增加的方法 */ public void add(){ addThingCommand.execute(); } /** * 删除的方法 */ public void remove(){ removeThingCommand.execute(); } /** * 撤销的方法 */ public void back(){ backOutCommand.execute(); } }
最后是测试类
package com.command.main; import com.command.command.Command; import com.command.concrete.command.AddThingCommand; import com.command.concrete.command.BackOutCommand; import com.command.concrete.command.RemoveThingCommand; import com.command.invoker.KeyBoard; import com.command.receiver.NotePad; public class CommandMain { public static void main(String[] args) { NotePad notePad = new NotePad(); Command add = new AddThingCommand(notePad); Command remove = new RemoveThingCommand(notePad); Command back = new BackOutCommand(notePad); KeyBoard keyBoard = new KeyBoard(); keyBoard.setAddThingCommand(add); keyBoard.setRemoveThingCommand(remove); keyBoard.setBackOutCommand(back); keyBoard.add(); keyBoard.remove(); keyBoard.back(); } }
然后来看看结果
最后引用ID为jason0539博客的总结
/article/1367736.html
优点
1.降低对象之间的耦合度。
2.新的命令可以很容易地加入到系统中。
3.可以比较容易地设计一个组合命令。
4.调用同一方法实现不同的功能
缺点
使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。
适用情况
1.系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
2.系统需要在不同的时间指定请求、将请求排队和执行请求。
3.系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。
4.系统需要将一组操作组合在一起,即支持宏命令。
相关文章推荐
- Warning: Problems in Mirror May Be Larger Than They Appear
- linux c 笔记 网络编程(三)..套接字数据传输
- bzoj2743
- 如何抓微信的请求
- Java4Android-接口
- 最小生成树 Prime算法
- cocos2dx添加文本的三种方法及适用情况CCLabelTTF,CCLabelBMFont,CCLabelAtlas
- 计蒜客 难题题库 033 三个数的和
- hdu5339Untitled
- jQuery图片上传前先在本地预览
- Android官方数据绑定框架DataBinding(一)
- JAVA 基本数据类型长度
- Run
- 深入学习C语言中的函数指针和左右法则
- 信号包络
- Spring HTTP Invoker使用介绍
- 计蒜客 难题题库 032 罗马数字
- 8月书讯:喜悦翩然而至
- 安卓安装过程
- SAP*和DDIC用户被锁分析与解决方案