設計模式解密(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

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM