“This is the 29th day of my participation in the August Genwen Challenge.More challenges in August”

What is command mode?

The Command Pattern is the encapsulation of commands. Each Command is an operation. The requesting party sends a request to perform an operation, and the receiving party receives the request and performs the operation. The command pattern decouples the requester from the receiver, and the requester simply requests the execution of the command, regardless of how the command is received, acted upon, or executed. The command mode belongs to the behavior mode.

In software systems, the behavior requester and the behavior implementor are usually tightly coupled because of the simplicity of the implementation.

But tightly coupled relationships lack extensibility, and in some cases you can only modify the source code when you need to record, undo, or redo behavior. The command pattern decouples the request from the implementation by introducing an abstract command interface between the request and the implementation, and the middleware is abstract and can have different subclass implementations, so it is extensible. So, the essence of naming patterns is to decouple command patterns from processing.

2. Application scenarios of command mode

When a certain operation of the system has command semantics, and the command implementation is unstable (change), the request and implementation can be decoupled through the command pattern, and the code architecture of the requester can be stabilized by using the abstract command interface, and the specific command implementation details of the receiver can be encapsulated. The receiver and abstract command interface is weakly coupled (internal methods do not need to be consistent) and has good scalability.

The command mode is applicable to the following scenarios:

  1. Operations with “commands” in real semantics (command menus, shell commands…) .
  2. The request caller and the request receiver need to be decoupled so that the caller and receiver do not interact directly.
  3. Actions waiting to be performed, such as undo and Redo operations, need to be abstracted.
  4. Command macros (that is, command combination operations) need to be supported.

Roles involved in command mode

The command mode contains four roles:

  1. Receiver: This class is responsible for implementing or executing a request.
  2. Command: Defines all Command actions that need to be executed.
  3. ConcreteCommand: This class maintains a Receiver internally, calling the Receiver’s related methods in its execute() method.
  4. Requester role (Invoker) : Receives client commands and executes them.

Application of command mode in business scenarios

If we develop a player, the player has a playback function, have the function of dragging the progress bar, stop playback function, suspended function, our to operate the player is not directly call the method that player, but by a control bar to the player with instructions to the kernel, so what specific convey instructions, will be encapsulated as a a button. Each button then encapsulates a command. The control bar is used to decouple the instruction sent by user from the instruction received by player kernel.

Create the Player kernel Player class:

public class Player {

    public void play(a) {
        System.out.println("Normal Play");
    }

    public void speed(a) {
        System.out.println("Drag the progress bar");
    }

    public void stop(a) {
        System.out.println("Stop playing");
    }

    public void pause(a) {
        System.out.println("Pause play"); }}Copy the code

Create command interface IAction class:

public interface IAction {

    void execute(a);
}
Copy the code

Then create the instructions that the action player can receive, PlayAction class:

public class PlayAction implements IAction {

    private Player player;

    public PlayAction(Player player) {
        this.player = player;
    }

    @Override
    public void execute(a) { player.play(); }}Copy the code

PauseAction class:

public class PauseAction implements IAction {

    private Player player;

    public PauseAction(Player player) {
        this.player = player;
    }

    @Override
    public void execute(a) { player.pause(); }}Copy the code

Drag the progress bar instruction SpeedAction class:

public class SpeedAction implements IAction {

    private Player player;

    public SpeedAction(Player player) {
        this.player = player;
    }

    @Override
    public void execute(a) { player.speed(); }}Copy the code

StopAction class:

public class StopAction implements IAction {

    private Player player;

    public StopAction(Player player) {
        this.player = player;
    }

    @Override
    public void execute(a) { player.stop(); }}Copy the code

Finally, create the Controller class:

public class Controller {

    private List<IAction> actions = new ArrayList<>();

    public void addAction(IAction action) {
        actions.add(action);
    }

    public void execute(IAction action) {
        action.execute();
    }

    public void executes(a) {
        for(IAction action : actions) { action.execute(); } actions.clear(); }}Copy the code

From the above code, the control bar can execute a single command or multiple commands in batches. Let’s look at the client test code:

public class Test {

    public static void main(String[] args) {
        Player player = new Player();
        Controller controller = new Controller();
        controller.execute(new PlayAction(player));

        controller.addAction(new PauseAction(player));
        controller.addAction(new PlayAction(player));
        controller.addAction(new StopAction(player));
        controller.addAction(newSpeedAction(player)); controller.executes(); }}Copy the code

Since the control bar has been decoupled from the player kernel, if you want to extend commands in the future, you only need to add commands, without changing the structure of the control bar.

Five, command mode in the source code

The Runnable interface in the JDK is essentially an abstraction of commands, and any class that implements the Runnable interface is considered a thread.

@FunctionalInterface
public interface Runnable {
 
    public abstract void run(a);
}
Copy the code

In fact, by calling the thread’s start() method, we are entitled to grab CPU resources without having to write our own logic to grab CPU resources. Once the thread grabs CPU resources, it executes the run() method, using the Runnable interface to decouple user requests from CPU execution.

Advantages and disadvantages of command mode

Advantages:

  1. By introducing middleware (abstract interfaces), command requests are decoupled from implementation.
  2. Good scalability, can easily add new commands.
  3. Support combination command, support command queue.

Disadvantages:

  1. There may be too many specific command classes.
  2. The result of the command pattern is actually the result of the recipient’s execution, but in order to architecture in the form of a command, decouple the request from the implementation and introduce additional type structures (the requester and the abstract command interface), which add to the difficulty of understanding.

7. Friendship links

Design Patterns – Factory Patterns learning tour

Design Patterns – a learning tour of singleton patterns

Design Patterns – A learning journey of prototyping patterns

Design Patterns – Builder patterns learning tour

Design Patterns – Agent patterns learning tour

Design Patterns – A learning tour of facade patterns

Design Patterns – A learning tour of decorator patterns

Design Patterns – Enjoy yuan patterns learning journey

Design Patterns – A learning journey of composite patterns

Design Patterns – Adapter patterns learning journey

Design Patterns – Bridge patterns learning journey

Design Patterns – Delegation patterns learning journey

Design Patterns – a template method pattern learning journey

Design Patterns – A learning journey of Strategic patterns

Design Patterns – A learning journey of chain of Responsibility patterns

Design Patterns – An iterator pattern learning journey

Welcome to follow the wechat public account (MarkZoe) to learn from and communicate with each other.