GOF对命令模式的定义是:“将一个请求封装为一个对象,从而使用户可用不同的请求对客户进行参数化:对请求排队或记录请求日志,并支持可撤销的操作。”
下面以赤壁之战为例,上代码
package Command;
public class Soldiers {
public void Combinate()
{
System.out.println("士兵们集合起来了!");
}
public void Fight()
{
System.out.println("士兵们冲锋陷阵");
}
//铁索连舟
public void CableBoat()
{
System.out.println("士兵们把军船用铁栓栓在了一起");
}
}
package Command;
public abstract class Command {
protected Soldiers soldiers;
public Command(Soldiers soldiers)
{
this.soldiers = soldiers;
}
public abstract void ExcuteCommand();
}
package Command;
public class FightCommand extends Command{
public FightCommand(Soldiers soldiers) {
super(soldiers);
// TODO Auto-generated constructor stub
}
@Override
public void ExcuteCommand() {
// TODO Auto-generated method stub
soldiers.Fight();
}
}
package Command;
public class CombinateCommand extends Command{
public CombinateCommand(Soldiers soldiers) {
super(soldiers);
// TODO Auto-generated constructor stub
}
@Override
public void ExcuteCommand() {
// TODO Auto-generated method stub
soldiers.Combinate();
}
}
package Command;
public class CableBoatCommand extends Command{
public CableBoatCommand(Soldiers soldiers) {
super(soldiers);
// TODO Auto-generated constructor stub
}
@Override
public void ExcuteCommand() {
// TODO Auto-generated method stub
soldiers.CableBoat();
}
}
package Command;
import java.util.ArrayList;
import java.util.List;
//传令官类
public class Herald {
private List<Command> commands = new ArrayList<Command>();
public void SetCommand(Command c)
{
commands.add(c);
}
public void Notify()
{
for(int i = 0;i<commands.size();i++)
{
(commands.get(i)).ExcuteCommand();
}
}
public void CancelCommand(Command c)
{
commands.remove(c);
}
}
package Command;
public class client {
public static void main(String[] args) {
// TODO Auto-generated method stub
Soldiers soldiers = new Soldiers();
Command combinateCommand = new CombinateCommand(soldiers);
Command fightCommand = new FightCommand(soldiers);
Command cableBoatCommand = new CableBoatCommand(soldiers);
Herald herald = new Herald();
herald.SetCommand(combinateCommand);
herald.SetCommand(fightCommand);
herald.SetCommand(fightCommand);
herald.SetCommand(cableBoatCommand);
herald.Notify();
System.out.println("战斗失败了,曹操买来了后悔药");
herald.CancelCommand(cableBoatCommand);
herald.Notify();
}
}
命令模式可以很容易地设计一个命令的队列。
命令模式适用于以下几种情况:
- 需要抽象出待执行动作以便参数化某个对象时
- 当需要在不同的时刻执行排列以及执行请求时
- 当系统需要支持取消操作时
- 当系统需要记录,修改日志时