前言:命令模式內容比較多,這里做了拆分
命令模式基礎篇 :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