Command design pattern

I. Introduction of models

1.1 definition

Encapsulate the request into an object, which can parameterize other objects with different requests (inject different request dependencies into other objects), and support the queuing execution, logging, revocation and other (additional control) functions of requests (commands).

1.2 advantages

  1. Reduce the coupling degree of the system by introducing middleware (abstract interface)
  2. It has good expansibility and is very convenient to add or delete commands. Using the command mode to add or delete commands will not affect other classes and meet the opening and closing principle
  3. Macro commands can be implemented. Command mode can be combined with combined mode to assemble multiple commands into a combined command, namely macro command
  4. It is convenient to realize Undo and Redo operations. Command mode can be combined with memo mode to realize command revocation and recovery
  5. Additional functions can be added to the existing commands. For example, logging, combined with decorator mode, will be more flexible

1.3 disadvantages

  1. A large number of specific command classes may be generated. Because each specific operation needs to design a specific command class, which will increase the complexity of the system
  2. The result of the command mode is actually the execution result of the receiver. However, in order to structure and decouple the request and implementation in the form of command, additional type structure (the interface between the requester and abstract command) is introduced, which increases the difficulty of understanding

2, Structure and Implementation

2.1 structure

  1. Abstract Command role: it declares the interface for executing commands and has the abstract method execute for executing commands
  2. ConcreteCommand: it is the concrete implementation class of the abstract command class. It has the receiver object and completes the operation to be executed by calling the receiver's function
  3. Implementer / Receiver role: it performs operations related to command functions and is the real implementer of specific command object business
  4. Caller / requester role (Invoker): it is the sender of the request. It usually has many command objects and executes the relevant request by accessing the command object. It does not directly access the receiver

2.2 realization

2.2.1 class diagram

2.2.2,LightCommand

package com.erlang.command;

/**
 * @description: Abstract command
 * @author: erlang
 * @since: 2022-02-16 23:38
 */
public interface LightCommand {

    /**
     * Command execution method
     */
    void execute();
}

2.2.3,LightOffCommand

package com.erlang.command;

/**
 * @description: close command
 * @author: erlang
 * @since: 2022-02-16 23:46
 */
public class LightOffCommand implements LightCommand {

    private Light light;

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

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

2.2.4,LightOnCommand

package com.erlang.command;

/**
 * @description: Open command
 * @author: erlang
 * @since: 2022-02-16 23:46
 */
public class LightOnCommand implements LightCommand {

    private Light light;

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

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

2.2.5,NoLightCommand

package com.erlang.command;

/**
 * @description: Empty command
 * @author: erlang
 * @since: 2022-02-16 23:52
 */
public class NoLightCommand implements LightCommand {
    @Override
    public void execute() {
        System.out.println("NoLightCommand Empty command");
    }
}

2.2.6,Light

package com.erlang.command;

/**
 * @description: Recipient role 
 * @author: erlang
 * @since: 2022-02-16 23:46
 */
public class Light {

    /**
     * name
     */
    private String name;

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

    /**
     * open
     */
    public void on() {
        System.out.printf("open%s\n", name);
    }

    /**
     * close
     */
    public void off() {
        System.out.printf("close%s\n", name);
    }
}

2.2.7,RemoteControl

package com.erlang.command;

import java.util.Arrays;

/**
 * @description: Remote control
 * @author: erlang
 * @since: 2022-02-16 23:38
 */
public class RemoteControl {
    LightCommand[] onCommands;
    LightCommand[] offCommands;

    public RemoteControl() {
        onCommands = new LightCommand[7];
        offCommands = new LightCommand[7];
        LightCommand lightCommand = new NoLightCommand();
        for (int i = 0; i < 7; i++)  {
            onCommands[i] = lightCommand;
            offCommands[i] = lightCommand;
        }
    }

    public void setCommand(int index, LightCommand on, LightCommand off) {
        onCommands[index] = on;
        offCommands[index] = off;
    }

    public void onButtonWasPush(int index) {
        onCommands[index].execute();
    }

    public void offButtonWasPush(int index) {
        offCommands[index].execute();
    }

}

2.2.8,RemoteLoader

package com.erlang.command;

/**
 * @description: Command mode client test
 * @author: erlang
 * @since: 2022-02-16 23:37
 */
public class RemoteLoader {

    public static void main(String[] args) {
        RemoteControl remoteControl = new RemoteControl();
        LightCommand tvOn = new LightOnCommand(new Light("television"));
        LightCommand tvOff = new LightOffCommand(new Light("television"));
        remoteControl.setCommand(0, tvOn, tvOff);

        LightCommand airOn = new LightOnCommand(new Light("air conditioner"));
        LightCommand airOff = new LightOffCommand(new Light("air conditioner"));
        remoteControl.setCommand(1, airOn, airOff);
        System.out.println("Operating TV:");
        remoteControl.onButtonWasPush(0);
        remoteControl.offButtonWasPush(0);
        System.out.println("-----------------------------\n Operating the air conditioner:");
        remoteControl.onButtonWasPush(1);
        remoteControl.offButtonWasPush(1);
        System.out.println("-----------------------------\n Empty operation:");
        remoteControl.onButtonWasPush(2);
        remoteControl.offButtonWasPush(2);
    }
}

2.2.9 implementation results

Operating TV:
Turn on the TV
 Turn off TV
-----------------------------
Operating the air conditioner:
Turn on the air conditioner
 Turn off the air conditioner
-----------------------------
Empty operation:
NoLightCommand Empty command
NoLightCommand Empty command

Keywords: Design Pattern

Added by ohjay on Wed, 16 Feb 2022 18:26:29 +0200