命令模式

定义

将一个请求封装成一个对象,从而可以用不同的请求对客户参数化,对请求排队或记录请求日志,以及支持可撤销的操作

UML

public interface Command {
    /**
     * 执行命令具体的操作
     */
    void execute();
}

/**
 * 具体的命令实现对象
 */
class ConcreteCommand implements Command{
    /**
     * 接收者
     */
    private Receiver receiver = null;

    /**
     * 命令对象可以有自己的状态
     */
    private String state;

    public ConcreteCommand(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void execute() {
        receiver.action();
    }
}

class Receiver{
    public void action(){
        System.out.println("真正的操作");
    }
}

class Invoker{
    private Command command = null;

    public void setCommand(Command command) {
        this.command = command;
    }

    public void runCommand(){
        command.execute();
    }
}

class Client{
    /**
     * 负责创建命令对象,设定接收者
     */
    public void assemble(){
        Receiver receiver = new Receiver();
        Command command = new ConcreteCommand(receiver);
        Invoker invoker = new Invoker();
        invoker.setCommand(command);
        invoker.runCommand();
    }
}

在这里插入图片描述
Command和ConcreteCommand分别是命令的抽象和实现。
Receiver:接收命令的对象。
Invoker:要求命令对象执行请求。使用命令对象的接口。

特点

  1. 命令模式将动作的请求者和动作的执行者解耦。
  2. 如果命令类过多,可能会增加复杂度。
  3. 空命令也是一种命令。
  4. 命令可以放置到队列里,可以多线程的执行命令。
  5. 命令模式有利于实现请求的撤销和重做。

示例

例如要给一个遥控器上的按钮设置可编程命令,on表示打开,off表示关闭。
在这里插入图片描述
先加一个命令试试:

public interface Command {
    void execute();
}

class Light{
    public void on(){
        System.out.println("电灯打开");
    }
}

class LightOnCommand implements Command{
    Light light;

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

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

class SimpleRemoteControl{
    Command slot;
    public void setCommand(Command command){
        slot = command;
    }

    public void buttonWasPressed(){
        slot.execute();
    }
}

class RemoteControlTest{
    public static void main(String[] args) {
        SimpleRemoteControl remote = new SimpleRemoteControl();
        Light light = new Light();
        LightOnCommand lightOn = new LightOnCommand(light);
        remote.setCommand(lightOn);
        remote.buttonWasPressed();
    }
}

将7个插槽全部编入命令,注意NoCommand也是一种命令

public interface Command {
    void execute();
}

/**
 * NoCommand表示空的命令,什么也不做即可。
 */
class NoCommand implements Command{
    @Override
    public void execute() {
        System.out.println("do nothing");
    }
}

class Light{
    private String name;

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

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

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

class LightOnCommand implements Command {
    Light light;

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

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

class LightOffCommand implements Command {
    Light light;

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

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



class RemoteControl{
    Command[] onCommands,offCommands;
    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;
        }
    }

    public void setCommand(int slot,Command onCommand,Command offCommand){
        onCommands[slot] = onCommand;
        offCommands[slot] = offCommand;
    }

    public void onButtonWasPressed(int slot){
        onCommands[slot].execute();
    }

    public void onButtonWasPushed(int slot){
        offCommands[slot].execute();
    }

    public String toString(){
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("\n------Remote Control-------\n");
        for (int i = 0; i < onCommands.length; i++) {
            stringBuffer.append("[slot " + i + "]" + onCommands[i].getClass().getName() + " " +
                    offCommands[i].getClass().getName() + "\n");
        }
        return stringBuffer.toString();
    }
}

class RemoteLoader{
    public static void main(String[] args) {
        RemoteControl remoteControl = new RemoteControl();
        Light livingRoomLight = new Light("Living Rommt");
        Light kitchenLight = new Light("Kitchen");
        LightOnCommand livingRoomLightOn = new LightOnCommand(livingRoomLight);
        LightOffCommand livingRoomLightOff = new LightOffCommand(livingRoomLight);

        LightOnCommand kitchenLightOn = new LightOnCommand(kitchenLight);
        LightOffCommand kitchenLightOff = new LightOffCommand(kitchenLight);

        remoteControl.setCommand(0,livingRoomLightOn,livingRoomLightOff);
        remoteControl.setCommand(1,kitchenLightOn,kitchenLightOff);
        remoteControl.onButtonWasPressed(0);
        remoteControl.onButtonWasPushed(0);
        remoteControl.onButtonWasPressed(1);
        remoteControl.onButtonWasPushed(1);
    }
}

给遥控器加上撤销/返回上一步功能:

/**
 * 加上撤销功能
 */
public interface Command {
    void execute();

    void undo();
}

/**
 * NoCommand表示空的命令,什么也不做即可。
 */
class NoCommand implements Command {
    @Override
    public void execute() {
        System.out.println("do nothing");
    }

    @Override
    public void undo() {
        System.out.println("do nothing");
    }
}

class Light{
    private String name;

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

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

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

class LightOnCommand implements Command {
    Light light;

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

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

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

class LightOffCommand implements Command {
    Light light;

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

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

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


class RemoteControl{
    Command[] onCommands,offCommands;
    Command undoCommand; //记录撤销之前的命令
    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 onButtonWasPressed(int slot){
        onCommands[slot].execute();
        undoCommand = onCommands[slot];
    }

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

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

    public String toString(){
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("\n------Remote Control-------\n");
        for (int i = 0; i < onCommands.length; i++) {
            stringBuffer.append("[slot " + i + "]" + onCommands[i].getClass().getName() + " " +
                    offCommands[i].getClass().getName() + "\n");
        }
        return stringBuffer.toString();
    }
}

class RemoteLoader{
    public static void main(String[] args) {
        RemoteControl remoteControl = new RemoteControl();
        Light livingRoomLight = new Light("Living Rommt");
        Light kitchenLight = new Light("Kitchen");
        LightOnCommand livingRoomLightOn = new LightOnCommand(livingRoomLight);
        LightOffCommand livingRoomLightOff = new LightOffCommand(livingRoomLight);

        LightOnCommand kitchenLightOn = new LightOnCommand(kitchenLight);
        LightOffCommand kitchenLightOff = new LightOffCommand(kitchenLight);

        remoteControl.setCommand(0,livingRoomLightOn,livingRoomLightOff);
        remoteControl.setCommand(1,kitchenLightOn,kitchenLightOff);
        remoteControl.onButtonWasPressed(0);
        remoteControl.onButtonWasPushed(0);
        remoteControl.undoButtonWasPushed();
        remoteControl.onButtonWasPressed(1);
        remoteControl.onButtonWasPushed(1);
        remoteControl.undoButtonWasPushed();
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值