本文主要介紹命令模式的功能(命令模式的概念),下面一起看看命令模式的功能(命令模式的概念)相關資訊。
1.目的是將請求轉換成一個獨立的對象,包含與請求相關的所有信息。這種轉換允許你將方法參數(shù)化,根據(jù)不同的請求延遲請求的執(zhí)行或者放入隊列,并且可以實現(xiàn)撤銷操作。
2.動機如果開發(fā)一個新的文本編輯器,當前的任務是創(chuàng)建一個有多個按鈕的工具欄,讓每個按鈕對應編輯器的不同操作。創(chuàng)建了一個非常簡潔的按鈕類,不僅可以用來生成工具欄上的按鈕,還可以用來生成各種對話框的通用按鈕。盡管所有按鈕看起來都相似,但它們可以執(zhí)行不同的操作(打開、保存、打印和應用等)。).問題是這些按鈕的點擊處理代碼放在哪里?最簡單的解決方案是在使用按鈕的地方創(chuàng)建大量的子類。這些子類包含了點擊按鈕后必須執(zhí)行的代碼。
但是這種方法有嚴重的缺陷。首先,創(chuàng)建了大量的子類,每次修改基類按鈕,可能都需要修改所有子類的代碼。簡單來說,gui代碼笨拙地依賴業(yè)務邏輯中不穩(wěn)定的代碼(這違反了依賴倒置原則)。更困難的是,復制/粘貼文本等操作可能會在多個地方被調用。例如,用戶可以點擊小 復制 按鈕,或者通過上下文菜單復制一些東西,或者直接使用鍵盤上的ctrl c。我們的程序本來只有一個工具欄,所以可以用按鈕子類來實現(xiàn)各種操作。換句話說,復制按鈕子類包含復制文本的代碼是可行的。實現(xiàn)了上下文菜單、快捷等功能后,需要將操作碼復制到很多類中,或者需要讓菜單依賴按鈕,這是一個比較差的選擇。
優(yōu)秀的軟件設計通常封裝了更改的部分,這往往會導致軟件分層。最常見的例子:第一層負責用戶圖像界面;另一層負責業(yè)務邏輯。gui層負責在屏幕上呈現(xiàn)漂亮的圖形,捕捉所有輸入并顯示用戶和程序的結果。;工作。當有重要的事情需要完成時(比如計算月球軌道或者寫年報),gui層會把工作委托給業(yè)務邏輯的底層。在代碼中,gui對象傳遞一些參數(shù)來調用業(yè)務邏輯對象。這個過程通常被描述為一個對象向另一個對象發(fā)送請求。
命令模式建議gui對象不要直接提交這些請求。請求的所有細節(jié)(如被調用對象、方法名和參數(shù)列表)都要提取出來,形成一個命令類,這個命令類只包含一個觸發(fā)請求的方法。gui對象可以觸發(fā)命令,命令對象將自己處理所有細節(jié)。所有命令都實現(xiàn)相同的接口。界面通常只有一個不帶任何參數(shù)的執(zhí)行方法,它允許您使用同一個請求發(fā)送方執(zhí)行不同的命令,而無需與特定的命令類耦合。此外,還有一個額外的好處。現(xiàn)在你可以在運行時切換連接到發(fā)送器的命令對象,從而改變發(fā)送器 的行為。
3.適用性如果需要通過一個操作來參數(shù)化一個對象,可以使用command mode命令模式將一個特定的方法調用轉換成一個獨立的對象。因此,您可以將命令作為方法的參數(shù)傳遞,將命令保存在其他對象中,或者在運行時切換連接的命令。
如果要將操作放入隊列或遠程執(zhí)行操作,可以使用命令模式。像其他對象一樣,命令也可以序列化(序列化意味著轉換為字符串),這樣就可以很容易地將它們寫入文件或數(shù)據(jù)庫。一段時間后,字符串可以恢復到原來的命令對象。因此,您可以延遲或計劃命令的執(zhí)行。但是它的作用遠不止于此!同樣,你也可以將命令放入隊列,記錄下來或者通過網(wǎng)絡發(fā)送。
如果要實現(xiàn)操作回滾功能,可以使用命令模式。雖然有很多方法可以實現(xiàn)撤銷和重做功能,但命令模式可能是最常用的一種。為了能夠回滾操作,需要實現(xiàn)已執(zhí)行操作的歷史功能。命令歷史是一個堆棧結構,包含所有已執(zhí)行的命令對象及其相關的程序狀態(tài)備份。這種方法有兩個缺點:
首先,保存程序狀態(tài)的功能不容易實現(xiàn),因為有些狀態(tài)可能是私有的。您可以使用memento模式在一定程度上解決這個問題。
其次,備份狀態(tài)可能會占用大量內存。因此,有時需要求助于另一種實現(xiàn)方法:命令不需要恢復原始狀態(tài),而是執(zhí)行相反的操作。逆向操作也有代價:可能很難甚至不可能實現(xiàn)。
支持修改日志,這樣當系統(tǒng)崩潰時,可以重做修改。在命令界面中增加加載操作和存儲操作可以用來保持一致的修改日志。從崩潰中恢復的過程包括從磁盤重新讀取記錄的命令,并使用執(zhí)行操作重新執(zhí)行它們,以構建具有基于原語操作的高級操作的系統(tǒng)。這種結構在支持事物的信息系統(tǒng)中很常見。事務封裝了一組對數(shù)據(jù)的更改。命令模式提供了一種對事務建模的方法。命令有一個公共接口,使您能夠以相同的調用所有事務。同時,很容易添加新的事務來擴展系統(tǒng)4的結構。
5.效果1。命令模式將調用操作的對象與知道如何實現(xiàn)操作的對象分離開來(單一責任原則)。
2.實現(xiàn)撤銷和恢復功能。
3.實現(xiàn)操作的延遲執(zhí)行
4.多個命令可以組合成一個組合命令。普通的一般來說,組合命令是復合模式的一個例子。
5.您可以在程序中創(chuàng)建新命令,而無需修改客戶端代碼(開閉原則)
6.代碼實現(xiàn)commands/command . java: ;抽象基本命令。
包command.commands導入命令.編輯器.編輯器;/* * * * @作者高明* @ date 2021/7/25-20 : 05 */public抽象類命令{ public editor editor私有字符串備份;command(editor editor){ this . editor = editor;} void backup{ backup = editor . textfield . gettext;} public void undo{ editor . textfield . settext(backup);}公共抽象布爾execute;} commands/copycommand.java:將選定的文本復制到剪貼板。
包command.commands導入命令.編輯器.編輯器;/* * * * @作者高明* @ date 2021/7/25-20 : 06 */public class copy command擴展命令{ public copy command(editor editor){ super(editor);} @ override public boolean execute{ editor . clipboard = editor . textfield . getselectedtext;返回false} } commands/pastecommand.java:從剪貼板粘貼文本。
包command.commands導入命令.編輯器.編輯器;/* * * * @作者高明* @ date 2021/7/25-20 : 06 */public class paste command擴展命令{ public paste command(editor editor){ super(editor);} @ override public boolean execute{ if(editor . clipboard = = null | | editor . clipboard . isempty)返回falsebackup;editor . textfield . insert(editor . clipboard,editor . textfield . getcaretposition);返回true} } commands/cutcommand.java:將文本剪切到剪貼板。
包command.commands導入命令.編輯器.編輯器;/* * * * @作者高明* @ date 2021/7/25-20 : 06 */public class cut command擴展命令{ public cut command(editor editor){ super(editor);} @ override public boolean execute{ if(editor . textfield . getselectedtext。isempty)返回falsebackup;string source = editor . textfield . gettext;editor . clipboard = editor . textfield . getselectedtext;editor . textfield . settext(cut string(source));返回true}私有字符串cut string(string source){ string start = source . substring(0,editor . textfield . getselectionstart);string end = source . substring(editor . textfield . get selection end);返回起始端;} } commands/commandhistory.java:指揮史
包command.commands導入java . util . stack;/* * * * @作者高明* @ date 2021/7/25-20 : 06 */public class command history { private stack command history = new stack;public void push(command c){ history . push(c);}公共命令pop{ return history . pop;} public bool:文本編輯器的gui。
package command.editor導入command . commands . *;導入javax . swing . *;導入java . awt . *;導入java . awt . event . action event;導入java . awt . event . action listener;/* * * * @作者高明* @ date 2021/7/25-20 : 06 */public class editor { public jtextarea textfield;公共字符串剪貼板;私有command history history = new command history;public void init{ jframe frame = new jframe( 文本編輯器(類型使用按鈕,盧克!) );jpanel content = new jpanel;兄弟me.setcontentpane(內容);frame . setdefaultcloseoperation(window constants。exit _ on _ close);content.setlayout(新的boxlayout(content,boxlayout。y _軸));textfield = new jtextarea;textfield . setline wrap(true);content . add(textfield);jpanel buttons = new jpanel(new flow layout(flow layout。居中));jbutton ctrl c = new jbutton( ctrl c );jbutton ctrl x = new jbutton( ctrl x );jbutton ctrl lv = new jbutton( ctrl v );jbutton ctrlz = new jbutton( ctrl z );編輯器editor = thisctrlc . addactionlistener(new action listener{ @ override public void action performed(actionevent e){ execute command(new copy command(editor));} });ctrl x . addactionlistener(new action listener{ @ override public void action performed(action event e){ execute command(new cut command(editor));} });ctrlv . addactionlistener(new action listener{ @ override public void action performed(action event e){ execute command(new paste command(editor));} });ctrlz . addactionlistener(new action listener{ @ override public void actionper formed(action event e){ undo;} });buttons . add(ctrl lc);buttons . add(ctrl lx);buttons . add(ctrl lv);buttons . add(ctrlz);content.add(按鈕);frame.setsize(450,200);frame . setlocationrelativeto(null);frame . set visible(true);} private void execute command(command命令){ if(command . execute){ history . push(command);} }私有void undo{ if(history . isempty)return;command command = history . pop;如果(命令!= null){ command . undo;} } } d:客戶端代碼
包命令;導入命令.編輯器.編輯器;/* * * * @作者高明* @ date 2021/7/25-20 : 05 */public class demo { public static void main(string[]args){ editor editor = new editor;editor . init;}}運行結果
7.與其他模式的關系責任鏈模式、命令模式、中介者模式和觀察者模式用于處理請求的發(fā)送者和接收者之間的不同連接模式:-責任鏈動態(tài)地將請求按順序傳輸給一系列潛在接收者,直到其中一個接收者處理該請求-命令在發(fā)送者和請求者之間建立單向連接-中介者清除發(fā)送者和請求者之間的直接連接,并強制它們通過中間對象間接通信-觀察者允許接收者動態(tài)地訂閱或取消接收請求。
你可以同時使用命令和紀念品模式來實現(xiàn) 撤消 。在這種情況下,命令用于在目標對象上執(zhí)行各種操作,備忘錄用于在命令執(zhí)行之前保存對象的狀態(tài)。原型模式可用于保存命令的歷史。訪問者模式可以被視為命令模式的增強版本對象可以對不同類的各種對象執(zhí)行操作。命令和策略模式看起來很相似,因為兩者都可以通過某些行為來參數(shù)化對象。然而,他們的意圖是非常不同的:-您可以使用命令將任何操作轉換為對象。操作的參數(shù)將成為對象的成員變量。您可以延遲操作的執(zhí)行,將操作放入隊列,保存歷史命令或將命令發(fā)送到遠程服務,等等。-策略通常可以用來描述完成某件事情的不同,允許你在同一個上下文類中切換算法。
責任鏈的管理者可以用命令來實現(xiàn)。在這種情況下,您可以對請求所表示的同一個上下文對象執(zhí)行許多不同的操作。還有一種實現(xiàn),就是請求本身就是一個命令對象。在這種情況下,您可以在由一系列不同上下文連接的鏈上執(zhí)行相同的操作。
8.已知應用的例子:命令模式在java代碼中非常常見。在大多數(shù)情況下,它被用來代替包含行為的回調函數(shù)。此外,它還用于任務排序和記錄操作歷史等。下面是核心java庫中的一些例子:java.lang.runnable的所有實現(xiàn)javax.swing.action的所有實現(xiàn)標識方法:一個命令模式可以由一個抽象或接口類型(sender)中的行為方法標識,該方法調用另一個不同的抽象或接口類型(receiver)實現(xiàn)中的方法,該方法在創(chuàng)建時被命令模式的實現(xiàn)封裝。
標簽:
命令操作
了解更多命令模式的功能(命令模式的概念)相關內容請關注本站點。