设计模式 —— 命令模式(Command Pattern)
2016-05-29 18:34
603 查看
命令模式(Command Pattern)
概念:
概述:在软件设计中,我们经常会遇到某些对象发送请求,然后某些对象接受请求后执行,但发送请求的对象可能并不知道接受请求的对象是谁,执行的是什么动作。此时可通过 命令模式 来实现,让发送者和接受者完全的松耦合,这样可大大增强程序的灵活性。定义:命令模式 将“请求”封装成对象,以便使用不同的请求,队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。
组成:
Client(客户):负责创建一个具体的命令(Concrete Command)
Invoker(调用者):调用者持有一个命令对象,并在某个时刻调用命令对象的 execute() 方法。
Command(命令接口):包含命令对象的 execute() 方法和 undo() 方法。
ConcreteCommand(具体命令):实现命令接口。包括两个操作,执行命令和撤销命令。
Receiver(接收者):接受命令并执行。
例子:
现在比较火的小米手机,可以当作遥控器控制多种不同的家电,手机发送命令,不同的电器接收到后执行。Command 类
public interface Command { public void execute(); public void undo(); }
开灯命令
public class LightOnCommand implements Command { private Light light; LightOnCommand(Light light) { this.light = light; } public void execute() { light.on(); } public void undo() { light.off(); } }
开电视命令
public class TVOnCommand implements Command { private TV tv; public TVOnCommand(TV tv) { this.tv = tv; } public void execute() { tv.on(); } public void undo() { tv.off(); } }
家用电器接口类
public interface HouseholdAppliances { public void on(); public void off(); }
电视类
public class TV implements HouseholdAppliances { public void on() { System.out.println("the TV on"); } public void off() { System.out.println("the TV off"); } }
电灯类
public class Light implements HouseholdAppliances{ public void on() { System.out.println("the light on"); } public void off() { System.out.println("the light off"); } }
手机控制器类
public class MiPhone { ArrayList commands; public MiPhone() { commands = new ArrayList(); } public void setCommand(Command command) { commands.add(command); } public void onButtonWasPushed(int slot) { ((Command)commands.get(slot-1)).execute(); } public static void main(String[] args) { MiPhone miPhone = new MiPhone(); //创建电器 Light light = new Light(); TV tv = new TV(); //创建命令 LightOnCommand lightOnCommand = new LightOnCommand(light); TVOnCommand tvOnCommand = new TVOnCommand(tv); //给小米手机设置命令 //设置第一个按钮为开灯 miPhone.setCommand(lightOnCommand); //设置第二个按钮为开电视 miPhone.setCommand(tvOnCommand); //开灯 miPhone.onButtonWasPushed(1); //开电视 miPhone.onButtonWasPushed(2); } }
运行结果:
适用场景
系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。系统需要在不同的时间指定请求、将请求排队(如:线程池+工作队列)和执行请求。
系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。
系统需要将一组操作组合在一起,即支持宏命令。
优缺点:
优点:
降低系统的耦合度:Command模式将调用操作的对象与知道如何实现该操作的对象解耦。Command是头等的对象。它们可像其他的对象一样被操纵和扩展。
组合命令:你可将多个命令装配成一个组合命令,即可以比较容易地设计一个命令队列和宏命令。一般说来,组合命令是Composite模式的一个实例。
增加新的Command很容易,因为这无需改变已有的类。
可以方便地实现对请求的Undo和Redo。
缺点:
使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。更多用途:
宏命令模式:命令模式 加 组合模式,我们可以将多个命令组合到一起来实现命令的批处理。队列请求:将命令排成一个队列打包,一个个调用 execute 方法,如线程池的任务队列,线程不关心任务队列中是读 IO 还是计算,只取出命令后执行,接着进行下一个。
日志请求:某些应用需要我们将所有的动作记录在日志中,然后在系统死机等情况出现时,重新调用这些动作恢复到之前的状态。如数据库事务。
完
参考:
《Head first 设计模式》
设计模式 ( 十三 ) 命令模式Command(对象行为型)
相关文章推荐
- C++学习(一)——基本语法
- D001-开发工具-AVR Studio 环境配置
- 最后一次作业
- 一个操作系统的实现(6)-初识分页机制
- jquery键盘事件
- leetcode 101 Symmetric Tree C++
- (翻译)Google Guava Cache
- Java异常处理机制
- 循环节姿势
- Spring-通过xml配置实现AOP
- C++循环队列基本操作
- 有向图强连通分量的Tarjan算法
- Gradle DSL method not found: 'android()
- 课程计划进程
- 在PowerPoint中插入视频的两种方法
- Eclipse中Maven中央仓库索引的建立
- 链表中环的入口结点
- DP 动态规划 Problem R 1018 完全背包
- POJ 3230 Travel(朴素DP)
- android控件Button