命令模式

模式定义

将“请求”封装成对象,以便使用不同的请求队列或者日志来参数化其他对象。命令模式也支持可撤销的操作

模式类图

示例

遥控器上不同开关控制不同的电器的开关示例,强耦合设计思路遥控器控制类中判断不同开关然后调用不同的电器。这样设计不利于后期的扩展和维护,需要进行解除耦合的操作。当开关按下时其实遥控器不关心这个开关绑定的是什么电器,只是开关是开我就调用绑定好的电器的开的操作。所以封装所有电器的开,关,撤销等到不同命令中,遥控器上可以根据需要绑定不同电器的操作命令。当开关开或者关的时候,只要调用绑定好的电器的不同命令即可。

/**
 * 灯具厂商
 *
 * @author Colin
 * @create 2018-05-02
 **/
public class Light {

    private String name;

    public Light(String name){
        this.name=name;
    }

    public void on(){
        System.out.println(this.name+"开灯");
    }

    public void off(){
        System.out.println(this.name+"关灯");
    }
}



/**
 * 命令接口
 *
 * @author Colin
 * @create 2018-05-02
 **/
public interface Command {

    /**
     * 执行命令
     */
    public void execute();

    /**
     * 撤销
     */
    public void undo();

}


/**
 * 关灯命令
 *
 * @author Colin
 * @create 2018-05-02
 **/
public class LightOffCommand implements Command {

    private  Light light;

    public LightOffCommand(Light light){
        this.light=light;
    }
    @Override
    public void execute() {
        light.off();
    }

    @Override
    public void undo() {
        light.on();
    }
}

/**
 * 开灯命令
 *
 * @author Colin
 * @create 2018-05-02
 **/
public class LightOnCommand implements Command {
    private Light light;

    public LightOnCommand(Light light){
        this.light=light;
    }

    @Override
    public void execute() {
        light.on();
    }

    @Override
    public void undo() {
        light.off();
    }
}

/**
 * 空命令
 *
 * @author Colin
 * @create 2018-05-02
 **/
public class NoCommand implements Command {
    @Override
    public void execute() {

    }

    @Override
    public void undo() {

    }
}

遥控器,即调用者Invoker

/**
 * 遥控器实现类
 *
 * @author Colin
 * @create 2018-05-02
 **/
public class RemoteControl {

    private Command[] onCommands;
    private Command[]  offCommands;
    private Command undoCommand;

    public RemoteControl(){
        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 onButtonWasPushed(int slot){
        onCommands[slot].execute();
        undoCommand=onCommands[slot];
    }

    public void offButtonWasPushed(int slot){
        offCommands[slot].execute();
        undoCommand=offCommands[slot];
    }

    public void undoButtonWasPushed(){
        undoCommand.undo();
    }
}

客户端,client,动态绑定,解耦


/**
 * 遥控器测试类
 *
 * @author Colin
 * @create 2018-05-02
 **/
public class RemoteLoader {

    @Test
    public void testRemoteControl(){
        Light livingLight=new Light("卧室");
        Light kitchenLight=new Light("厨房");

        LightOnCommand  livingRoomLightOnCommand=new LightOnCommand(livingLight);
        LightOffCommand livingRoomLightOffCommand=new LightOffCommand(livingLight);


        LightOnCommand  kitchenLightOnCommand=new LightOnCommand(kitchenLight);
        LightOffCommand kitchenLightOffCommand=new LightOffCommand(kitchenLight);


        RemoteControl remoteControl=new RemoteControl();
        remoteControl.setCommand(0,livingRoomLightOnCommand,livingRoomLightOffCommand);
        remoteControl.setCommand(1,kitchenLightOnCommand,kitchenLightOffCommand);


        remoteControl.onButtonWasPushed(0);
        remoteControl.offButtonWasPushed(0);

        remoteControl.onButtonWasPushed(1);
        remoteControl.offButtonWasPushed(1);

        remoteControl.undoButtonWasPushed();

    }
}

总结

  • 命令模式将发出请求的对象和执行请求的对象解耦,即上面client(请求对象)和Light(执行请求对象)
  • 在被解耦的两者之间是通过命令对象进行沟通的,命令对象封装了接收者的一个或者一组动作,即上面的Commd对象,开灯命令和关灯命令
  • 调用者通过命令对象的统一的execute方法发出请求,使接受则的动作得以执行

猜你喜欢

转载自www.cnblogs.com/coliz/p/8987645.html
今日推荐