模式定义
命令模式(Command Pattern):将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。
UML类图
- 抽象命令 Command 关联接收者,声明抽象命令函数。
- 具体命令 ConcreteCommand 抽象命令类的子类,通过调用接收者对象方法实现了具体命令。
- 调用者 Invoker 又称为请求者,它通过命令对象来执行请求。依赖命令对象。
- 接收者 Receiver 执行与请求相关的子操作。
代码结构
public class CommandApp
{
public void Run()
{
Receiver receiver = new Receiver();
Command command = new ConcreteCommand(receiver);
Invoker invoker = new Invoker();
invoker.SetCommand(command);
invoker.ExecuteCommand();
Console.ReadKey();
}
}
/// <summary>
/// 抽象命令
/// </summary>
abstract class Command
{
protected Receiver receiver;
public Command(Receiver receiver)
{
this.receiver = receiver;
}
public abstract void Execute();
}
/// <summary>
/// 具体命令
/// </summary>
class ConcreteCommand : Command
{
public ConcreteCommand(Receiver receiver) : base(receiver)
{
}
public override void Execute()
{
receiver.Action();
}
}
/// <summary>
/// 接收者
/// </summary>
class Receiver
{
public void Action()
{
Console.WriteLine("Called Receiver.Action()");
}
}
/// <summary>
/// 调用者
/// </summary>
class Invoker
{
private Command _command;
public void SetCommand(Command command)
{
this._command = command;
}
public void ExecuteCommand()
{
_command.Execute();
}
}
情景案例
电视机遥控器例子,电视器Receiver
遥控器Invoker
。电视只有设置具体的台和声明,这里通过命名模式添加了在原来电视台和声音的加减。
public class User
{
public void Use()
{
TV tv = new TV();
Command command = new ConcreteCommand(tv);
RemoteControl remote = new RemoteControl();
remote.SetCommand(command);
remote.SetChannel(50);
tv.Display();
remote.DownChannel();
remote.UpSound();
tv.Display();
Console.ReadKey();
}
}
/// <summary>
/// 抽象命令
/// </summary>
abstract class Command
{
protected TV tv;
public Command(TV tv)
{
this.tv = tv;
}
/// <summary>
/// 设置音量
/// </summary>
/// <param name="n"></param>
public abstract void SetSound(int n);
/// <summary>
/// 设置频道
/// </summary>
/// <param name="n"></param>
public abstract void SetChannel(int n);
}
/// <summary>
/// 具体命令
/// </summary>
class ConcreteCommand : Command
{
public ConcreteCommand(TV tv) : base(tv)
{
}
public override void SetChannel(int n)
{
this.tv.SetChannel(n);
}
public override void SetSound(int n)
{
this.tv.SetSound(n);
}
}
/// <summary>
/// 电视机
/// </summary>
class TV
{
private int _sound = 0;
private int _channel = 0;
public void SetSound(int n)
{
_sound = n;
}
public void SetChannel(int n)
{
_channel = n;
}
public void Display()
{
Console.WriteLine("现在电视的频道是:{0},音量是:{1}", _channel, _sound);
}
}
/// <summary>
/// 遥控器
/// </summary>
class RemoteControl
{
private int _sound=0;
private int _channel=0;
/// <summary>
/// 最多有99个频道
/// </summary>
private int _maxChannel = 99;
/// <summary>
/// 音量最大100
/// </summary>
private int _maxSound = 100;
private Command _command;
public void SetCommand(Command command)
{
this._command = command;
}
/// <summary>
/// 直接按数字输入频道
/// </summary>
/// <param name="n"></param>
public void SetChannel(int n)
{
if (n >= 0 && n <= _maxChannel)
{
_channel = n;
this._command.SetChannel(n);
}
}
public void UpSound()
{
if(_sound < _maxSound)
{
_sound++;
}
this.SetSound(_sound);
}
public void DownSound()
{
if (_sound > 0)
{
_sound--;
}
this.SetSound(_sound);
}
public void UpChannel()
{
if (_channel < _maxChannel)
{
_channel++;
}
else
{
_channel = 0;
}
this.SetChannel(_channel);
}
public void DownChannel()
{
if (_channel > 0)
{
_channel--;
}
else
{
_channel = _maxChannel;
}
this.SetChannel(_channel);
}
private void SetSound(int n)
{
if(n>=0 && n<= _maxSound)
{
_sound = n;
this._command.SetSound(_sound);
}
}
}