Design pattern command pattern (behavioral)

Keywords: less

Article directory

I. Pattern Definition

Command pattern: encapsulating a request as an object separates the responsibility of issuing a request from the responsibility of executing a request. The two communicate with each other through the command object, which facilitates the storage, transfer, invocation, addition and management of the command object. Command mode, aliased as Action mode or Transaction mode, belongs to object behavior mode.

II. Model roles

Command mode includes the following roles:

  • Client: Customer class, responsible for calling
  • Command: An Abstract command class that declares the interface for executing commands and has an abstract method execute().
  • ConcreteCommand: The concrete command class is the concrete implementation class of the abstract command class. It has the recipient object and completes the operation of the command by calling the recipient's function.
  • Invoker: The caller, the sender of the request, usually has many command objects and executes the related requests by accessing the command objects. It does not directly access the recipient.
  • Receiver: Receiver is the real implementer of the specific command object business.

3. Model Analysis

The essence of command mode is to encapsulate commands, separating the responsibility of issuing and executing commands.

The actual executor of the command mode is the Receiver. The caller and the receiver communicate through the command object.

Command mode allows the requesting party and the receiving party to separate, so that the requesting party does not need to know the interface of the receiving party, much less how the request is received, whether the operation is executed, when it is executed, and how it is executed.

Typical command mode code

The Abstract command class:

public abstract class Command
{
	public abstract void execute();
} 

Specific command class:

public class ConcreteCommand extends Command
{
	private Receiver receiver;
	public void execute()
	{
		receiver.action();
	}
} 

Caller Invoker class:

public class Invoker
{
	private Command command;
	
	public Invoker(Command command)
	{
		this.command=command;
	}
	
	public void setCommand(Command command)
	{
		this.command=command;
	}
	
	//Business methods, which call methods of command classes
	public void call()
	{
		command.execute();
	}
} 

Receiver class:

public class Receiver
{
	public void action()
	{
		//Specific operation
	}
} 

Typical examples

Examples come from Design Patterns A Book

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. 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. The three specific command classes represent three operations: turning on the TV, turning off the TV and switching channels. Obviously, the TV remote controller is a typical example of command mode application.

The Abstract command class:

public interface AbstractCommand
{
	public void execute();
}

Specific command classes:

Changing platform

public class TVChangeCommand implements AbstractCommand
{
	private Television tv;
	public TVChangeCommand()
	{
		tv = new Television();
	}
	public void execute()
	{
		tv.changeChannel();
	}
}

Shutdown

public class TVCloseCommand implements AbstractCommand
{
	private Television tv;
	public TVCloseCommand()
	{
		tv = new Television();
	}
	public void execute()
	{
		tv.close();
	}
}

Boot up

public class TVOpenCommand implements AbstractCommand
{
	private Television tv;
	public TVOpenCommand()
	{
		tv = new Television();
	}
	public void execute()
	{
		tv.open();
	}
}

Receiver class:

public class Television
{
	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!");
	}
}

Invoker 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 change()
	{
		changeCommand.execute();
	}	

	public void close()
	{
		 closeCommand.execute();	
	}
}

V. Applicable Scenarios

  • The system needs to support command Undo and Redo operations.
  • The system needs to combine a set of operations to support macro commands.
  • The system needs to specify, queue and execute requests at different times.
  • The system needs to decouple the caller and the receiver of the request so that the caller and the receiver do not interact directly.

Posted by jrmckee on Thu, 16 May 2019 16:46:40 -0700