日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > asp.net >内容正文

asp.net

设计模式学习笔记(十七)——Command命令模式

發(fā)布時(shí)間:2023/12/9 asp.net 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 设计模式学习笔记(十七)——Command命令模式 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
設(shè)計(jì)模式學(xué)習(xí)筆記(十七)——Command命令模式

Command命令模式介紹:

Command命令模式是一種對(duì)象行為型模式,它主要解決的問(wèn)題是:在軟件構(gòu)建過(guò)程中,“行為請(qǐng)求者”與“行為實(shí)現(xiàn)者”通常呈現(xiàn)一種“緊耦合”的問(wèn)題。如下圖:

?

有時(shí)我們必須向某對(duì)象提交請(qǐng)求,但并不知道關(guān)于被請(qǐng)求的操作或請(qǐng)求的接受者的任何信息,此時(shí)無(wú)法抵御變化的緊耦合是不合適的。如:需要對(duì)行為進(jìn)行“記錄、撤銷/重做、事務(wù)”等處理。我們所要做的是將依賴關(guān)系轉(zhuǎn)化,將緊耦合變?yōu)樗神詈稀t上圖的形式轉(zhuǎn)化為如下形式:



???????

?

?????? Command模式通過(guò)將請(qǐng)求本身變成一個(gè)對(duì)象來(lái)使行為請(qǐng)求者可向未指定的應(yīng)用對(duì)象提出請(qǐng)求。

?????? GoF《設(shè)計(jì)模式》中說(shuō)道:將一個(gè)請(qǐng)求封裝為一個(gè)對(duì)象,從而使你可用不同的請(qǐng)求對(duì)客戶進(jìn)行參數(shù)化;對(duì)請(qǐng)求排隊(duì)或記錄請(qǐng)求日志,以及支持可撤銷的操作。

Command命令模式結(jié)構(gòu):

??????


?

?

定義場(chǎng)景:

?????? 現(xiàn)在來(lái)看一個(gè)場(chǎng)景:對(duì)于notepad大家都很熟悉,在我們使用notepad打開(kāi)一個(gè)文檔之后,往往做一些操作,如;輸入字符(Write)、刪除前一個(gè)字符(Delete)、撤銷剛才的操作(UnDo)。現(xiàn)在我們就用Console程序模擬這個(gè)過(guò)程。

代碼實(shí)現(xiàn)與結(jié)構(gòu)分析:

?????? 在實(shí)現(xiàn)代碼前先說(shuō)明實(shí)現(xiàn)Command模式需要烤爐的一些問(wèn)題:

1、? 一個(gè)命令對(duì)象應(yīng)達(dá)到何種智能程度:命令對(duì)象的能力可大可小。這樣就出現(xiàn)了兩個(gè)極端。一是:它僅確定一個(gè)接收者和執(zhí)行該請(qǐng)求的動(dòng)作;一是:它自己實(shí)現(xiàn)所有功能,根本不需要額外的接收者對(duì)象。我給他們起了便于我方便記憶的名字,第一種叫OperationCommand,第二種叫ObjectCommand。當(dāng)然只是為了便于記憶和理解,如有不理解,在代碼實(shí)現(xiàn)與結(jié)構(gòu)分析最后我會(huì)再談?wù)勎业南敕?#xff0c;如有不妥,還請(qǐng)多提意見(jiàn),一會(huì)在下面的代碼中會(huì)分別對(duì)這兩種情況進(jìn)行示范。

2、? 支持取消和重做:為了達(dá)到這個(gè)目的ConcreteCommand類中要存儲(chǔ)額外的狀態(tài)信息。也就是上圖中ConcreteCommand的state屬性。

3、? 避免取消操作中過(guò)程中的錯(cuò)誤積累:由于命令重復(fù)的執(zhí)行、取消執(zhí)行和重執(zhí)行的過(guò)程可能會(huì)積累錯(cuò)誤,以致一個(gè)應(yīng)用的狀態(tài)最終偏離初始值。這就有必要在Command中存入更多的信息以保證這些對(duì)象可被精確的復(fù)原。

下面來(lái)看看代碼上的實(shí)現(xiàn):首先,我先作一個(gè)OperationCommand的例子,先做一個(gè)請(qǐng)求的接收者Document(也就是結(jié)構(gòu)圖中的Receiver)

class Document

??? {

??????? public string strContent;

?

??????? public Document()

??????? {

??????????? strContent = "";

??????? }

}

?

在這個(gè)程序中我們還要定義一個(gè)抽象類Command,對(duì)于OperationCommand類型來(lái)說(shuō),它僅確定一個(gè)接收者和執(zhí)行該請(qǐng)求的動(dòng)作。所以,在抽象類Command中,只聲明一個(gè)Excute的方法。這個(gè)方法在其子類中進(jìn)行實(shí)現(xiàn)。(當(dāng)然這個(gè)Command還可以定義成接口)

abstract class Command

??? {

??????? public Command()

??????? { }

??????? public abstract void Excute();

}

?

接下來(lái),就要實(shí)現(xiàn)各種操作(結(jié)構(gòu)圖中的ConcreteCommand),代碼如下

//寫(xiě)操作

class WriteCommand :Command

??? {

??????? Document doc;

??????? ArrayList ObjectState;

??????? public WriteCommand(Document doc,ArrayList state)

??????? {

??????????? this.doc = doc;

??????????? ObjectState = state;

??????? }

?

??????? public override void Excute()

??????? {

??????????? doc.strContent += Console.ReadLine();

??????????? ObjectState.Add(doc.strContent);

??????? }

??? }

???

??? //刪除操作

??? class DeleteCommand : Command

??? {

??????? Document doc;

??????? ArrayList ObjectState;

??????? public DeleteCommand(Document doc,ArrayList state)

??????? {

??????????? this.doc = doc;

??????????? ObjectState = state;

??????? }

?

??????? public override void Excute()

??????? {

??????????? doc.strContent = doc.strContent.Substring(0, doc.strContent.Length - 1);

??????????? ObjectState.Add(doc.strContent);

??????? }

??? }

?

??? //撤銷操作

??? class UnDoCommand : Command

??? {

??????? Document doc;

??????? ArrayList ObjectState;

??????? public UnDoCommand(Document doc,ArrayList state)

??????? {

??????????? this.doc = doc;

??????????? ObjectState = state;

??????? }

?

??????? public override void Excute()

??????? {

??????????? doc.strContent = (string)ObjectState[ObjectState.Count - 2];

??????????? ObjectState.Add(doc.strContent);

??????? }

}

?

實(shí)現(xiàn)了各種操作后,編寫(xiě)一個(gè)客戶代碼進(jìn)行測(cè)試

class Program

??? {

??????? static void Main(string[] args)

??????? {

??????????? Document doc = new Document();

??????????? Console.WriteLine("Please Input next operation:");

??????????? string strOperation =Console.ReadLine();

??? ????????Command com = null;

??????????? ArrayList ObjectState =new ArrayList();//Record state

??????????? while (strOperation !="Exit")

??????????? {

??????????????? switch (strOperation.ToLower())

??????????????? {

??????????????????? case "write":

??? ????????????????????com = newWriteCommand(doc, ObjectState);

??????????????????????? com.Excute();

??????????????????????? Console.WriteLine("Write Operation:" + doc.strContent);

??????????????????????? break;

??????????????????? case "del":

???????????? ???????????com = newDeleteCommand(doc, ObjectState);

??????????????????????? com.Excute();

??????????????????????? Console.WriteLine("Delete Operation:" + doc.strContent);

??????????????????????? break;

??????????????????? case "undo":

?????????????????? ?????com = newUnDoCommand(doc, ObjectState);

??????????????????????? com.Excute();

??????????????????????? Console.WriteLine("UnDo Operation:" + doc.strContent);

??????????????????????? break;

??????????????????? default:

??????????????????????? Console.WriteLine("Wrong Operation:");

??????????????????????? break;

??????????????? }

??????????????? Console.WriteLine("Please Input next operation:");

??????????????? strOperation = Console.ReadLine();

??????????? }

??????? }

}

?

測(cè)試結(jié)果:

Please Input next operation:

write

k

Write Operation:k

Please Input next operation:

write

i

Write Operation:ki

Please Input next operation:

write

d

Write Operation:kid

Please Input next operation:

write

d

Write Operation:kidd

Please Input next operation:

del

Delete Operation:kid

Please Input next operation:

undo

UnDo Operation:kidd

Please Input next operation:

?

下面再來(lái)實(shí)現(xiàn)以下ObjectCommand的例子,首先還是編寫(xiě)一個(gè)已存在的請(qǐng)求接收者Document(結(jié)構(gòu)圖中的Receiver)

class Document

??? {

??????? public string strContent;

?

??????? public Document()

??????? {

??????????? strContent = "";

??????? }

}

?

接下來(lái)實(shí)現(xiàn)抽象類Command(也可以使用接口),對(duì)于ObjectCommand類型來(lái)說(shuō),它自己實(shí)現(xiàn)所有功能,根本不需要額外的接收者對(duì)象,所以在Command中聲明了所有的操作

abstract class Command

??? {

??????? public Command()

??????? {? }

?

??????? public abstract void Write();

??????? public abstract void Delete();

??????? public abstract void UnDo();

}

?

有了Command,就可以實(shí)現(xiàn)具體的操作類型DocumentCommand(結(jié)構(gòu)圖中的ConcreteCommand)

class DocumentCommand :Command

??? {

??????? private Document doc;

??????? private ArrayList ObjectState = new ArrayList();//Record State

??????? public DocumentCommand(Document doc)

??????? {

??????????? this.doc = doc;

??????? }

?

??????? public override void Write()

??????? {

??????????? Console.WriteLine("Please input an character:");

??????????? string strRead = Console.ReadLine();

??????????? doc.strContent += strRead;

??????????? ObjectState.Add(doc.strContent);

??????? }

?

???? ???public override void Delete()

??????? {

??????????? doc.strContent = doc.strContent.Substring(0, doc.strContent.Length - 1);

??????????? ObjectState.Add(doc.strContent);???????????

??????? }

?

??????? public override void UnDo()

??????? {

??????????? doc.strContent = (string)ObjectState[ObjectState.Count - 2];

??????????? ObjectState.Add(doc.strContent);

??????? }

}??

?

接下來(lái)就用一個(gè)客戶端代碼作一下測(cè)試

class Program

??? {

??????? static void Main(string[] args)

??????? {

??????????? Document doc = new Document();

???? ???????DocumentCommand com =new DocumentCommand(doc);

??????????? Console.WriteLine("Please Input next operation:");

??????????? string strOperation =Console.ReadLine();

??????????? while (strOperation !="Exit")

??????????? {

??????????????? switch (strOperation.ToLower())

??????????????? {

??????????????????? case "write":

??????????????????????? com.Write();

??????????????????????? Console.WriteLine("Write Operation:" + doc.strContent);

??????????????????????? break;

??????????????????? case "del":

?? ?????????????????????com.Delete();

??????????????????????? Console.WriteLine("Delete Operation:" + doc.strContent);

??????????????????????? break;

??????????????????? case "undo":

??????????????????????? com.UnDo();

??????????????????????? Console.WriteLine("UnDo Operation:" + doc.strContent);

??????????????????????? break;

??????????????????? default:

??????????????????????? Console.WriteLine("Wrong Operation:");

??????????????????????? break;

??????????????? }

??????????????? Console.WriteLine("Please Input next operation:");

??????????????? strOperation = Console.ReadLine();

??????????? }

??????? }

??? }

?

測(cè)試結(jié)果如下:

Please Input next operation:

write

Please input an character:

k

Write Operation:k

Please Input next operation:

write

Please input an character:

i

Write Operation:ki

Please Input next operation:

write

Please input an character:

d

Write Operation:kid

Please Input next operation:

write

Please input an character:

d

Write Operation:kidd

Please Input next operation:

del

Delete Operation:kid

Please Input next operation:

undo

UnDo Operation:kidd

Please Input next operation:

?

這兩個(gè)程序中需要有幾點(diǎn)說(shuō)明:

1、????????????? 對(duì)于OperationCommand,我的理解是它所實(shí)現(xiàn)的Command只是某一個(gè)操作對(duì)于某一個(gè)接收者,所以我給它取名為OperationCommand。對(duì)于ObjectCommand,是實(shí)現(xiàn)這樣一種對(duì)象,它實(shí)現(xiàn)了請(qǐng)求接收者的所有操作,所以取名為ObjectCommand

2、????????????? 在代碼實(shí)例中,我對(duì)狀態(tài)的保存處理相對(duì)簡(jiǎn)單,但這是因?yàn)槔昧薙tring對(duì)象的特點(diǎn),當(dāng)String對(duì)象被修改時(shí),系統(tǒng)會(huì)重新分配一塊內(nèi)存。不修改原內(nèi)存上的內(nèi)容。如果是要保存其他的引用類型應(yīng)當(dāng)注意使用深拷貝,否則,所保存的狀態(tài)對(duì)象都指向一個(gè)內(nèi)存地址,隨著狀態(tài)的改變,保存不了原有的狀態(tài)。

3、????????????? 在對(duì)象狀態(tài)的保存上,我們可以使用Prototype模式。

Command模式的幾個(gè)要點(diǎn):

1、? Command模式的根本目的在于將“行為請(qǐng)求者”與“行為實(shí)現(xiàn)者”解耦,在面向?qū)ο笳Z(yǔ)言中,常見(jiàn)的實(shí)現(xiàn)手段是“將行為抽象為對(duì)象”。

2、? 實(shí)現(xiàn)Command接口的具體命令對(duì)象ConcreteCommand 有時(shí)候根據(jù)需要可能會(huì)保存一些額外的狀態(tài)信息。

3、? 通過(guò)使用Composite模式,可以將多個(gè)“命名”封裝為一個(gè)“復(fù)合命令”MacroCommand。

4、? Command模式與C#中的Delegate有些類似。但兩者定義行為接口的規(guī)范有所區(qū)別:Command以面向?qū)ο笾械摹敖涌?實(shí)現(xiàn)”類定義行為接口規(guī)范,更嚴(yán)格,更符合抽象原則:Delegate以函數(shù)簽名來(lái)定義行為接口規(guī)范,更靈活,但抽象能力比較弱

http://www.cnblogs.com/kid-li/category/44668.html

轉(zhuǎn)載于:https://www.cnblogs.com/xiayong123/p/3716998.html

總結(jié)

以上是生活随笔為你收集整理的设计模式学习笔记(十七)——Command命令模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。