Command mode (Command)----design mode

Command mode (Command)----design mode

The command mode, in simple terms, is to decouple the "requester of the command action" and the "executor of the command action", and require that the request can be undone.

Command mode can be seen everywhere in life:

The boss issues an order, not directly to the employees, but to the secretary. How to execute the order is handed over to the secretary to complete it; or a multi-purpose remote control with many switch buttons for household appliances on it. At this time You can control all electrical appliances through this one remote control, and the switches of specific electrical appliances are not directly related to you...

What is command mode?

Command Pattern, in software design, we often need to send requests to certain objects, but we don't know who the recipient of the request is or which operation is being requested. We only need to run the program When specifying a specific request receiver, you can use the command mode to design.

The command mode enables the request sender and the request receiver to eliminate the coupling between each other, make the calling relationship between objects more flexible, and achieve decoupling.

In the command mode, a request is encapsulated as an object, so that different parameters can be used to represent different requests (ie commands), and the command mode also supports undo operations.

There should be some friends who feel confused. In fact, I was also very confused at first. Let's see the implementation process of a specific multi-use remote control. It may be clear~

Several sections in command mode

  1. Command:

    Define the interface of the command and declare the method of execution.

  2. ConcreteCommand (in the following demo, the switching actions of lights and TVs are all like this):

    The command interface implements the object, which is a "virtual" implementation; usually holds the receiver, and invokes the receiver's function to complete the operation to be performed by the command.

  3. Receiver (LightRecever, TV Recever):

    Receiver, the object that actually executes the command. Any class can be a receiver, as long as it can implement the corresponding function that the command requires.

    Usually aggregated in ConcreteCommand .

  4. Invoker (RemoteController):

    The command object is required to execute the request, which usually holds the command object, and can hold many command objects. This is where the client actually triggers the command and asks the command to perform the corresponding action, which is equivalent to using the entry of the command object.

  5. Client:

    Create a specific command object and set the receiver of the command object. Note that this is not a client in our conventional sense, but is assembling the command object and receiver. Perhaps, it is better to call this Client an assembler, because the client that actually uses the command is triggered from the Invoker.

Class Diagram for Command Pattern

insert image description here

Multi-use remote control case realization

command interface

package com.design_patterns.command;

//创建命令接口
public interface Command {
    
    

    //执行动作(操作)
    public void execute();
    //撤销动作(操作)
    public void undo();

}

LightOnCommand light on execution class

package com.design_patterns.command;

public class LightOnCommand implements Command {
    
    

    private LightReceiver lightReceiver;

    //构造方法

    public LightOnCommand(LightReceiver lightReceiver) {
    
    
        this.lightReceiver = lightReceiver;
    }

    //聚合LightReceiver
    @Override
    public void execute() {
    
    
         //调用接收者的方法
        lightReceiver.on();
    }

    @Override
    public void undo() {
    
    
        //调用接收者的方法
        lightReceiver.off();
    }
}

LightOffCommand light off execution class

package com.design_patterns.command;

public class LightOffCommand implements Command {
    
    

    private LightReceiver lightReceiver;

    //构造方法
    public LightOffCommand(LightReceiver lightReceiver) {
    
    
        this.lightReceiver = lightReceiver;
    }

    //执行关闭的方法
    @Override
    public void execute() {
    
    
        this.lightReceiver.off();
    }


    //执行撤销命令
    @Override
    public void undo() {
    
    
        this.lightReceiver.on();
    }
}

TVOnCommand TV open execution class

package com.design_patterns.command;

public class TVOnCommand implements Command {
    
    

    //聚合tv接收者
    private TVReceiver tvReceiver;

    //通过构造方法传递进来实际的tv接收者
    public TVOnCommand(TVReceiver tvReceiver) {
    
    
        this.tvReceiver = tvReceiver;
    }

    @Override
    public void execute() {
    
    
        //使接收者执行动作命令
        this.tvReceiver.on();
    }

    @Override
    public void undo() {
    
    
        //撤回操作
        this.tvReceiver.off();
    }
}

NoCommand No command class, used to initialize operations

package com.design_patterns.command;


/**
 * 无任何命令,即空执行。
 * 用于初始化每个按钮,当调用空命令时,对象什么都不做
 * 其实,这样也是一种设计模式,可以省略对空命令的判断
 */
public class NoCommand implements Command {
    
    
    @Override
    public void execute() {
    
    

    }

    @Override
    public void undo() {
    
    

    }
}

TVOffCommand TV off execution class

package com.design_patterns.command;

public class TVOffCommand implements Command {
    
    

    private TVReceiver tvReceiver;

    public TVOffCommand(TVReceiver tvReceiver) {
    
    
        this.tvReceiver = tvReceiver;
    }

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

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

LightReceiver light receiver class

package com.design_patterns.command;

public class LightReceiver {
    
    

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

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

TVReceiver TV receiver class

package com.design_patterns.command;

public class TVReceiver {
    
    

    public void on(){
    
    
        System.out.println("电视TV打开了!");
    }

    public void off(){
    
    
        System.out.println("电视TV关闭了!");
    }
}

The invoker multi-purpose remote control class that the RemoteController requests

package com.design_patterns.command;

public class RemoteController {
    
    

    //开 按钮的命令数组
    Command[] onCommands;
    Command[] offCommands;


    //执行撤销的命令
    Command undoCommand;

    public RemoteController() {
    
    
        onCommands = new Command[5];
        offCommands = new Command[5];

        for (int i = 0; i < 5; i++){
    
    
            onCommands[i] = new NoCommand();
            offCommands[i] = new NoCommand();
        }
    }


    //为我们的按钮设置你所需要的命令
    public void setCommand(int no, Command onCommand, Command offCommand){
    
    
        onCommands[no] = onCommand;
        offCommands[no] = offCommand;
    }


    //按下开的按钮
    public void onButtonWasPushed(int no){
    
    
        // 找到你按下的按钮,并调用对应的方法
        onCommands[no].execute();
        //记录这次的操作,用于撤销
        undoCommand = onCommands[no];
    }


    //按下关的按钮
    public void offButtonWasPushed(int no){
    
    
        // 找到你按下的按钮,并调用对应的方法
        offCommands[no].execute();
        //记录这次的操作,用于撤销
        undoCommand = offCommands[no];
    }


    //按下撤销按钮
    public void undoButtonWasPush(){
    
    
        //撤销上次的动作
        undoCommand.undo();
    }

}

Client client

package com.design_patterns.command;

import javafx.scene.effect.Light;

public class Client {
    
    
    public static void main(String[] args) {
    
    
        //使用命令设计模式,完成通过遥控器,对电灯的操作

        /**
         * 创建电灯的对象(接收者)
         */
        LightReceiver lightReceiver = new LightReceiver();

        //创建电灯相关的开关命令
        LightOnCommand lightOnCommand = new LightOnCommand(lightReceiver);
        LightOffCommand lightOffCommand = new LightOffCommand(lightReceiver);


        //创建一个遥控器
        RemoteController remoteController = new RemoteController();

        //给我们的遥控器设置相关的命令,比如 no = 0 使电灯的开和关的操作
        remoteController.setCommand(0,lightOnCommand,lightOffCommand);


        System.out.println("----按下灯的开的按钮----");
        remoteController.onButtonWasPushed(0);
        System.out.println("----按下灯的关的按钮----");
        remoteController.offButtonWasPushed(0);

        System.out.println("----撤销的操作----");
        remoteController.undoButtonWasPush();


        /**
         * 创建电视TV的对象(接收者)
         */
        TVReceiver tvReceiver = new TVReceiver();

        //创建电视TV相关的开关命令
        TVOnCommand tvOnCommand = new TVOnCommand(tvReceiver);
        TVOffCommand tvOffCommand = new TVOffCommand(tvReceiver);

        //给我们的遥控器设置相关的命令,比如 no = 1 使用电视TV的开和关的操作
        remoteController.setCommand(1,tvOnCommand,tvOffCommand);


        System.out.println("----按下电视TV的开的按钮----");
        remoteController.onButtonWasPushed(1);
        System.out.println("----按下电视TV的关的按钮----");
        remoteController.offButtonWasPushed(1);

        System.out.println("----撤销的操作----");
        remoteController.undoButtonWasPush();

    }
}

operation result

----按下灯的开的按钮----
电灯打开了!
----按下灯的关的按钮----
电灯关闭了!
----撤销的操作----
电灯打开了!
----按下电视TV的开的按钮----
电视TV打开了!
----按下电视TV的关的按钮----
电视TV关闭了!
----撤销的操作----
电视TV打开了!

Summarize

The main function of the command mode is to realize the separation of the requesting end and the executing end . A request object is used to receive the request, and the executing end is called to perform the operation. The same command mode also realizes the undo operation of the action , which further improves the robustness of the program.

Well, this is the command mode. If you don't understand it, please leave a comment below~

Guess you like

Origin blog.csdn.net/weixin_43479947/article/details/108457716