命令模式

命令模式(Command Pattern),将发出请求的对象和执行请求的对象解耦。在被解耦的两者之间是通过命令对象进行沟通。命令对象封装了接收者和一个或一组动作。

举个栗子:

需要设计一个遥控器,该遥控器具有3个可编程的插槽(每个都可以指定到一个不同的家电装置),第一个槽位对应电灯Light,第二个槽位风扇Fan,第三个槽位热水器Heater,每个插槽都有对应的开关按钮。这个遥控器还具备一个整体的撤销按钮(暂时支持一次撤销)。

分析:

有3个槽位,每个槽位都有开和关的情况,如果用一般的编程方式的话,我们要通过一堆的if语句去判断这3*2中情况。通过命令模式给出某个槽位对应的命令即可。

1、命令接口:

接口 Command.java 类:

/**
 *  命令接口
 */
public interface Command {
    public void execute();
}

2、设备相关类(与命令接口无关)

Light.java 类:

/**
 *  设备:电灯
 */
public class Light{

    public void on(){
        System.out.println("Light is on!");
    }

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

Fan.java 类:

/**
 * 设备:电风扇
 */
public class Fan {

    public void on(){
        System.out.println("Fan is on!");
    }

    public void off(){
        System.out.println("Fan is off!");
    }
}

Heater.java 类:

/**
 *  设备:热水器
 */
public class Heater {

    public void on(){
        System.out.println("Heater is on!");
    }

    public void off(){
        System.out.println("Heater is off!");
    }
}

3、设备命令(需要实现commad)

NoCommand.java 类:

/**
 *  命令:什么都不做命令
 */
public class NoCommand implements Command {
    @Override
    public void execute() {
        System.out.println("Do no thing!");
    }
}

LihgtCommanOn.java 类:

/**
 *  命令: 电灯开启命令
 */
public class LightCommandOn implements Command {

    private Light light;

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

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

LightCommandOff.java 类:

/**
 *  命令:电灯关闭命令
 */
public class LightCommandOff implements Command {
    private Light light;

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

FanCommandOn.java 类:

/**
 *  命令:电风扇开启命令
 */
public class FanCommandOn implements Command {

    private Fan fan;

    public FanCommandOn(Fan fan){
        this.fan = fan;
    }
    @Override
    public void execute() {
        fan.on();
    }
}

FanCommandOff.java 类:

/**
 *  命令:电风扇关闭命令
 */
public class FanCommandOff implements Command {
    private Fan fan;

    public FanCommandOff(Fan fan){
        this.fan = fan;
    }
    @Override
    public void execute() {
        fan.off();
    }
}

HeaterCommandOn.java 类:

/**
 *  命令:热水器开启命令
 */
public class HeaterCommandOn implements Command {

    private Heater heater;

    public HeaterCommandOn(Heater heater){
        this.heater = heater;
    }
    @Override
    public void execute() {
        heater.on();
    }
}

HeaterCommandOff.java 类:

/**
 *  命令:热水器关闭命令
 */
public class HeaterCommandOff implements Command {
    private Heater heater;

    public HeaterCommandOff(Heater heater){
        this.heater = heater;
    }
    @Override
    public void execute() {
        heater.off();
    }
}

分析:

这里有三组设备:电灯Light、电风扇Fan、热水器Heater,每个设备都有开和关的命令,因此需要编写6个设备相关的命令类,注意,每个设备命令类都要实现Command接口。

4、遥控器

RemoteController.java 类:

/**
 *  遥控器
 */
public class RemoteController {

    Command[] commandsOn = new Command[3];
    Command[] commandsOff = new Command[3];
    Command noCommand = new NoCommand();
    Command undoComman = new NoCommand();

    /**
     *  初始化
     */
    public RemoteController(){
        for(int i=0;i<3;i++){
            commandsOn[i] = noCommand; //刚开始的命令都为空操作
            commandsOff[i] = noCommand;
        }
    }

    /**
     * 将各个槽位分别设置对应的命令
     * @param slot
     * @param commandOn
     * @param commandOff
     */
    public void setCommand(int slot, Command commandOn, Command commandOff){
        commandsOn[slot] = commandOn;
        commandsOff[slot] = commandOff;
    }

    /**
     * 某个槽位开启操作
     * @param slot
     */
    public void buttonPushOn(int slot){
        commandsOn[slot].execute();
        undoComman = commandsOff[slot];
    }

    /**
     *  某个槽位关闭操作
     * @param slot
     */
    public void buttonPushOff(int slot){
        commandsOff[slot].execute();
        undoComman = commandsOn[slot];
    }

    /**
     * 按钮按下,执行撤销操作
     */
    public void buttonPushUndo(){
        undoComman.execute();
    }
}

5、实际调用的程序如下:

public static void main(String[] args) {
    Light light = new Light();
    LightCommandOn lightCommandOn = new LightCommandOn(light);
    LightCommandOff lightCommandOff = new LightCommandOff(light);

    Fan fan = new Fan();
    FanCommandOn fanCommandOn = new FanCommandOn(fan);
    FanCommandOff fanCommandOff = new FanCommandOff(fan);

    Heater heater = new Heater();
    HeaterCommandOn heaterCommandOn = new HeaterCommandOn(heater);
    HeaterCommandOff heaterCommandOff = new HeaterCommandOff(heater);

    RemoteController remoteController = new RemoteController();
    remoteController.setCommand(0, lightCommandOn, lightCommandOff);
    remoteController.setCommand(1, fanCommandOn, fanCommandOff);
    remoteController.setCommand(2,heaterCommandOn,heaterCommandOff);

    remoteController.buttonPushOn(1);
    remoteController.buttonPushUndo();
    remoteController.buttonPushOff(0);
    remoteController.buttonPushUndo();
}

输出结果:

Fan is on!

Fan is off!

Light is off!

Light is on!

分析:

遥控器中提供了将不同的设备开关命令对应槽位的设置,并提供了撤销上一步的操作。实际调用的程序可以参考上面提供的demo。通过命令作为中间者,实现命令发起请求和命令接收者的解耦。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值