This is the 15th day of my participation in the August Text Challenge.More challenges in August

In Dr. Yan Hong’s book JAVA and Mode, the Command mode is described as follows: The Command mode belongs to the behavior mode of the object. Command mode is also called Action mode or Transaction mode. The command pattern encapsulates a request or operation into an object. The command mode allows the system to parameterize clients with different requests, queue requests or log requests, and provide command undo and recovery functions.

The command pattern works by unpacking a user’s request as a command object and then sending the command to a specific invocation handler. The command pattern separates the responsibility of issuing and executing commands and delegates them to different objects, thus achieving decoupling between the senders of commands and the executors of commands.

UML diagrams

Five roles involved in command mode:

  • Abstract Command: Defines the canonical behavior that declares all Command instruction classes.
  • ConcreteCommand: defines a ConcreteCommand role, typically containing a reference to a command receiver, executed by invoking the concrete executor in the execute method.
  • Receiver: This class is responsible for implementing or executing a request and acts as a concrete logical processing role.
  • Requestor role (Invoker) : This class is responsible for calling a command object to perform a specific request. The related method is called an action method.

UML diagrams are not fixed and can be adapted in practice. For example, Receiver can be defined as a generic Receiver to handle multiple commands directly or a combination of factory method patterns to handle multiple commands.

Case presentation

We all know that there are up, down, left and right operation commands in mini-games, so this time we use this scenario to simulate.

Create abstract commands and concrete commands

abstract class Command {
	protected Receiver receiver;
	public abstract void execute(a);
	public void setReceiver(Receiver receiver) {
		this.receiver = receiver; }}class UpCommand extends Command{
	
	@Override
	public void execute(a) {
		System.out.println("Command: Up"); receiver.doCommand(); }}class DownCommand extends Command{
	@Override
	public void execute(a) {
		System.out.println("Command: Down"); receiver.doCommand(); }}Copy the code

Define Receiver

abstract class Receiver {
	public abstract void doCommand(a);
}

class UpReceiver extends Receiver{

	@Override
	public void doCommand(a) {
		System.out.println("Performer: Up."); }}class DownReceiver extends Receiver{

	@Override
	public void doCommand(a) {
		System.out.println("Executor: Down"); }}Copy the code

Define the requester role Invoker

public class Invoker {
	private Command command;
	
	
	public Invoker(Command command) {
		super(a);this.command = command;
	}

	public void doCommand(a){ command.execute(); }}Copy the code

Defining the client

public class Client {

	/ * * *@param args
	 */
	public static void main(String[] args) {
		Command commandUp = new UpCommand();
		commandUp.setReceiver(new UpReceiver());
		Invoker invoker = newInvoker(commandUp); invoker.doCommand(); }}Copy the code

The above is a demonstration of the command pattern, in which multiple receivers of the corresponding type are implemented by inheritance, which can also be done in one receiver.

The advantages and disadvantages

advantages

  1. Inter-class decoupling: There is no dependency between the caller role and the receiver role. The caller can implement the function simply by calling the Execute method of the Command abstract class, without knowing which receiver is performing the function. In my understanding, Receiver can be specified directly in the Command, and does not need to be dynamically bound in the client. This might be easier, but scalability needs to be considered.
  2. Extensibility: Subclasses of Command can be easily extended, while Invoker, the caller, and the high-level module Client do not generate heavy code coupling.
  3. The command mode is better combined with other modes. The command mode can be combined with the responsibility chain mode to achieve command family parsing tasks. Combined with the template method pattern, the bloat problem of the Command subclass can be reduced.

The disadvantage of the Command pattern is that if you have N commands, the problem is that you have N subclasses of Command instead of just a few, and the class is very bloated, which requires the reader to be very careful about using it in the category.