设计模式解密(11)- 命令模式 - 扩展篇(命令队列)
前言:命令模式内容比较多,这里做了拆分
命令模式基础篇 :http://www.cnblogs.com/JsonShare/p/7202133.html
命令模式扩展篇 - 宏命令:http://www.cnblogs.com/JsonShare/p/7206395.html
命令模式扩展篇 - 撤销命令:http://www.cnblogs.com/JsonShare/p/7206513.html
命令模式扩展篇 - 命令队列:http://www.cnblogs.com/JsonShare/p/7206607.html
命令模式扩展篇 - 请求日志:http://www.cnblogs.com/JsonShare/p/7206665.html
3、命令队列
有时候我们需要将多个请求排队,当一个请求发送者发送一个请求时,将不止一个请求接收者产生响应,这些请求接收者将逐个执行业务方法,完成对请求的处理。此时,我们可以通过命令队列来实现。
命令队列的实现方法有多种形式,其中最常用、灵活性最好的一种方式是增加一个CommandQueue类,由该类来负责存储多个命令对象,而不同的命令对象可以对应不同的请求接收者;
CommandQueue类的典型代码如下所示:
public class CommandQueue { //定义一个ArrayList来存储命令队列 private ArrayList<Command> commands = new ArrayList<Command>(); public void addCommand(Command command) { commands.add(command); } public void removeCommand(Command command) { commands.remove(command); } //循环调用每一个命令对象的execute()方法 public void execute() { for (Object command : commands) { ((Command)command).execute(); } } }
请求发送者类Invoker也要针对CommandQueue编程,代码修改如下:
public class Invoker { private CommandQueue commandQueue; //维持一个CommandQueue对象的引用 //构造注入 public Invoker(CommandQueue commandQueue) { this. commandQueue = commandQueue; } //设值注入 public void setCommandQueue(CommandQueue commandQueue) { this.commandQueue = commandQueue; } //调用CommandQueue类的execute()方法 public void call() { commandQueue.execute(); } }
下面实例讲解:
package com.designpattern.Command.extend.CommandQueue; /** * 抽象命令角色类 * @author Json */ public interface Command { /** * 执行方法 */ void execute(); }
package com.designpattern.Command.extend.CommandQueue; /** * 接收者角色类 - Java工程师 * @author Json */ public class JavaCoder { /** * 真正执行命令相应的操作 */ public void work(String task){ System.out.println("java工程师要完成【"+task+"】"); } }
package com.designpattern.Command.extend.CommandQueue; /** * 接收者角色类 - H5工程师 * @author Json */ public class H5Coder { /** * 真正执行命令相应的操作 */ public void work(String task){ System.out.println("H5工程师要完成【"+task+"】"); } }
package com.designpattern.Command.extend.CommandQueue; /** * 具体命令 -- Java工程师执行任务 * @author Json */ public class JavaCommand implements Command{ //持有相应的接收者对象 private JavaCoder javaCoder; //具体任务 private String task; /** * 构造方法 */ public JavaCommand(JavaCoder javaCoder,String task){ this.javaCoder = javaCoder; this.task = task; } @Override public void execute() { //通常会转调接收者对象的相应方法,让接收者来真正执行功能 javaCoder.work(this.task); } }
package com.designpattern.Command.extend.CommandQueue; /** * 具体命令 -- H5工程师执行任务 * @author Json */ public class H5Command implements Command{ //持有相应的接收者对象 private H5Coder h5Coder; //具体任务 private String task; /** * 构造方法 */ public H5Command(H5Coder h5Coder,String task){ this.h5Coder = h5Coder; this.task = task; } @Override public void execute() { //通常会转调接收者对象的相应方法,让接收者来真正执行功能 h5Coder.work(this.task); } }
package com.designpattern.Command.extend.CommandQueue; import java.util.ArrayList; /** * CommandQueue命令队列类 * @author Json */ public class CommandQueue { //定义一个ArrayList来存储命令队列 private ArrayList<Command> commands = new ArrayList<Command>(); public void addCommand(Command command) { commands.add(command); } public void removeCommand(Command command) { commands.remove(command); } //循环调用每一个命令对象的execute()方法 public void execute() { for(Command command : commands) { command.execute(); } } }
package com.designpattern.Command.extend.CommandQueue; /** * 请求发送者类Manager针对CommandQueue编程 * @author Json */ public class Manager { private CommandQueue commandQueue; //维持一个CommandQueue对象的引用 //构造注入 public Manager(CommandQueue commandQueue) { this. commandQueue = commandQueue; } //设值注入 public void setCommandQueue(CommandQueue commandQueue) { this.commandQueue = commandQueue; } //调用CommandQueue类的execute()方法 public void call() { commandQueue.execute(); } }
测试:
package com.designpattern.Command.extend.CommandQueue; /** * * @author Json */ public class Client { public static void main(String[] args) { //创建接收者 JavaCoder javaCoder = new JavaCoder(); H5Coder h5Coder = new H5Coder(); //创建命令对象 JavaCommand javaCommand = new JavaCommand(javaCoder,"登录模块的后台代码"); H5Command h5Command = new H5Command(h5Coder,"登录模块的前台代码"); //创建命令对象队列 CommandQueue commandqueue = new CommandQueue(); commandqueue.addCommand(javaCommand); commandqueue.addCommand(h5Command); //创建请求者,把命令对象设置进去 Manager manager = new Manager(commandqueue); //执行方法 manager.call(); } }
结果:
java工程师要完成【登录模块的后台代码】
H5工程师要完成【登录模块的前台代码】
上面简单只是实现,旨在了解命令队列的结构:
当一个发送者发送请求后,将有一系列接收者对请求作出响应,命令队列可以用于设计批处理应用程序,如果请求接收者的接收次序没有严格的先后次序,我们还可以使用多线程技术来并发调用命令对象的execute()方法,从而提高程序的执行效率。(注:例子没使用多线程,请自行修改代码!!!)
PS:源码地址 https://github.com/JsonShare/DesignPattern/tree/master
PS:原文地址 http://www.cnblogs.com/JsonShare/p/7206607.html