天天看點

設計模式-指令模式

  指令(Command)模式屬于對象的行為模式。指令模式又稱為行動(Action)模式或交易(Transaction)模式。(學習)

   指令模式把一個請求或者操作封裝到一個對象中。指令模式允許系統使用不同的請求把用戶端參數化,對請求排隊或者記錄請求日志,可以提供指令的撤銷和恢複功能。

指令模式的結構

  指令模式是對指令的封裝。指令模式把發出指令的責任和執行指令的責任分割開,委派給不同的對象。

  每一個指令以都是一個操作:請求的一方送出請求要求執行一個操作;接收的一方收到請求,并執行操作。指令模式允許請求的一方和接收的一方獨立開來,便得請求的一方不必知道接收請求的一方的接口,更不必知道請求是怎麼被接收,以及操作是否被執行、何時被執行,以及是怎麼被執行的。

  指令允許主求的一方和接收請求的一方能夠獨立演化,進而具有以下的優點:

  1. 指令模式使新的指令很容易地被加入到系統裡;
  2. 允許接收請求的一方決定是否要否決請求;
  3. 能較容易地設計一個指令隊列;
  4. 可以容易地實作對請求的撤銷和恢複;
  5. 在需要的情況下,可以較容易地将指令記入日志;

下面以一個示意性的系統,說明指令模式的結構。

指令模式涉及到五個角色,它們分别是:

  • 用戶端角色:建立一個具體指令(ConcreteCommand)對象并确定其接收者。
  • 指令角色:聲明了一個給所有具體指令類的抽象接口。
  • 具體指令角色:定義一個接收者和行為之間的弱耦合;實作execute()方法,負責調用接收者的相應操作。execute()方法通常叫做執行方法。
  • 請求者角色:負責調用指令對象執行請求,相關的方法叫做行動方法。
  • 接收者角色:負責具體實施和執行一個請求。任命一個類都可以成為接收者,實施和執行請求的方法叫做行動方法。

源代碼

package Command

/**
 * 接收者角色類
 * */
class Receiver {
    /*
    * 真正執行指令相産操作
    * */
    fun action(){
        println("執行操作")
    }
}      
package Command

/**
 * 抽象指令角色類
 * */
interface Command {
    /*
    * 執行方法
    * */
    fun execute()
}      
package Command

/**
 * 具體指令角色類
 * */
class ConcreteCommand constructor(receiver: Receiver) : Command {

    //持有相應的接收者對象
    private var receiver: Receiver? = null

    init {
        this.receiver = receiver
    }

    override fun execute() {
        //通常會轉調接收者對象的相應方法,讓接收者來真正執行功能
        receiver?.action()
    }
}      
package Command

/**
 * 請求者角色類
 * */
class Invoker constructor(command: Command) {

    //持有指令對象
    private var command: Command? = null

    init {
        this.command = command
    }

    /**
     * 行動方法
     * */
    fun action(){
        command?.execute()
    }
}      

測試

//建立接收者
val receiver = Receiver()
//建立指令對象,設定他的接收者
val command = ConcreteCommand(receiver)
//建立請求者,把指令對象設定進去
val invoker = Invoker(command)
//執行方法
invoker.action()      

指令模式的注意事項和細節

  1. 将發起請求的對象與執行請求的對象解耦。發起請求的對象是調用者,調用者隻要調用指令對象的execute()方法就可以讓接收者工作,而不必知道具體的接收者對象是誰、是如何實作的,指令對象會負責讓接收者執行請求的動作,也是就是說請求發起者和請求執行者之間的解耦是通過指令對象實作的,指令對象起到了紐帶橋梁的作用。
  2. 容易設計一個指令隊列。隻要把指令對象放到隊列,就可以多線程的執行指令。
  3. 容易實作對請求的撤銷和重做。
  4. 指令模式的不足:可能導緻某些系統有過多的具體指令類,增加了系統的複雜度,這點在使用時要注意。
  5. 空指令也是一種設計模式,它為我們省去了判空的操作。
  6. 指令模式經典的應用場景:界面的一個按鈕都是一條指令、模拟cmd(dos指令)訂單的撤銷/恢複、觸發-回報機制。

繼續閱讀