命令模式:把方法调用封装起来
抽象命令
//命令接口
public interface Command
{
//执行
void execute();
//撤销
void undo();
}
具体命令
//开灯命令
public class LightOnCommand : Command
{
Light light;
public LightOnCommand(Light light)
{
this.light = light;
}
public void execute()
{
light.on();
}
public void undo()
{
light.off();
}
}
//关灯命令
public class LightOffCommand : Command
{
Light light;
public LightOffCommand(Light light)
{
this.light = light;
}
public void execute()
{
light.off();
}
public void undo()
{
light.on();
}
}
public class RemoteControl
{
//创建命令容器
Command[] onCommands;
Command[] offCommands;
public RemoteControl()
{
//实例化命令容器,并全部绑定为空命令
onCommands = new Command[7];
offCommands = new Command[7];
Command noCommand = new NoCommand();
for (int i = 0; i < onCommands.Length; i++)
{
onCommands[i] = noCommand;
offCommands[i] = noCommand;
}
}
//绑定一对设备开关命令到指定编号
public void setCommand(int slot, Command onCommand, Command offCommand)
{
onCommands[slot] = onCommand;
offCommands[slot] = offCommand;
}
//指定编号打开开关
public void onButtonWasPushed(int slot)
{
onCommands[slot].execute();
}
//指定编号关闭开关
public void offButtonWasPushed(int slot)
{
offCommands[slot].execute();
}
//获取容器绑定命令信息
public String toString()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("\n------- Remote Control -------\n");
for (int i = 0; i < onCommands.Length; i++)
{
stringBuilder.Append(string.Format("[slot{0}] {1} {2}\n", i.ToString(), onCommands[i].GetType().Name, offCommands[i].GetType().Name));
}
return stringBuilder.ToString();
}
}
总结:
1.命令模式将发出请求的对象和执行请求的对象解耦。
2.在被解耦的两者之间是通过命令对象进行沟通的。命令对象封装了接收者和一个或一组动作。
3.调用者通过调用命令对象的execute()发出请求,这会使得接收者的动作被调用。
4.调用者可以接收命令当做参数,甚至在运行时动态地进行。
5.命令可以支持撤销,做法是实现一个undo()方法来回到execute()被执行前的状态。
6.宏命令是命令的一种简单的延伸,允许调用多个命令。宏方法也可以支持销。
7.实际操作时,很常见使用“聪明”命令对象,也就是直接实现了请求,而不是将工作委托给接收者。
8.命令也可以用来实现日志和事务系统。