首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件开发 >

【设计方式】之命令模式(Command)

2012-08-01 
【设计模式】之命令模式(Command)命令模式的定义为:把一个请求封装成一个对象,因此可以使用不同的请求来参数

【设计模式】之命令模式(Command)
命令模式的定义为:把一个请求封装成一个对象,因此可以使用不同的请求来参数化别的对象,将请求加入队列或者记录请求日志,并且支持撤销操作。
官方定义为:The Command Pattern encapsulates a request as an object, thereby letting you parameterize other objects with different request, queue or log requests, and support undoable operations.


Command中比较重要的几个参与者:
Command
- declares an interface for executing an operation.
ConcreteCommand 
- defines a binding between a Receiver object and an action
- implements Execute by invoking the corresponding operation(s) on Receiver.
Client
- Create a ConcreteCommand ojbect and sets its receiver.
Invoker
- asks the command to carry out the request.
Receiver
- konws how to perform the oprations associated with carrying out a request, Any class may serve as a Receiver.




Command模式将命令的发送者与接受者分离,Command对象即为两者间的桥梁。
首先必须定义一个命令的接口(Command),接口中定义命令所支持的操作,然后定义具体的命令类(ConcreteCommand),并指定命令的接收着(Receiver),有时候接收者与命令可以合二为一。
利用多态机制,调用者(Invoker)只需要定义命令的接口(Command)对象便可,命令的细节对调用着是透明的。


还有一个比较重要的特点就是undoable,
undo的过程就是Execute的逆过程,比较负责的撤销动作则用到了Memento模式。


命令对象不一定只是一个单一的命令,也可以是很多命令的集合,这样命令就可以不用定义Invoker。


《Header First Design Patterns》中的示例代码如下:

public interface Command {    public void execute();    public void undo();}public class CeilingFanCommand implements Command {    protected CeilingFan ceilingFan;    protected int prevSpeed;    public CeilingFanCommand(CeilingFan ceilingFan) {        this.ceilingFan = ceilingFan;    }    public void execute() {        prevSpeed = ceilingFan.getSpeed();    }    public void undo() {        if (prevSpeed == CeilingFan.HIGH) {            ceilingFan.high();        } else if (prevSpeed == CeilingFan.MEDIUM) {            ceilingFan.medium();        } else if (prevSpeed == CeilingFan.LOW) {            ceilingFan.low();        } else if (prevSpeed == CeilingFan.OFF) {            ceilingFan.off();        }    }}public class CeilingFanHighCommand extends CeilingFanCommand {    public CeilingFanHighCommand(CeilingFan ceilingFan) {        super(ceilingFan);    }    @Override    public void execute() {        super.execute();        ceilingFan.high();    }}public class CeilingFanMediumCommand extends CeilingFanCommand {    public CeilingFanMediumCommand(CeilingFan ceilingFan) {        super(ceilingFan);    }    @Override    public void execute() {        super.execute();        ceilingFan.medium();    }}public class CeilingFanOffCommand extends CeilingFanCommand {    public CeilingFanOffCommand(CeilingFan ceilingFan) {        super(ceilingFan);    }    @Override    public void execute() {        super.execute();        ceilingFan.low();    }}public class NoCommand implements Command {    public NoCommand() { }        @Override    public void execute() { }    @Override    public void undo() { }}public class CeilingFan {    public static final int HIGH = 3;    public static final int MEDIUM = 2;    public static final int LOW = 1;    public static final int OFF = 0;    String location;    int speed;    public CeilingFan(String location) {        this.location = location;        speed = OFF;    }    public void high() {        speed = HIGH;    }    public void medium() {        speed = MEDIUM;    }    public void low() {        speed = LOW;    }    public void off() {        speed = OFF;    }    public int getSpeed() {        return speed;    }}public class RemoteControlWithUndo {    Command[] onCommands;    Command[] offCommands;    Command undoCommand;    public RemoteControlWithUndo() {        onCommands = new Command[7];        offCommands = new Command[7];        Command noCommand = new NoCommand();        for (int i = 0; i < 7; i++) {            onCommands[i] = noCommand;            offCommands[i] = noCommand;        }        undoCommand = noCommand;    }    public void setCommand(int slot, Command onCommand, Command offCommand) {        onCommands[slot] = onCommand;        offCommands[slot] = offCommand;    }    public void onButtonWasPressed(int slot) {        onCommands[slot].execute();        undoCommand = onCommands[slot];    }    public void offButtonWasPressed(int slot) {        offCommands[slot].execute();        undoCommand = offCommands[slot];    }    public void undoButtonWasPressed() {        undoCommand.undo();    }    public String toString() {        StringBuffer sb = new StringBuffer();        sb.append("\n------ Remote Control ------\n");        for (int i = 0; i < onCommands.length; i++) {            sb.append("[slot " + i + "] " + onCommands[i].getClass().getName() + "  " + offCommands[i].getClass().getName() + "\n");        }        return sb.toString();    }}public class RemoteLoader {    public static void main(String[] args) {        RemoteControlWithUndo remoteControl = new RemoteControlWithUndo();        CeilingFan ceilingFan = new CeilingFan("Living Room");        CeilingFanMediumCommand ceilingFanMedium =             new CeilingFanMediumCommand(ceilingFan);        CeilingFanHighCommand ceilingFanHigh =             new CeilingFanHighCommand(ceilingFan);        CeilingFanOffCommand ceilingFanOff =             new CeilingFanOffCommand(ceilingFan);        remoteControl.setCommand(0, ceilingFanMedium, ceilingFanOff);        remoteControl.setCommand(1, ceilingFanHigh, ceilingFanOff);        remoteControl.onButtonWasPressed(0);        remoteControl.offButtonWasPressed(0);        System.out.println(remoteControl);        remoteControl.undoButtonWasPressed();        remoteControl.onButtonWasPressed(1);        System.out.println(remoteControl);        remoteControl.undoButtonWasPressed();    }}


热点排行