命令模式

有时候必须向某个对象提交请求,但是却并不知道关于被请求操作或请求的接收者的任何信息。

命令模式的关键是一个抽象的Command类或接口。这个Command抽象类(或接口)里面包含了一个执行命令的方法execute()。这个方法由具体Command去实现。

假设有一个遥控器,它有四个按钮,需要将其中的两个设计为灯(Light)的开、关,另外两个控制收音机(Video)的开、关。

在这个例子中遥控器物理上根本没有与等或者收音机接触(要不然也不叫“遥控器”了),以面向对象的思想去理解,遥控器作为控制器应该是一个类,所有控制的light和Video应该注册到这个控制其上面。然后是Light和Video,Light应该具有开或者关的表现效果(就是亮或者灭,可开、关是对应的,开-->亮,关-->灭),Video也类似。

接下来就是Command类组了,这个是命令模式的核心,它们都具有一个execute接口暴露给调用者,不同的具体Command如LightOnCommand应该具有一个所控制灯的引用(要不然不知道这个命令对应哪盏灯)。因此命令模式的代码如下:

首先是light和Video

//Light,这里直接写成了on和off。跟准确的应该是亮和灭

package Command;

/**
 * Created by sgzhang on 2015/8/14.
 */
public class Light {
    public void on(){
        System.out.println("Light is on!");
    }

    public void off(){
        System.out.println("Light is off");
    }
}
//Video

package Command;

/**
 * Created by sgzhang on 2015/8/14.
 */
public class Video {
    public void on(){
        System.out.println("Video is on ");
    }
    public void off(){
        System.out.println("Video is off");
    }

    public void turnUp(){
        System.out.println("Video turnUp!");
    }

    public void turnDown(){
        System.out.println("Video turnDown!");
    }
}
然后是它们对应的命令,先是一个超类Command(接口)

package Command;

/**
 * Created by sgzhang on 2015/8/14.
 */
public interface Command {
    void execute();
}
接着是具体的Command

package Command;

/**
 * Created by sgzhang on 2015/8/14.
 */
public class LightOnCommand implements Command {
    Light light;

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

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


package Command;

/**
 * Created by sgzhang on 2015/8/14.
 */
public class LightOffCommand implements Command {
    Light light;

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

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


//这个程序的Video的execute里面执行了两个动作
package Command;

/**
 * Created by sgzhang on 2015/8/14.
 */
public class VideoOnCommand implements Command {
    Video video;

    public VideoOnCommand(Video video) {
        this.video = video;
    }

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

package Command;

/**
 * Created by sgzhang on 2015/8/14.
 */
public class VideoOffCommand implements Command{
    Video video;

    public VideoOffCommand(Video video) {
        this.video = video;
    }

    @Override
    public void execute() {
        video.turnDown();
        video.off();
    }
}


然后是遥控器,buttonOn()和buttonOff()对应了遥控器在物理意义上的按钮。

package Command;

/**
 * Created by sgzhang on 2015/8/14.
 */
public class RemoteControl {
    Command[] onCommands;
    Command[] offCommands;

    public RemoteControl() {
        this.onCommands = new Command[2];
        this.offCommands=new Command[2];
    }

    public void setCommand(int slot,Command onCommand,Command offCommand){
        onCommands[slot-1]=onCommand;
        offCommands[slot-1]=offCommand;
    }
    public void buttonOn(int slot){
        onCommands[slot-1].execute();
    }

    public void buttonOff(int slot){
        offCommands[slot-1].execute();
    }
}

最后是测试代码:

package Command;

/**
 * Created by sgzhang on 2015/8/14.
 */
public class RemoteControlTest {
    public static void  main(String[] args){
        RemoteControl remoteControl=new RemoteControl();
        Light light=new Light();
        LightOnCommand lightOn=new LightOnCommand(light);
        LightOffCommand lightOff=new LightOffCommand(light);
        remoteControl.setCommand(1,lightOn,lightOff);

        Video video=new Video();
        VideoOnCommand videoOn=new VideoOnCommand(video);
        VideoOffCommand videoOff=new VideoOffCommand(video);
        remoteControl.setCommand(2,videoOn,videoOff);

        
        
        
        remoteControl.buttonOff(1);
        remoteControl.buttonOn(2);
    }
}



输出

Light is off
Video is on 
Video turnUp!


可以看到,经过对遥控器的一些配置之后, 最后两行实现了对Light和Video的控制。

命令模式适用:

1,抽象出执行的动作以参数化某对象;

2,在不同的时刻指定、排列、执行请求;

3,支持取消

4,支持日志。比如系统宕机后可根据日志中的操作记录,顺序执行命令,让系统恢复到备份的状态。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值