用Java 8 Lambda表達式實現設計模式:命令模式

jopen 9年前發布 | 19K 次閱讀 Java 8 Java開發

在這篇博客里,我將說明如何在使用Java 8 Lambda表達式的函數式編程方式實現命令設計模式。命令模式的目標是將請求封裝成一個對象,從對客戶端的不同類型請求,例如隊列或日志請求參數化,并提供相應的操作。命令模式是一種通用編程方式,該方式基于運行時決策順序來執行方法。模式的參與者如下:

  • 命令 聲明用于執行操作的接口。
  • 實體命令 :定義接收者對象和動作的綁定。
  • 客戶端 :創建實體命令實例并設置它的接收者。
  • 調用者:控制命令來執行請求。
  • 接收者 :實際完成工作。
  • </ul>

    這些參與者之間的關系描述如下:

     用Java 8 Lambda表達式實現設計模式:命令模式

    讓我們看一個命令模式的具體例子,了解它是如何轉換成lambda表達式的。假定我們有一個文件系統工具,所有動作都依賴它,例如打開文件,向文件寫入和關閉文件。這可以實現宏功能 ,即一系列的操作可以被記錄下來,之后作為一個單獨操作執行。下面是我們的接收者。

    public interface FileSystemReceiver {
        void openFile();
        void writeFile();
            void closeFile();
    }

    每個操作都是命令,例如openFilewriteFile 。我們可以創建一個通用命令接口來適配這些不同的操作。讓我們將接口命名為Action,因為在我們的情境下,它代表執行一個操作。所有命令對象都需要實現這個接口。

    public interface Action {
        public void perform();
    }

    現在,讓我們為每個操作實現Action接口。所有這些類需要做的就是調用FileReceiver的一個方法,并將這個調用封裝到Action接口中。在封裝操作后,使用適當的類命名規范來命名這些類因此,openFile方法對象的類稱為OpenFile

    public class OpenFile implements Action {

    private final FileReceiver fileReceiver;
    
    public OpenFile(FileReceiver fileReceiver) {
        this.fileReceiver = fileReceiver;
    }
    
    public void perform() {
        fileReceiver.openFile();
    }
    
    

    }</pre>

    現在,我們實現Macro類。每個宏包含一個動作序列,該序列可以依次執行動作,它將作為調用者。這個類可以記錄動作,并一起運行。我們可以將動作序列存儲在列表中,然后反復地獲取每個動作來執行。

    public class Macro {
        private final List actions;

    public Macro() {
        actions = new ArrayList<>();
    }
    
    public void record(Action action) {
        actions.add(action);
    }
    
    public void run() {
        actions.forEach(Action::perform);
    }
    

    }</pre>

    當填充宏對象時,我們可以添加每個命令的實例,這些實例也會被記錄在宏對象里。現在簡單的運行宏對象,每個命令將依次執行。我們的客戶端代碼如下。

    Macro macro = new Macro();
    macro.record(new OpenFile(fileReceiver));
    macro.record(new WriteFile(fileReceiver));
    macro.record(new CloseFile(fileReceiver));
    macro.run();

    如果你跟著我的思路讀到這里,你會好奇lambda表達式如何適配這些的。實際上,所有命令類,例如OpenFile、WriteFile和CloseFile,其實只是lambda表達式想打破它們的封裝。這些命令類只是在類之間傳遞。使用lambda表達式整個模式得到大大的簡化,因為我們完全可以廢除這些類。然我們看看宏類(客戶端)使用lambda表達式代替命令類的效果。

    Macro macro = new Macro();
    macro.record(() -> fileReceiver.openFile());
    macro.record(() -> fileReceiver.writeFile());
    macro.record(() -> fileReceiver.closeFile());
    macro.run();

    如果能夠意識到每個lambda表達式都在執行一個單獨的方法調用,可以進一步改進。因此,可以直接使用方法引用。

    Macro macro = new Macro();
    macro.record(fileReceiver::openFile);
    macro.record(fileReceiver::writeFile);
    macro.record(fileReceiver::closeFile);
    macro.run();

    命令模式易于擴展,新的動作方法可以被添加到接收者中來創建新的命令實現,這樣不需要改變任何客戶端代碼。JDK中的Runnable接口(java.lang.Runnable)是命令模式常用的流行接口。這篇博客中,我試著闡述帶Java 8 lambda表達式的命令模式。你可以看到使用lambda表達式,少了很多樣板代碼,從而讓代碼變得更整潔。

    原文鏈接: javacodegeeks 翻譯: ImportNew.com - liken
    譯文鏈接: http://www.importnew.com/16789.html

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!