輕鬆實現記錄與撤銷——C#中的Command模式
阿新 • • 發佈:2020-06-01
Command模式屬於行為模式,作為大名鼎鼎的23個設計模式之一,Command模式理解起來不如工廠模式,單例模式等那麼簡單直白。究其原因,行為模式著重於使用,如果沒有程式設計實踐,確實不如創造模式那麼直白。我們先看看UML類圖。
![](https://img2020.cnblogs.com/blog/699616/202005/699616-20200531211709411-1430504978.png)
估計很多同學看著圖就暈了,那麼多東西,Command和Concrete Command還好理解,那些Receiver和Invoker又是什麼東西呢?
彆著急,只要理解了一點,這個模式就很容易理解了,下面劃重點,**Command模式最主要的特點,是將命令封裝成類,在類中儲存命令執行的上下文(即該命令執行的引數,執行的物件),以實現命令執行物件和命令發出物件的解耦**。
這樣一來是不是覺得好理解多了?Command類裡面的Receiver,就是命令具體執行的物件。這裡的Client可以理解為裝配環境,在這裡面程式碼例項化Command。Invoker內部儲存命令(可以儲存多條命令,實現命令記錄檢視,撤銷等),客戶端程式碼通過Invoker來操作命令。接下來我們看看示例程式碼。
#### 定義Command介面 ####
首先我們定義一個支援撤銷的Command介面。
```csharp
interface Command
{
void Execute();
void Undo();
}
```
#### 定義Receiver ####
接下來我們定義Receiver,也就是命令的執行物件,這裡我們定義一個Ball類。
```csharp
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);
}
}
```
#### 定義具體命令
這裡定義兩個命令,一個修改名字,一個修改大小。
```csharp
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
接下來是Invoker,,也就是儲存命令,並最終會被使用者程式碼呼叫的類,這裡我們叫它CommandManager。
```csharp
class CommandManager
{
priva