Design pattern - command pattern (definition, case analysis, features, shortcomings)

preface

The content of this article mainly refers to the design mode (2nd Edition) edited by Liu Wei, and also combines some of my own thinking and understanding, hoping to help you.

This article explains the command mode, which enables the request sender and the request receiver to eliminate the coupling between each other and make the call relationship between objects more flexible.

text

1, Definition

Command pattern: encapsulate a request into an object, so that we can parameterize the customer with different requests; Queue requests or record request logs, and support revocable operations. Command mode is an object behavior mode. Its alias is action mode or transaction mode.

In software design, we often need to send requests to some objects, but we don't know who the receiver of the request is or what the requested operation is. We just need to specify the specific receiver of the request when the program is running. At this time, we can use the command mode to design so that the coupling between the sender and receiver of the request can be eliminated, Make the calling relationship between objects more flexible.

The essence of command mode is to encapsulate the command, separating the responsibility of issuing the command from the responsibility of executing the command. The command mode allows the requesting party and the receiving party to be independent, so that the requesting party does not have to know the interface of the receiving party, let alone how the request is received, whether, when and how the operation is executed.

Command mode makes the request itself an object that can be stored and passed like other objects. The key of the command mode is to introduce the abstract command interface, and the sender programs for the abstract command interface. Only the specific command that implements the abstract command interface can be associated with the receiver.

2, Scenario hypothesis

The TV is the receiver of the request, and the remote controller is the sender of the request. There are some buttons on the remote controller, and different buttons correspond to different operations of the TV. The abstract command role is played by a command interface. Three specific command classes implement the abstract command interface. These three specific command classes represent three operations: turning on the TV, turning off the TV and switching channels.

In fact, the design is to encapsulate the commands separately, use the commands with the remote control, and control the TV with the commands, so as to achieve the separation and correlation of these relationships.

3, Scenario analysis

Class diagram of the above scenario (specific analysis is below)

First, define a TV class

public class TV
{
	public void open(){
		System.out.println("Turn on the TV!");
	}
	public void close(){
		System.out.println("Turn off the TV!");
	}
	public void changeChannel(){
		System.out.println("Switch TV channels!");
	}
}

Command abstract class

//Real permission class RealPermission
public interface AbstractCommand{
	public void execute();
}

Three specific command classes

//Turn on TV command
public class TVOpenCommand implements AbstractCommand{
	private TV tv;
	public TVOpenCommand(){
		tv = new TV();	
	}
	public void execute(){
		tv.open();
	}
}

//Turn off TV command
public class TVCloseCommand implements AbstractCommand{
	private TV tv;
	public TVCloseCommand(){
		tv = new TV();	
	}
	public void execute(){
		tv.close();
	}
}

//TV channel switching command
public class TVChangeCommand implements AbstractCommand{
	private TV tv;
	public TVChangeCommand(){
		tv = new TV();	
	}
	public void execute(){
		tv.changeChannel();
	}
}

In the above command class, we can see that it has an attribute to store the manipulated object. When the external interface is called, it is to call the corresponding method of the stored object.

Remote control class

public class Controller
{
	private AbstractCommand openCommand,closeCommand,changeCommand;
	public Controller(AbstractCommand openCommand,
		AbstractCommand closeCommand,
		AbstractCommand changeCommand){
		
		this.openCommand = openCommand;
		this.closeCommand = closeCommand;
		this.changeCommand = changeCommand;
	}
	
	public void open(){
		openCommand.execute();
	}
	public void close(){
		closeCommand.execute();
	}
	public void changeChannel(){
		changeCommand.execute();
	}
}

In the controller, we no longer deal with TV directly. We just need to store all commands, initialize them, and then call the desired commands directly

Next is the client code:

public class Client
{
	public static void main(String args[])
	{
		AbstractCommand openCommand,closeCommand,changeCommand;
		
		openCommand = new TVOpenCommand();
		closeCommand = new TVCloseCommand();
		changeCommand = new TVChangeCommand();
		
		Controller control = new Controller(openCommand,closeCommand,changeCommand);

		control.open();
		control.change();
		control.close();
	}
}

4, Pattern analysis

Pattern class diagram:

  • Command: Abstract command class
  • ConcreteCommand: concrete command class
  • Invoker: Caller
  • Receiver: receiver
  • Client: customer class

In fact, we also know about the process. Instead of directly calling the command sender and receiver, we add an intermediate layer to encapsulate the command into a class. At this time, the command sender can have a series of command objects for storage and calling. In fact, the same should be true for the command class, You can store multiple objects that accept commands and make corresponding calls.

(1) Mode characteristics

  1. Reduce the coupling degree of the system.
  2. New commands can be easily added to the system.
  3. You can easily design a command queue and macro commands (combined commands) (described in the expansion)
  4. Undo and Redo of requests can be easily realized (described in the expansion)

(2) Mode disadvantages

  1. Using command mode may cause some systems to have too many specific command classes. Because a specific command class needs to be designed for each command, some systems may need a large number of specific command classes, which will affect the use of command mode.

5, Usage scenario

  • The system needs to decouple the request caller and the request receiver, so that the caller and the receiver do not interact directly.
  • The system needs to specify, queue and execute requests at different times.
  • The system needs to support Undo and redo operations of commands. (it will be described in the expansion)
  • The system needs to combine a set of operations, that is, support macro commands. (it will be described in the expansion)

6, Expansion and extension

  • Implementation of undo operation
    In the command mode, we can realize the operation of revocation and reply, and this implementation actually uses the command object of the first layer we added. In addition to executing the corresponding command, the command class can also use the class to store some important information, such as previous operations, which can be used during revocation.
    For example, the following simple Adder adder is used for data summation calculation. The interface class CalculatorForm can use the Adder or withdraw to the operation in the previous step.

    Here we can see that the command class on the right has an undo method, which is used to provide revocation. The specific implementation of AddCommand class is shown below:
public class AddCommand extends AbstractCommand
{
	private Adder adder = new Adder();
	private int value;

	public int execute(int value){
		this.value = value;
		return adder.add(value);
	}

	public int undo(){
		return adder.add(-value);
	}
}

As we know from the above, in the specific implementation command class, we set an int value for data storage. If you want to undo it, you can directly add(-value).
Accordingly, if the function needs to be revoked, we can also store it in the command class.

  • Macro command
    Macro command, also known as combined command, is the product of the combination of command mode and combined mode.
    Macro command is also a specific command, but it contains references to other command objects. When calling the execute() method of macro command, the execute() method of each member command it contains will be called recursively. The member object of a macro command can be a simple command or continue to be a macro command. Executing a macro command will execute multiple specific commands, so as to realize the batch processing of commands.

summary

This article mainly introduces the command mode of design mode and two corresponding extensions.

Keywords: Design Pattern

Added by spighita on Wed, 09 Feb 2022 06:42:06 +0200