设计模式(九)—命令模式

最后更新于:2022-04-01 16:26:11

**定义**:将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志, 可以提供命令的撤销和恢复功能。 ## 命令模式的通用模式: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-06-06_5755340a10f29.jpg) **该类图中** Receive接受者角色 ---|该角色就是干活的角色,命令传递到这里应该是被执行的 Command命令角色 ---|需要执行的所有命令都在这里声明 Invoker调用者角色 ---|接收命令,并执行命令。 ~~~ public class CommandTest { public static void main(String[] args) { //首先声明调用者Invoker MyInvoker invoker = new MyInvoker(); //声明命令的接收者 Receiver receiver1 = new ConcreteReceive1(); //声明命令 Command command1 = new ConcreteCommand1(receiver1); invoker.setCommand(command1); invoker.action(); } } abstract class Receiver{ //抽象的接收者,定义具体接受者要实现的方法 public abstract void doSomething(); } class ConcreteReceive1 extends Receiver{ @Override public void doSomething() { System.out.println("接收者1号,需要执行的方法...."); } } class ConcreteReceiver2 extends Receiver{ @Override public void doSomething() { System.out.println("接收者2号,需要执行的方法..."); } } abstract class Command{ //抽象的命令类,定义要执行的命令,具体命令主体由子类来完成。 public abstract void execute(); } class ConcreteCommand1 extends Command{ private Receiver receiver; //用构造函数来传递,具体的接收者是谁。 public ConcreteCommand1(Receiver receiver) { this.receiver = receiver; } @Override public void execute() { //让接收者去执行具体的方法。 this.receiver.doSomething(); } } class ConcreteCommand2 extends Command{ private Receiver receiver; //用构造函数来传递,具体的接收者是谁。 public ConcreteCommand2(Receiver receiver) { this.receiver = receiver; } @Override public void execute() { //让接收者去执行具体的方法。 this.receiver.doSomething(); } } class MyInvoker{ private Command command; //调用者角色,去决定具体的接收者执行什么命令 public void setCommand(Command command) { this.command = command; } public void action() { this.command.execute(); } } ~~~ ## 一个例子: 一个项目组分为需求组(require),美工组,编码组,三部分。客户在进行修改需求、美工时需要对各个部门进行交互。 但是这样的做法对客户来说十分不便捷。因此需要一个中介者替客户传达他对各项目组的需求。 他将客户一系列的命令(Command)传达给不同的项目小组。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-06-06_5755340a2ec27.jpg) ~~~ public class CommandEx { public static void main(String[] args) { //首选创建一个指挥者实体 Invoker invok = new Invoker(); //命令实体要求添加一个需求 CommandWork cw1 = new AddRequire(); CommandWork cw2 = new DelPage(); //指挥者,设置好命令 invok.addCommand(cw1); invok.addCommand(cw2); //指挥者去传达命令。 invok.action(); } } abstract class GroupWork{ /** * 抽象的项目工作类,定义需要的方法供实现类去执行。 */ //找具体的执行者 public abstract void find(); //要求添加功能 public abstract void add(); //要求删除功能 public abstract void delete(); //要求修改功能 public abstract void change(); //要求制定出具体的计划 public abstract void plan(); } /** * 美工组,执行任务 * @author admin * */ class PageGroup extends GroupWork{ @Override public void find() { System.out.println("找到美工组...."); } @Override public void add() { System.out.println("要求美工组添加一张图片..."); } @Override public void delete() { System.out.println("要求美工组删除一张图片...."); } @Override public void change() { System.out.println("要求美工组修改这张页面...."); } @Override public void plan() { System.out.println("要求美工组制定出具体计划...."); } } /* * 编码组,执行任务 */ class CodeGroup extends GroupWork{ @Override public void find() { System.out.println("找到程序员...."); } @Override public void add() { System.out.println("要求程序员添加一个绚丽的功能..."); } @Override public void delete() { System.out.println("要求程序员删除有bug的功能...."); } @Override public void change() { System.out.println("要求程序员修改具体功能...."); } @Override public void plan() { System.out.println("要求程序员制定出详细的计划...."); } } /** * 需求组执行任务。 * @author admin * */ class requireGroup extends GroupWork{ @Override public void find() { System.out.println("找到需求组...."); } @Override public void add() { System.out.println("要求需求组添加一项功能..."); } @Override public void delete() { System.out.println("要求需求组删除项功能...."); } @Override public void change() { System.out.println("要求美需求组修改一项...."); } @Override public void plan() { System.out.println("要求需求组制定详细的需求分析...."); } } abstract class CommandWork{ /** * 模拟客户提出要求,并且让具体的项目组去执行任务。 */ //这里已经知道这三类项目小组,所以在抽象类中直接实例化 GroupWork rg = new requireGroup(); GroupWork pg = new PageGroup(); GroupWork cg = new CodeGroup(); public abstract void executeWork(); } class AddRequire extends CommandWork{ @Override public void executeWork() { //找到需求组 super.rg.find(); //添加一个功能 super.rg.add(); //指定具体计划 super.rg.plan(); } } class DelPage extends CommandWork{ @Override public void executeWork() { //找到需求组 super.pg.find(); //添加一个功能 super.pg.delete(); //指定具体计划 super.rg.plan(); } } class Invoker{ /** * 命令的调用者,通过该类,向项目组传达客户的命令。 * 相当于项目经理。 */ private ArrayList<CommandWork> command_list = new ArrayList<CommandWork>(); public void addCommand(CommandWork command){ this.command_list.add(command); } public void action(){ if(command_list.size()>0){ for(CommandWork cw : command_list){ cw.executeWork(); } } /*//接收到命令,就去转达 this.cw.executeWork();*/ } } ~~~ **命令模式的优点:** * 类间解耦 * 可扩展性 * 命令模式结合其他模式更优秀
';