意圖 0 適用性 1 結構 2 實現 3 效果 4 參考 5意圖將請求封裝成一個對象,客戶接受請求參數;可以對請求排隊或者記錄請求日誌,以及可以支持撤銷操作適用性抽象出待執行的動作以參數化某對象。命令模式是回調機制的一個面向對象的替代品在不同的時刻指定、排列和執行請求支持取消操作支持修...
意圖
將請求封裝成一個對象,客戶接受請求參數;可以對請求排隊或者記錄請求日誌,以及可以支持撤銷操作
適用性
- 抽象出待執行的動作以參數化某對象。命令模式是回調機制的一個面向對象的替代品
- 在不同的時刻指定、排列和執行請求
- 支持取消操作
- 支持修改日誌
- 支持事務
結構
實現
使用遙控器,實現對一個燈的遠程遙控。燈有開、關兩個操作。
class Light
{
public void On()
{
Console.WriteLine("light is on");
}
public void Off()
{
Console.WriteLine("light is off");
}
}
首先抽象出操作類或者介面
public interface ICommand
{
void Execute();
void Undo();//撤銷
}
對這開、關兩個操作請求進行封裝,操作需要一個對象作為初始化參數
class LightOnCommand : ICommand
{
private Light _light;
public LightOnCommand(Light light)
{
this._light = light;
}
public void Execute()
{
_light.On();
}
public void Undo()
{
_light.Off();
}
}
class LightOffCommand:ICommand
{
private Light _light;
public LightOffCommand(Light light)
{
this._light = light;
}
public void Execute()
{
_light.Off();
}
public void Undo()
{
_light.On();
}
}
遙控器接受請求作為初始化參數
class SimpleRemoteControl
{
private ICommand _onSlot;
private ICommand _offSlot;
private ICommand _lastCommand;//記錄最後一次操作請求
public void SetCommand(ICommand onCommand,ICommand offCommand)
{
_onSlot = onCommand;
_offSlot = offCommand;
}
public void OnButtonWasPressed()
{
_onSlot.Execute();
_lastCommand = _onSlot;
}
public void OffButtonWasPressed()
{
_offSlot.Execute();
_lastCommand = _offSlot;
}
public void Undo()
{
_lastCommand.Undo();
}
}
使用封裝好的請求對客戶(遙控器)進行參數化,使其可以控制燈,也可以封裝更多操作,使遙控器可以控制其他物品
class Program
{
static void Main(string[] args)
{
SimpleRemoteControl remote = new SimpleRemoteControl();
Light light = new Light();
LightOnCommand lightOn = new LightOnCommand(light);
LightOffCommand lightOff = new LightOffCommand(light);
remote.SetCommand(lightOn, lightOff);
remote.OnButtonWasPressed();
remote.OffButtonWasPressed();
remote.Undo();//撤銷上一步操作
Console.ReadKey();
}
}
運行結果
效果
- 將調用操作的對象與知道如何實現該操作的對象解耦
- 可以將多個命令裝配成一個複合命令
- 增加新的命令無需修改已有的類