在軟件系統(tǒng)中,行為請求者;與行為實(shí)現(xiàn)者通常呈現(xiàn)一種緊耦合。但在某些場合,比如要對行為進(jìn)行記錄、撤銷/重做、事務(wù)等處理,這種無法抵御變化的緊耦合是不合適的。在這種情況下,如何將行為請求者與行為實(shí)現(xiàn)者解耦?將一組行為抽象為對象,可以實(shí)現(xiàn)二者之間的松耦合。
將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進(jìn)行參數(shù)化;對請求排隊(duì)或記錄請求日志,以及支持可撤消的操作。
一,結(jié)構(gòu)
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
二,示例代碼
public class Document { public void display() { System.out.println("Display"); } public void undo() { System.out.println("Undo"); } public void redo() { System.out.println("Redo"); } } /** * 抽象命令 * * @author Salmon * */ public abstract class DocumentCommand { protected Document _document; public DocumentCommand(Document doc) { this._document = doc; } public abstract void execute(); } /** * 顯示命令 * * @author Salmon * */ public class DisplayCommand extends DocumentCommand { public DisplayCommand(Document doc) { super(doc); } public void execute() { this._document.display(); } } /** * 撤銷命令 * * @author Salmon * */ public class UndoCommand extends DocumentCommand { public UndoCommand(Document doc) { super(doc); } public void execute() { this._document.undo(); } } /** * 重做命令 * * @author Salmon * */ public class RedoCommand extends DocumentCommand { public RedoCommand(Document doc) { super(doc); } public void execute() { _document.redo(); } } /** * invoker角色 * @author Salmon * */ public class DocumentInvoker { private DocumentCommand _discmd; private DocumentCommand _undcmd; private DocumentCommand _redcmd; public DocumentInvoker(DocumentCommand discmd, DocumentCommand undcmd, DocumentCommand redcmd) { this._discmd = discmd; this._undcmd = undcmd; this._redcmd = redcmd; } public void display() { _discmd.execute(); } public void undo() { _undcmd.execute(); } public void redo() { _redcmd.execute(); } } /** * 客戶端代碼 * @author Salmon * */ public class Client { public static void main(String[] args) { Document doc = new Document(); DocumentCommand discmd = new DisplayCommand(doc); DocumentCommand undcmd = new UndoCommand(doc); DocumentCommand redcmd = new RedoCommand(doc); DocumentInvoker invoker = new DocumentInvoker(discmd, undcmd, redcmd); invoker.display(); invoker.undo(); invoker.redo(); } }
可以看到:
1.在客戶程序中,不再依賴于Document的display(),undo(),redo()命令,通過Command對這些命令進(jìn)行了封裝,使用它的一個關(guān)鍵就是抽象的Command類,它定義了一個操作的接口。同時我們也可以看到,本來這三個命令僅僅是三個方法而已,但是通過Command模式卻把它們提到了類的層面,這其實(shí)是違背了面向?qū)ο蟮脑瓌t,但它卻優(yōu)雅的解決了分離命令的請求者和命令的執(zhí)行者的問題,在使用Command模式的時候,一定要判斷好使用它的時機(jī)。
2.上面的Undo/Redo只是簡單示意性的實(shí)現(xiàn),如果要實(shí)現(xiàn)這樣的效果,需要對命令對象設(shè)置一個狀態(tài),由命令對象可以把狀態(tài)存儲起來。
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
