Behavioral mode: command mode

1, Definition and characteristics of patterns
Command mode: encapsulate a request into an object, separating the responsibility of issuing the request from the responsibility of executing the request.
In this way, the two communicate through the command object, which is convenient to store, transfer, call, add and manage the command object.

advantage:
1. Reduce the coupling degree of the system.
Command mode can decouple the object that invokes the operation from the object that implements the operation.
2. Adding or deleting commands is very convenient.
Using the command mode, adding and deleting commands will not affect other classes. It meets the "opening and closing principle" and is flexible for expansion.
3. Macro commands can be implemented.
Command mode can be combined with combined mode to assemble multiple commands into a combined command, that is, macro command.
4. It is convenient to realize Undo and Redo operations.
The command mode can be combined with the memo mode introduced later to realize the revocation and recovery of commands.

Disadvantages:
A large number of specific command classes may be generated.
Because a specific command class needs to be designed for each specific operation, which will increase the complexity of the system.

2, Structure of patterns
Relevant operations in the system can be abstracted into commands to separate the caller from the implementer.

Main roles:
1. Abstract Command class (Command) role: it declares the interface for executing commands and has the abstract method execute() for executing commands.
2. Concrete Command role: 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: performs operations related to command functions and is the real implementer of specific command object business.
4. Caller / requester role: it is the sender of the request. It usually has many command objects and executes relevant requests by accessing the command object. It does not directly access the receiver.

Figure 1 structure diagram of command mode

3, Application scenarios of patterns
1. When the system needs to decouple the request caller from the request receiver, the command mode makes the caller and receiver not interact directly.
2. When the system needs to request commands randomly or add or delete commands frequently, the command mode is more convenient to realize these functions.
3. When the system needs to perform a set of operations, the command mode can define macro commands to realize this function.
4. When the system needs to support Undo and Redo operations of commands, the command object can be stored and implemented in memo mode.

4, Mode extension
In software development, sometimes the command mode is combined with the previous combination mode, which constitutes the macro command mode, also known as the combination command mode.
A macro command contains a set of commands, which act as both a specific command and a caller. When it is executed, all the commands it contains will be called recursively.

Its specific structure is shown in Figure 2.

Fig. 2 structure diagram of combined command mode

Of course, the command mode can also be combined with the memo mode, which becomes the revocable command mode.

5, Implementation of pattern

Figure 3 example code structure

Abstract command role:

package com.example.designpattern.command;

/**
 * @author Administrator
 * @date 2020/8/4
 * Abstract command role
 */
interface ICommand {
    public void execute();
}

Recipient role:

package com.example.designpattern.command;

/**
 * @author Administrator
 * @date 2020/8/4
 * Recipient role
 */
class TV {
    /**
     * Current channel
     */
    private int currentChannel;

    public int getCurrentChannel() {
        return currentChannel;
    }

    public void setCurrentChannel(int currentChannel) {
        this.currentChannel = currentChannel;
    }


    /**
     * Related methods of executing commands
     */
    public void turnOn() {
        System.out.println("turn on TV");
    }

    public void turnOff() {
        System.out.println("Turn off the TV");
    }

    public void changeChannel(int channel) {
        System.out.println("Switch channels:" + channel);
    }
}

Specific command role 1:

package com.example.designpattern.command;

/**
 * @author Administrator
 * @date 2020/8/4
 * Specific command roles
 * A reference containing the recipient role object is required
 */
class OnCommand implements ICommand {
    private TV tv;

    public OnCommand(TV tv) {
        this.tv = tv;
    }

    @Override
    public void execute() {
        tv.turnOn();
    }
}

Specific command role 2:

package com.example.designpattern.command;

/**
 * @author Administrator
 * @date 2020/8/4
 * Specific command roles
 * A reference containing the recipient role object is required
 */
class OffCommand implements ICommand {
    private TV tv;

    public OffCommand(TV tv) {
        this.tv = tv;
    }

    @Override
    public void execute() {
        tv.turnOff();
    }
}

Specific command role 3:

package com.example.designpattern.command;

/**
 * @author Administrator
 * @date 2020/8/4
 * Specific command roles
 * A reference containing the recipient role object is required
 */
class ChangeChannelCommand implements ICommand {
    private TV tv;
    private int channel;

    public ChangeChannelCommand(TV tv, int channel) {
        this.tv = tv;
        this.channel = channel;
    }

    @Override
    public void execute() {
        tv.changeChannel(channel);
    }
}

Sender role:

package com.example.designpattern.command;

/**
 * @author Administrator
 * @date 2020/8/4
 * Sender role
 * Hold the command object to be sent
 * <p>
 * Remote control of analog TV
 */
class Control {
    private OnCommand onCommand;
    private OffCommand offCommand;
    private ChangeChannelCommand channelCommand;

    public Control() {
    }

    public Control(OnCommand onCommand, OffCommand offCommand, ChangeChannelCommand channelCommand) {
        this.onCommand = onCommand;
        this.offCommand = offCommand;
        this.channelCommand = channelCommand;
    }

    public OnCommand getOnCommand() {
        return onCommand;
    }

    public void setOnCommand(OnCommand onCommand) {
        this.onCommand = onCommand;
    }

    public OffCommand getOffCommand() {
        return offCommand;
    }

    public void setOffCommand(OffCommand offCommand) {
        this.offCommand = offCommand;
    }

    public ChangeChannelCommand getChannelCommand() {
        return channelCommand;
    }

    public void setChannelCommand(ChangeChannelCommand channelCommand) {
        this.channelCommand = channelCommand;
    }


    /**
     * Related methods of sending commands
     */
    public void orderOn() {
        onCommand.execute();
    }

    public void orderOff() {
        offCommand.execute();
    }

    public void orderchange() {
        channelCommand.execute();
    }
}

Call:

package com.example.designpattern.command;

/**
 * @author Administrator
 * @date 2020/8/4
 */
class Client {
    public static void main(String[] args) {
        //recipient
        TV tv = new TV();

        //command
        OnCommand onCommand = new OnCommand(tv);
        OffCommand offCommand = new OffCommand(tv);
        ChangeChannelCommand channelCommand = new ChangeChannelCommand(tv, 3);

        //sender 
        Control control = new Control(onCommand, offCommand, channelCommand);

        //Sender sends request
        control.orderOn();
        control.orderchange();
        control.orderOff();
    }
}

Test results:

Figure 4 test results

6, PPT material











Tags: Design Pattern

Posted by huppsi on Tue, 24 May 2022 18:44:00 +0300