23种设计模式之命令模式(Command)
命令模式是一种对象的行为型模式,类似于传统程序设计方法中的回调机制,它将一个请求封装为一个对象,从而使得可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。命令模式是对命令的封装,将发出命令的责任和执行命令的责任分割开,委派给不同的对象,以实现发送者和接收者完全解耦,提供更大的灵活性和可扩展性。
优点:
1)将调用操作的对象与知道如何完成该操作的对象相分离。
2)更容易添加新命令,因为不用修改已有类。
使用场景:
1)想要通过要执行的动作来参数化对象。
2)要在不同的时间指定、排序以及执行请求。
3)必须支持Undo、日志记录或事务。
Command 模式
/// <summary> /// 电灯类 /// </summary> public class Light { /// <summary> /// 调整灯光亮度,0表示关灯,100表示亮度最大 /// </summary> /// <param name="degree"></param> public void TurnLight(int degree) { if (degree == 0) { Console.WriteLine("关灯"); } else { Console.WriteLine("开灯了,度数为:" + degree); } } }
/// <summary> /// 电视机类 /// </summary> public class TV { /// <summary> /// 0表示关机,1表示开机并切换到1频道 /// </summary> /// <param name="channel"></param> public void SetChannel(int channel) { if (channel == 0) { Console.WriteLine("关机"); } else { Console.WriteLine("表示开机并切换到" + channel + "频道"); } } }
/// <summary> /// 命令接口 /// </summary> public interface Command { /// <summary> /// 打开 /// </summary> void On(); /// <summary> /// 关闭 /// </summary> void Off(); }
/// <summary> /// 遥控器类 /// </summary> public class RemoteController { //遥控器有4个按钮,按照编号分别对应4个Command对象 protected Command[] commands = new Command[4]; public void OnPressButton(int button) { //按钮被按下时执行命令对象中的命令 if (button % 2 == 0) { commands[button].On(); } else { commands[button].Off(); } } public void SetCommand(int button, Command command) { commands[button] = command;//设置每个按钮对象的命令对象 } }
/// <summary> /// 电灯命令类 /// </summary> public class LightCommand : Command { protected Light light; public void On() { light.TurnLight(100);//打开最大 } public void Off() { light.TurnLight(0);//打开最低 } public LightCommand(Light light) { this.light = light; } }
/// <summary> /// 电视机命令类 /// </summary> public class TVCommand : Command { protected TV tv; public void On() { tv.SetChannel(1); } public void Off() { tv.SetChannel(0); } public TVCommand(TV tv) { this.tv = tv; } }
class Program { static void Main(string[] args) { //命令设计模式 Light light = new Light(); TV tv = new TV(); LightCommand lightCommand = new LightCommand(light); TVCommand tvCommand = new TVCommand(tv); RemoteController remoteController = new RemoteController(); remoteController.SetCommand(0, lightCommand); remoteController.SetCommand(1, lightCommand); remoteController.SetCommand(2, tvCommand); remoteController.SetCommand(3, tvCommand); remoteController.OnPressButton(2);//按下按钮2 } }