Java命令設(shè)計模式優(yōu)雅解耦命令和執(zhí)行提高代碼可維護性
介紹
Java命令模式(Command Pattern)是一種行為型設(shè)計模式,它將請求封裝成一個對象,從而使不同的請求可以進行參數(shù)化,并支持請求的排隊,記錄日志,撤銷操作等.
在命令模式中,將命令請求者(Invoker),命令接收者(Receiver)和命令對象(Command)進行了解耦,使得它們可以獨立地變化.具體的說,命令對象封裝了一個特定的請求和其對應的操作,Invoker對象負責調(diào)用命令來執(zhí)行請求,而Receiver對象則負責實際執(zhí)行命令所代表的操作.
在Java中,可以通過定義一個接口來定義命令對象的基本行為,然后再定義具體的命令對象實現(xiàn)該接口.Invoker對象可以包含一個或多個命令對象,可以通過調(diào)用命令對象的execute()方法來執(zhí)行相應的命令.而Receiver對象則負責實際執(zhí)行命令所代表的操作,其具體實現(xiàn)可以再命令對象的execute()方法中調(diào)用.
實現(xiàn)
命令對象接口
public interface Command { /** * 執(zhí)行 */ void execute(); /** * 撤銷 */ void undo(); }
具體命令對象
public class ConcreteCommand1 implements Command { private Receiver receiver; private boolean isExecute; public ConcreteCommand1(Receiver receiver) { this.receiver = receiver; } /** * 執(zhí)行 */ @Override public void execute() { receiver.action1(); isExecute = true; } /** * 撤銷 */ @Override public void undo() { if (isExecute) { receiver.undoAction1(); isExecute = false; } } } public class ConcreteCommand2 implements Command { private Receiver receiver; private boolean isExecute; public ConcreteCommand2(Receiver receiver) { this.receiver = receiver; } /** * 執(zhí)行 */ @Override public void execute() { receiver.action2(); isExecute = true; } /** * 撤銷 */ @Override public void undo() { if (isExecute) { receiver.undoAction2(); isExecute = false; } } }
命令接收者
public class Receiver { public void action1() { System.out.println("Receiver.action1() 被調(diào)用..."); } public void action2() { System.out.println("Receiver.action2() 被調(diào)用..."); } public void undoAction1(){ System.out.println("Receiver.undoAction1() 被調(diào)用..."); } public void undoAction2(){ System.out.println("Receiver.undoAction2() 被調(diào)用..."); } }
命令請求者
public class Invoker { private List<Command> commandList = new ArrayList<>(); /** * 添加命令 * * @param command */ public void addCommand(Command command) { commandList.add(command); } /** * 執(zhí)行命令 */ public void executeCommands() { commandList.forEach(Command::execute); } /** * 撤銷命令 */ public void undoCommands() { for (int i = commandList.size() - 1; i >= 0; i--) { commandList.get(i).undo(); } } }
測試
public class Demo { public static void main(String[] args) { Receiver receiver = new Receiver(); Command command1 = new ConcreteCommand1(receiver); Command command2 = new ConcreteCommand2(receiver); Invoker invoker = new Invoker(); invoker.addCommand(command1); invoker.addCommand(command2); invoker.executeCommands(); invoker.undoCommands(); } }
再示例代碼中,定義了兩個具體的命令對象實現(xiàn),分別是ConcreteCommand1和ConcreteCommand2,它們都實現(xiàn)了Command接口,并且支持撤銷操作.每個ConcreteCommand對象內(nèi)部維護了一個boolean類型的isExecute變量,表示該命令是否已經(jīng)執(zhí)行過.如果execute()方法中,執(zhí)行具體的命令操作,并將isExecute設(shè)為true.再undo()方法中,如果該命令已經(jīng)執(zhí)行過,則執(zhí)行與execute()方法相反的操作,并將isExecute設(shè)為false.Receiver類是命令接收者,它實際執(zhí)行命令所代表的操作.Invoker類中包含了一個Command對象列表,它通過addCommand()方法向其中添加具體的Command對象,executeCommand()用于執(zhí)行所有添加的Command對象,而undoCommands()方法則用于撤銷所有添加的Command對象,執(zhí)行與撤銷的順序正好相反.
總結(jié)
優(yōu)點
- 解耦合,命令模式可以將命令請求者和命令接收者之間解耦合,使得它們之間不直接產(chǎn)生相互作用,從而提高系統(tǒng)的靈活性和可擴展性
- 擴展性,由于命令模式將請求封裝成對象,因此可以方便地新增或修改命令,而不影響其他對象的運行.同時,也可以方便地新增或修改命令接收者,從而實現(xiàn)系統(tǒng)功能的靈活變化.
- 撤銷操作,命令模式可以支持撤銷操作,使得系統(tǒng)具有回滾功能,增強了系統(tǒng)的容錯性.
缺點
- 系統(tǒng)復雜性,使用命令模式需要增加額外的類和接口,從而增加了系統(tǒng)的復雜性
- 性能損失.由于需要將請求封裝成對象,因此可能會導致系統(tǒng)性能的降低,特別是再處理大量請求時
應用場景
- 撤銷操作,如果系統(tǒng)需要支持撤銷操作,那么命令模式是一個非常好的選擇.例如:文本編輯器中的"撤銷"和"重做"操作.
- 日志記錄,命令模式可以用來記錄請求日志,從而實現(xiàn)系統(tǒng)的日志功能.例如:使用命令模式記錄用戶的操作記錄,實現(xiàn)系統(tǒng)的審計功能.
- 隊列請求.如果需要將請求排隊,可以使用命令模式來管理請求隊列.例如:使用命令模式管理操作系統(tǒng)的I/O請求隊列.
到此這篇關(guān)于Java命令設(shè)計模式優(yōu)雅解耦命令和執(zhí)行提高代碼可維護性的文章就介紹到這了,更多相關(guān)Java命令設(shè)計模式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java fastjson解析json字符串實現(xiàn)過程解析
這篇文章主要介紹了Java fastjson解析json字符串實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-10-10IDEA使用maven創(chuàng)建hibernate項目的實現(xiàn)步驟(圖文)
本文主要介紹了IDEA使用maven創(chuàng)建hibernate項目的實現(xiàn)步驟,包括創(chuàng)建Maven項目,配置Hibernate,以及創(chuàng)建實體類映射到數(shù)據(jù)庫等步驟,具有一定的參考價值,感興趣的可以了解一下2023-08-08使用java springboot設(shè)計實現(xiàn)的圖書管理系統(tǒng)(建議收藏)
這篇文章主要介紹了使用java springboot設(shè)計實現(xiàn)的圖書管理系統(tǒng),包含了整個的開發(fā)過程,以及過程中遇到的問題和解決方法,對大家的學習和工作具有借鑒意義,建議收藏一下2021-08-08Springboot實現(xiàn)頁面間跳轉(zhuǎn)功能
這篇文章主要介紹了Springboot實現(xiàn)頁面間跳轉(zhuǎn)功能,本文給大家分享兩種方式,方法一和方法二是不沖突的,但是通常情況下如果用方法二addViewControllers,需要把方法一所寫的Controller類給注釋掉,需要的朋友可以參考下2023-10-10IDEA新建springboot項目時未生成pom.xml文件的解決操作
這篇文章主要給大家介紹了關(guān)于IDEA新建springboot項目時未生成pom.xml文件的解決操作方法,文中通過實例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2023-02-02Java實現(xiàn)InputStream的任意拷貝方式
這篇文章主要介紹了Java實現(xiàn)InputStream的任意拷貝方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10