命令模式

来源:互联网 发布:淘宝网孕妇秋装套装 编辑:程序博客网 时间:2024/06/05 11:52

命令模式(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。通过命令作为中间者,实现命令发起请求和命令接收者的解耦。