Command模式屬於行爲模式,做爲大名鼎鼎的23個設計模式之一,Command模式理解起來不如工廠模式,單例模式等那麼簡單直白。究其緣由,行爲模式着重於使用,若是沒有編程實踐,確實不如創造模式那麼直白。咱們先看看UML類圖。編程
估計不少同窗看着圖就暈了,那麼多東西,Command和Concrete Command還好理解,那些Receiver和Invoker又是什麼東西呢?
彆着急,只要理解了一點,這個模式就很容易理解了,下面劃重點,Command模式最主要的特色,是將命令封裝成類,在類中保存命令執行的上下文(即該命令執行的參數,執行的對象),以實現命令執行對象和命令發出對象的解耦。
這樣一來是否是以爲好理解多了?Command類裏面的Receiver,就是命令具體執行的對象。這裏的Client能夠理解爲裝配環境,在這裏面代碼實例化Command。Invoker內部保存命令(能夠保存多條命令,實現命令記錄查看,撤銷等),客戶端代碼經過Invoker來操做命令。接下來咱們看看示例代碼。設計模式
首先咱們定義一個支持撤銷的Command接口。設計
interface Command { void Execute(); void Undo(); }
接下來咱們定義Receiver,也就是命令的執行對象,這裏咱們定義一個Ball類。code
class Ball { public int Size { get; set; } = 10; public string Name { get; set; } = "My First Ball"; public void Inspect() { Console.WriteLine("My Name is {0} and size is {1}", Name, Size); } }
這裏定義兩個命令,一個修更名字,一個修改大小。對象
class ChangeNameCommand : Command { private Ball _Ball; private string _OldName; public string NameYouWant { get; set; } public ChangeNameCommand(Ball ball) { _Ball = ball; } public void Execute() { _OldName = _Ball.Name; _Ball.Name = NameYouWant; } public void Undo() { _Ball.Name = _OldName; } } class ChangeSizeCommand : Command { //代碼大同小異,略 }
接下來是Invoker,,也就是存儲命令,並最終會被用戶代碼調用的類,這裏咱們叫它CommandManager。blog
class CommandManager { private Stack<Command> commands = new Stack<Command>(); public void RunCommand(Command command) { command.Execute(); commands.Push(command); } public void Undo() { if (commands.Count > 0) { var command = commands.Pop(); command.Undo(); } } public void ShowCommands() { var temp = commands.Reverse(); foreach(var command in temp) { //display command } } }
如今咱們看看客戶端代碼是怎麼使用他們的,定義Ball,定義命令,經過CommandManager去調用,這樣能夠方便查看命令記錄,撤銷命令,等。接口
static void Main(string[] args) { Ball ball = new Ball(); ball.Inspect(); ChangeNameCommand changeName = new ChangeNameCommand(ball) { NameYouWant = "Changed" }; ChangeSizeCommand changeSize = new ChangeSizeCommand(ball) { SizeYouWant = 20 }; CommandManager manager = new CommandManager(); manager.RunCommand(changeName); manager.RunCommand(changeSize); ball.Inspect(); manager.ShowCommands(); manager.Undo(); ball.Inspect(); manager.Undo(); ball.Inspect(); }
就醬,咱們已經實現了命令模式,而且還支持命令的記錄與撤銷,但願能對你們有點幫助。get