1. 程式人生 > 實用技巧 >Docker 從入門到掉坑

Docker 從入門到掉坑

Command Patterns

GoF定義:將請求作為一個物件來處理。使得可以使用不同的請求、佇列或者日誌請求來引數化客戶端。並且支援撤銷操作。

概念

通常,四個概念是相互關聯的

  1. command object:在接收端可以呼叫某個特定的方法,它儲存著可以呼叫receiver方法的引數
  2. invoker:只知道命令介面(接收符合Command介面宣告的物件),不知道具體哪個命令被呼叫
  3. client:持有invoker物件和command物件,客戶端決定哪些命令在一個特定的時間點執行,要實現這個功能,客戶端要將command物件傳給invoker物件
  4. receiver:命令的具體操作定義在這裡

例子

現實世界:我們不能改變過去發生的事情,但是我們希望原來可以那樣做,可惜沒有時光機的存在。但是日常生活中,我們可以不做或者重做很多事情,例如橡皮可以擦掉畫的畫,重新設計客廳。所以,取消和重做的操作是我們生活的一部分,我們通過一些內在或外在的命令來實現它們
程式碼世界:微軟的Paint軟體,我們通過工具欄可以隨時undo/redo很多操作

展示

程式碼

public class CommandPatternEx
{
    public static void main(String[] args)
    {
        System.out.println("***Command Pattern Demo***\n");
        Receiver intendedreceiver=new Receiver();
        /*Client holds Invoker and Command Objects*/
        Invoker inv = new Invoker();
        MyUndoCommand unCmd = new MyUndoCommand(intendedreceiver);
        MyRedoCommand reCmd = new MyRedoCommand(intendedreceiver);
        inv.executeCommand(unCmd);
        inv.executeCommand(reCmd);
    }
}

interface ICommand
{
    void doSomething();
}

class MyUndoCommand implements ICommand
{
    private Receiver receiver;

    public MyUndoCommand(Receiver receiver)
    {
        this.receiver = receiver;
    }

    @Override
    public void doSomething()
    {
        receiver.performUndoCommand();
    }
}

class MyRedoCommand implements ICommand
{
    private Receiver receiver;

    public MyRedoCommand(Receiver receiver)
    {
        this.receiver = receiver;
    }

    @Override
    public void doSomething()
    {
        receiver.performRedoCommand();
    }
}

class Receiver
{
    public void performUndoCommand()
    {
        System.out.println("Execution--Undo");
    }

    public void performRedoCommand()
    {
        System.out.println("Execution--Redo");
    }
}

class Invoker
{
    ICommand cmd;

    public void executeCommand(ICommand cmd)
    {
        this.cmd = cmd;
        this.cmd.doSomething();
    }
}

Note

  1. 這個模式廣泛應用於undo/redo操作
  2. 回撥函式可以用這個模式設計(如果沒有函式式介面,可以傳入一個command物件,即在方法的不同狀態下執行不同的命令)
  3. 當我們處理事務時很有用,可以響應資料的變化(結合2,當資料庫資料在不同狀態下執行不同命令)
  4. 命令易於擴充套件。它們和其它的物件沒有什麼不同,在使用Command物件時,不需要改變現在系統的類結構(擴充套件介面即可)
  5. 另一種模式叫做(chain of responsibility)這個模式中,我們將一個請求傳給一系列的物件串(chain),希望這串物件中的任一個可以處理這個請求。但是在本例中,我們將請求傳給了特定的物件(invoker物件)

思考

這個模式核心在於將命令和具體操作解耦,即(Command物件+Receiver物件),而Invoker物件作為統一的調命令介面防止了新建各種command物件調不同的方法。所有的command物件都是客戶端組裝完成(要調的命令所需的引數,且包含一個Receiver類),然後直接傳入Invoker執行命令