C# - 设计模式 - 命令模式
命令模式
问题场景
一个遥控器有1个插槽,插槽对应了两个按钮,一个on,一个off,插槽可以临时插入一个命令,当点击遥控器的on或off按钮时就会调用命令,命令调用某个对象的方法来执行具体的操作。
总结模式
一个对象只需存储命令和执行命令,它不需要知道命令执行的是什么逻辑,它只关心命令的存储和调用,具体执行的是什么操作应该由命令对象自己去和目标对象沟通。这个模式可以方便的执行命令,今后有新需求,就可以创建新的命令,只要该命令符合命令的抽象,通过把新命令注入到字典中就能够得到执行。
示例代码
先敲出下面的代码,而不要去设计具体的类型,先考虑可能的调用代码,再设计具体的类型
//遥控器有插槽和按钮//插槽:可以插入一个命令,命令作为遥控器的属性被存取
//按钮:执行命令,用遥控器的ButtonClick模拟按钮的点击
//执行命令可以控制某个电器装置
RemoteControl remoteControl = new RemoteControl( ); //遥控器
//电灯提供on和off方法
Light light = new Light( );
//命令,持有对电灯的引用,所以可以调用电灯的on和off方法
LightOnCmd lightOnCmd = new LightOnCmd( light );
LightOffCmd lightOffCmd = new LightOffCmd( light );
remoteControl.OnCmd = lightOnCmd; //遥控器持有开灯的命令
remoteControl.OffCmd = lightOffCmd; //遥控器持有关灯的命令
remoteControl.ButtonOnClick( ); //触发遥控器上的On按钮
remoteControl.ButtonOffClick( );//触发遥控器上的Off按钮
有了以上的思考,现在开始具体的类型结构设计
//命令的抽象public interface ICommand
{
void Execute( );
}
//开灯命令的具象
public class LightOnCmd : ICommand
{
private Light Light;
public LightOnCmd( Light light ) { Light = light; }
public void Execute( ) { Light.On( ); }
}
//关灯命令的具象
public class LightOffCmd : ICommand
{
private Light Light;
public LightOffCmd( Light light ) { Light = light; }
public void Execute( ) { Light.Off( ); }
}
//灯对象提供开关方法,供命令调用
public class Light
{
public void On( ) { Console.WriteLine( "灯亮" ); }
public void Off( ) { Console.WriteLine( "灯灭" ); }
}
//遥控器
public class RemoteControl
{
public ICommand OnCmd; //通过属性注入命令
public ICommand OffCmd; //通过属性注入命令
public void ButtonOnClick( ) { OnCmd.Execute( ); }
public void ButtonOffClick( ) { OffCmd.Execute( ); }
}
改进版:一次注入多个命令
//命令的抽象public interface ICommand
{
void Execute( );
}
//开灯命令的具象
public class LightOnCmd : ICommand
{
private Light Light;
public LightOnCmd( Light light ) { Light = light; }
public void Execute( ) { Light.On( ); }
}
//关灯命令的具象
public class LightOffCmd : ICommand
{
private Light Light;
public LightOffCmd( Light light ) { Light = light; }
public void Execute( ) { Light.Off( ); }
}
//灯对象提供开关方法,供命令调用
public class Light
{
public void On( ) { Console.WriteLine( "灯亮" ); }
public void Off( ) { Console.WriteLine( "灯灭" ); }
}
//遥控器
public class RemoteControl
{
public Dictionary<string, ICommand> Cmds;
private ICommand Cmd;
//通过构造函数注入一组命令
public RemoteControl( Dictionary<string, ICommand> cmds )
{
Cmds = cmds;
}
public void ButtonOnClick( string cmdOnKey )
{
Cmd = Cmds[cmdOnKey];
if (Cmd != null)
{
Cmd.Execute( );
}
}
public void ButtonOffClick( string cmdOffKey )
{
Cmd = Cmds[cmdOffKey];
if (Cmd != null)
{
Cmd.Execute( );
}
}
}
public class Programe
{
static void Main( string[] args )
{
Light light = new Light( );
Dictionary<string, ICommand> cmds = new Dictionary<string, ICommand>
{
{ "LightOn", new LightOnCmd(light) },
{ "LightOff", new LightOffCmd(light) }
};
RemoteControl remoteControl = new RemoteControl( cmds );
remoteControl.ButtonOnClick( "LightOn" );
remoteControl.ButtonOffClick( "LightOff" );
}
}
命令宏:当按下一个On按钮,可以打开电灯、再打开恒温器和电视机,这一组宏指令可以通过定义一个宏命令类来完成,具体略。
C# - 设计模式目录