Command mode of java design pattern (13)

Life can only be on the road, dreams can only be on the front, there is no problem with the mind, and the road is honest, and the right attitude can make your life more calm and comfortable. Of course, the mentality is adjusted by yourself, as long as you are willing, you can give yourself a correct mentality, as long as you are willing, you can stick to it.

Design pattern learning, I will blog about 23 design patterns in the near future , so stay tuned~ —
2021/1/16

definition

In software systems, " behavior requestors " and " behavior implementers " usually present a kind of " tight coupling ". But in some situations, such as "recording, undo/redo, transaction" and other processing of behavior, this kind of tight coupling that cannot resist changes is inappropriate. In this case, how to decouple the "behavior requester" from the "behavior implementer"? Abstract a set of behaviors as objects to achieve loose coupling between the two. This is the Command Pattern

Baidu Encyclopedia

Command mode analysis

  • The essence of the command mode is to encapsulate the command and separate the responsibility of issuing the command from the responsibility of executing the command.
  • Each command is an operation: the requesting party sends a request to perform an operation; the receiving party receives the request and performs the operation.
  • The command mode allows the requesting party and the receiving party to be independent, so that the requesting party does not need to know the interface of the receiving party, let alone how the request was received, and whether the operation was executed, when, and how Executed.
  • The command mode makes the request itself an object, which can be stored and transmitted like other objects.
  • The key to the command mode is the introduction of an abstract command interface, and the sender is programmed for the abstract command interface. Only specific commands that implement the abstract command interface can be associated with the receiver.

Simple understanding: If you
want to go to war, the general will issue an order to the soldier to execute the order. The general will not directly deal with the soldier, and will'connect' the general and the soldier through the order.

Role analysis

  • ICommand is used to define the command interface
  • Soldiers refer to soldiers to implement the ICommand command interface
  • Admiral refers to the general integration of the ICommand command interface to send commands
  • CommandContent refers to the specific content of the command

UML类图(1.1):
Insert picture description here

Project requirements

For example, now there are:

  • computer
  • TV
  • Cell phone
  • air conditioning

Wait for home appliances, each home appliance corresponds to a remote control, for example, there are 4 kinds of home appliances, then there are 4 kinds of remote controls, which is very troublesome, the command mode can combine these 4 kinds of home appliances into a remote control. Use a remote control to control these 4 home appliances. Like this

效果图(2.1):

Send a command through the remote control, and the corresponding product realizes the corresponding function, such as clicking the TV on button to turn on the TV and other operations

Code

ICommand (command interface):

public interface ICommand {
    
    
    //开始
    public void start();

    //撤回
    public void withdraw();
}

CommandContent (command specific content):

public class CommandContent {
    
    
    String type;
    
    //传递的是家电 比如说电视 
    public CommandContent(String type) {
    
    
        this.type = type;
    }
    public void on(){
    
    
        Log.i("命令模式",type+"  打开了~ ");
    }
    public void off(){
    
    
        Log.i("命令模式",type+"  关闭了~ ");
    }
}

TvOffCommand, specific implementation interface (TV off):

public class TvOffCommand implements ICommand{
    
    

    CommandContent dispatchOrders;

    public TvOffCommand(CommandContent dispatchOrders) {
    
    
        this.dispatchOrders = dispatchOrders;
    }
    @Override
    public void start() {
    
    
  		  //如果点击关闭,执行关闭命令
        dispatchOrders.off();
    }
    @Override
    public void withdraw() {
    
    
  		  //点击撤销,执行打开命令 
        dispatchOrders.on();
    }
}

TvOnCommand, specific implementation interface (TV on):

public class TvOnCommand implements ICommand{
    
    
    CommandContent dispatchOrders;

    public TvOnCommand(CommandContent dispatchOrders) {
    
    
        this.dispatchOrders = dispatchOrders;
    }
    @Override
    public void start() {
    
    
 		//如果点击打开,执行打开命令
        dispatchOrders.on();
    }
    @Override
    public void withdraw() {
    
    
 		  //点击撤销,执行关闭命令
        dispatchOrders.off();
    }
}

NoCommand (empty command, used for the first initialization, because the first time is neither open nor closed):

public class NoCommand implements ICommand{
    
    
    @Override
    public void start() {
    
    
    }

    @Override
    public void withdraw() {
    
    
    }
}

CallCommand (command caller):

public class CallCommand {
    
    

   	//开命令
    ICommand[] tvOnCommand;

    //关命令
    ICommand[] tvOffCommand;

    //记录当前存放的命令 用来撤回
    ICommand currentCommand;

	//默认可存放5条命令
    int number = 5;

	//初始化命令
    public CallCommand() {
    
    
        tvOnCommand = new ICommand[number];
        tvOffCommand = new ICommand[number];

        for (int i = 0; i < number; i++) {
    
    
          //先默认为空的命令
            tvOnCommand[i] = new NoCommand();
            tvOffCommand[i] = new NoCommand();
        }
    }

    /**
     * @param index        当前存放的下标
     * @param OnCommand  开始下标
     * @param OffCommand 结束下标
     */
    public void setTvOnCommand(int index, ICommand OnCommand, ICommand OffCommand) {
    
    
        this.tvOnCommand[index] = OnCommand;
        this.tvOffCommand[index] = OffCommand;
    }

    /**
     * @param index 命令下标
     */
    public void getOnCommand(int index) {
    
    
        this.tvOnCommand[index].start();
        //记录当前命令
        currentCommand =  this.tvOnCommand[index];
    }

    /**
     * @param index 命令下标
     */
    public void getOffCommand(int index) {
    
    
        this.tvOffCommand[index].start();
        //记录当前命令
        currentCommand =  this.tvOffCommand[index];
    }

    /**
     * 撤回
     */
    public void getWithdraw() {
    
    
        currentCommand.withdraw();
    }
}

Test code (client):

		//创建打开电视机命令具体内容
        CommandContent commandContent1 = new CommandContent("电视机");

        //初始化电视机开关命令
        TvOnCommand tvOnCommand = new TvOnCommand(commandContent1);
        TvOffCommand tvOffCommand = new TvOffCommand(commandContent1);

        //创建遥控器
        CallCommand callCommand = new CallCommand();
        //给遥控器初始化电视机开关命令
        callCommand.setTvOnCommand(0,tvOnCommand,tvOffCommand);

        //调用遥控器打开命令
        callCommand.getOnCommand(0);

        //调用遥控器关闭命令
        callCommand.getOffCommand(0);

        //调用遥控器撤回命令
        callCommand.getWithdraw();

Log图(3.1):
Insert picture description here
Advantages:

  • Reduce the degree of coupling between objects.
  • New commands can be easily added to the system.
  • Observe the principle of opening and closing (open for extension, closed for modification), and can be extended well

Disadvantages:

  • If it is a simple function, it will cause a lot of code and a lot of classes, and it will cause reading difficulties if you don't understand the command mode.
  • A specific command class needs to be designed for each command, so some systems may require a large number of specific command classes, which will affect the use of the command mode.

How to expand

Suppose you now need to add a command to switch the phone:

PhoneOnCommand (phone open command):

public class PhoneOnCommand implements ICommand{
    
    

    CommandContent dispatchOrders;

    public PhoneOnCommand(CommandContent dispatchOrders) {
    
    
        this.dispatchOrders = dispatchOrders;
    }
    @Override
    public void start() {
    
    
        dispatchOrders.on();
    }

    @Override
    public void withdraw() {
    
    
        dispatchOrders.off();
    }
}

PhoneOffCommand (phone off command):

public class PhoneOffCommand implements ICommand{
    
    

    CommandContent dispatchOrders;

    public PhoneOffCommand(CommandContent dispatchOrders) {
    
    
        this.dispatchOrders = dispatchOrders;
    }

    @Override
    public void start() {
    
    
        dispatchOrders.off();
    }

    @Override
    public void withdraw() {
    
    
        dispatchOrders.on();
    }
}

Test code (client):

	   //创建命令具体类容
        CommandContent commandContent2 = new CommandContent("手机");
        //创建手机命令
        PhoneOnCommand phoneOnCommand = new PhoneOnCommand(commandContent2);
        PhoneOffCommand phoneOffCommand = new PhoneOffCommand(commandContent2);

        //设置给遥控器命令
        callCommand.setTvOnCommand(1,phoneOnCommand,phoneOffCommand);

        //遥控器打开手机
        callCommand.getOnCommand(1);
        //遥控器关闭手机
        callCommand.getOffCommand(1);
        //遥控器打开手机
        callCommand.getOnCommand(1);
        //遥控器撤销
        callCommand.getWithdraw();

Log图(3.2): It
Insert picture description here
can be seen that the original code has not been changed, but the'command' has been modified a bit, and the corresponding method can still be adjusted;

Complete code

Go to Design Mode Homepage/Design Principles

Originality is not easy, your likes are your greatest support for me~

Guess you like

Origin blog.csdn.net/weixin_44819566/article/details/112714972