设计模式-15-命令模式
个人github地址:HibisciDai
设计模式系列项目源码:HibisciDai/DesignPattern-LearningNotes-HibisciDai
processon在线UML类图:processon
[TOC]
设计模式-15-命令模式
命令模式(Command Pattern)
意图
将一个请求封装为一个对象,从而使你可用不用的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
Encopsulate a request in object
allow the parameter ization of chents with different requests
allow saring the requests in a queue
主要解决
行为请求者与行为实现者通常是一种紧耦合的关系,如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计。
何时使用
将一组行为抽象为对象、松耦合。
关键代码
定义三个角色:
- received 真正的命令执行对象
- Command
- invoker 使用命令对象的入口
如何解决
通过调用者调用接受者执行命令
顺序:调用者→接受者→命令。
应用实例
struts 1 中的 action 核心控制器 ActionServlet 只有一个,相当于 Invoker,而模型层的类会随着不同的应用有不同的模型类,相当于具体的 Command。
优点
- 降低了系统耦合度。
- 新的命令可以很容易添加到系统中去。
缺点
使用命令模式可能会导致某些系统有过多的具体命令类。
使用场景
认为是命令的地方都可以使用命令模式,比如:
- GUI 中每一个按钮都是一条命令。
- 模拟 CMD。
注意事项
系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作,也可以考虑使用命令模式,见命令模式的扩展。
案例1
去餐厅点餐
类图
代码
pattern15.command.demo1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| public abstract class Command { abstract void makeFood(); }
public class MeatCommand extends Command { @Override void makeFood() { System.out.println("吱吱吱-肉"); } }
public class CakeCommand extends Command { @Override void makeFood() { System.out.println("香喷喷-蛋糕"); } }
public class Waiter { ArrayList<Command> cmds = new ArrayList<Command>();
void addCommand(Command c) { cmds.add(c); }
void delete(Command c) { cmds.remove(c); }
void notifyed() { for (Command c : cmds) { c.makeFood(); } } }
|
测试输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class Main { public static void main(String[] args) { Waiter w = new Waiter();
Command m1 = new MeatCommand(); Command m2 = new MeatCommand(); Command m3 = new MeatCommand(); Command c1 = new CakeCommand();
w.addCommand(m1); w.addCommand(m2); w.addCommand(m3); w.addCommand(c1);
w.delete(m3);
w.notifyed(); } }
|
案例2
数据库有 insert 、 delete、update、select命令
完成程序,希望可以实现批量操作和撤销功能
类图
代码
pattern15.command.demo2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| public abstract class Command { abstract void execute(); }
public class InsertCommand extends Command { @Override void execute() { System.out.println("插入"); } }
public class DeleteCommand extends Command { @Override void execute() { System.out.println("删除"); } }
public class UpdateCommand extends Command { @Override void execute() { System.out.println("更新"); } }
public class SelectCommand extends Command { @Override void execute() { System.out.println("查询"); } }
public class DBCommands { ArrayList<Command> cmds = new ArrayList<Command>();
void addCommand(Command c) { cmds.add(c); }
void delete(Command c) { cmds.remove(c); }
void notifyed() { for (Command c : cmds) { c.execute(); } } }
|
测试输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class Main { public static void main(String[] args) { DBCommands cmds = new DBCommands();
InsertCommand ic = new InsertCommand(); DeleteCommand dc = new DeleteCommand(); UpdateCommand uc = new UpdateCommand(); SelectCommand sc = new SelectCommand();
cmds.addCommand(ic); cmds.addCommand(dc); cmds.addCommand(uc); cmds.addCommand(sc);
cmds.notifyed(); } }
|