用Java 8 Lambda表達式實現設計模式:命令模式
在這篇博客里,我將說明如何在使用Java 8 Lambda表達式的函數式編程方式時實現命令設計模式。命令模式的目標是將請求封裝成一個對象,從對客戶端的不同類型請求,例如隊列或日志請求參數化,并提供相應的操作。命令模式是一種通用編程方式,該方式基于運行時決策順序來執行方法。模式的參與者如下:
- 命令 :聲明用于執行操作的接口。
- 實體命令 :定義接收者對象和動作的綁定。
- 客戶端 :創建實體命令實例并設置它的接收者。
- 調用者:控制命令來執行請求。
- 接收者 :實際完成工作。 </ul>
這些參與者之間的關系描述如下:
讓我們看一個命令模式的具體例子,了解它是如何轉換成lambda表達式的。假定我們有一個文件系統工具,所有動作都依賴它,例如打開文件,向文件寫入和關閉文件。這可以實現宏功能 ,即一系列的操作可以被記錄下來,之后作為一個單獨操作執行。下面是我們的接收者。
public interface FileSystemReceiver { void openFile(); void writeFile(); void closeFile(); }
每個操作都是命令,例如openFile和writeFile 。我們可以創建一個通用命令接口來適配這些不同的操作。讓我們將接口命名為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