This is the 8th day of my participation in the August More Text Challenge. For details, see:August is more challenging

Design patterns

WangScaler: an author who works with his heart.

Statement: talent and learning shallow, if there is a mistake, kindly correct.

Command mode

What is command mode?

The command pattern encapsulates a request as an object, separating the responsibility for making the request from the responsibility for executing it. It is like a remote control, we only need to press the button of the remote control to issue commands to achieve our goals, and we do not need to know the execution details of the commands.

We’ve all played a radio (maybe not since 2000), but let’s say it has two buttons: play and rewind. Press the play button twice to stop, and press the rewind button twice to stop rewinding.

Let’s take the radio as an example to explain our command mode.

First, create radio.java, the receiver of the command, and implement the four functions of the command: play, stop, rewind, and stop rewind

package com.wangscaler.command;
​
/ * * *@author WangScaler
 * @date 2021/7/27 17:45
 */public class Radio {
    public void play(a) {
        System.out.println("Start playing.");
    }
​
    public void stop(a) {
        System.out.println("Stop playing.");
    }
​
    public void rewind(a) {
        System.out.println("Start rewinding.");
    }
​
    public void stopRewind(a) {
        System.out.println("Stop rewinding."); }}Copy the code

Define an abstract Command interface, command-java, with execute (the first key) and undo (the second key).

package com.wangscaler.command;
​
/ * * *@author WangScaler
 * @date2021/7/27 ready * /public interface Command {
    public void execute(a);
​
    public void undo(a);
}
Copy the code

Define a specific command, PlayCommand, which is executed by calling the receiver Radio.

package com.wangscaler.command;
​
/ * * *@author WangScaler
 * @date2021/7/27 slew both * /public class PlayCommand implements Command {
    private Radio redio;
​
    public void execute(a) {
        redio.play();
    }
​
    public void undo(a) { redio.stop(); }}Copy the code

RewindCommand. Java, which executes the command by calling the receiver Radio

package com.wangscaler.command;
​
/ * * *@author WangScaler
 * @date2021/7/27 covenant * /public class RewindCommand implements Command {
    private Radio redio;
​
    public void execute(a) {
        redio.rewind();
    }
​
    public void undo(a) { redio.stopRewind(); }}Copy the code

The requester role, the key Keypad, has a bunch of command objects that implement the command.

package com.wangscaler.command;
​
/ * * *@author WangScaler
 * @dateProspering 2021/7/27 * /public class Keypad {
    private Command playCommand;
    private Command rewindCommand;
​
    public void setPlayCommand(Command playCommand) {
        this.playCommand = playCommand;
    }
​
    public void setRewindCommand(Command rewindCommand) {
        this.rewindCommand = rewindCommand;
    }
​
    public void play(a) {
        playCommand.execute();
    }
​
    public void rewind(a) {
        rewindCommand.execute();
    }
​
    public void stop(a) {
        playCommand.undo();
    }
​
    public void stopRewind(a) { rewindCommand.undo(); }}Copy the code

main

package com.wangscaler.command;
​
/ * * *@author WangScaler
 * @date2021/7/27 before * /public class Main {
    public static void main(String[] args) {
        Radio redio = new Radio();
        Command playCommand = new PlayCommand(redio);
        Command rewindCommand = new RewindCommand(redio);
        Keypad keypad = newKeypad(); keypad.setPlayCommand(playCommand); keypad.setRewindCommand(rewindCommand); keypad.rewind(); keypad.stopRewind(); keypad.play(); keypad.stop(); }}Copy the code

In the end, we achieved four functions by pressing buttons. This is the command mode.

Here our key Keypad has a series of command objects, playCommand and rewindCommand, and our receiver Radio implements the play, stop, rewind, stopRewind functions. Our command object calls its function by combining the Radio, and for us, the requester just presses the button to do what we want, without caring how the Radio actually does it.

Here we decouple the keys from the radio kernel, so if you want to extend the new command, you can simply add commands to it.

Command mode in the source code

In the JDK Runnable

package java.lang;
​
@FunctionalInterface
public interface Runnable {
    public abstract void run(a);
}
Copy the code

Runnable is the equivalent of the abstract command role in our command pattern, which defines a command method run, which is equivalent to the execute method in our example.

We can customize the specific command role, again based on the example above

package com.wangscaler.command;
​
/ * * *@author WangScaler
 * @dateBetter 2021/7/28 * /public class TurnOnThread implements Runnable {
    private Radio radio;
​
    public TurnOnThread(Radio radio) {
        this.radio = radio;
    }
​
    public void run(a) { radio.play(); }}Copy the code

Our receiver role is Radio as in the previous example. This time,Thread can act as our requester and issue the command through start(). The source code for Thread is as follows

package java.lang;
​
public class Thread implements Runnable {
    
  public synchronized void start(a) {
        if(threadStatus ! =0)
            throw new IllegalThreadStateException();
        group.add(this);
        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if(! started) { group.threadStartFailed(this); }}catch (Throwable ignore) {
            }
        }
    }
​
    private native void start0(a);
}
Copy the code

conclusion

Roles in command mode

    1. Abstract command role: Defines the abstract command method execute().
    1. Specific command class role: the combination receiver, by invoking the receiver’s function to achieve the execution of the command.
    1. The receiver role: the true implementer of the command, the concrete implementation of the function.
    1. Requestor role: Has many command objects, through which commands are delivered.

Disadvantages:

A large number of specific command classes are required.

When to Use:

Like our universal remote control, how do we control the air conditioner, the TV, the fans? Our air conditioner, TV and fan can all provide command object API, and our universal remote control can realize the control of air conditioner, TV and fan through these command objects.

The resources

  • JAVA Design Patterns
  • Command Mode (detailed version)
  • Command mode