1, Basic introduction
1. In software design, we often need to send a request 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 a specific request receiver when the program is running. At this time, we can use the command mode to design.
2. The command mode makes the request sender and the request receiver decouple from each other, and makes the calling relationship between objects more flexible and decoupled.
3. In the command mode, a request is encapsulated as an object to represent different requests with different parameters, and the command mode also supports undo operations.
2, Structure of command mode
1. Invoker: caller role
2. Command: command role
All the commands you need are here. They can be interfaces or abstract classes;
3. Receiver: receiver role
Know how to implement and execute a request related operation;
4,ConcreteCommand
Bind a receiver object with an action, call the receiver response operation, and implement execute
3, Advantages and disadvantages of command mode
1. Advantages
(1) Class decoupling
There is no dependency between the caller role and the receiver role. When the caller realizes the function, he only needs to call the execute method of the Command abstract class. He does not need to know which receiver is executing.
(2) Scalability
The subclass of Command can be easily extended, while the caller Invoker and the high-level module client do not produce serious code coupling.
(3) Better command mode combined with other modes
- Command mode can be combined with responsibility chain mode to realize command family analysis task;
- Combined with template method pattern, the expansion of command subclass can be reduced;
2. Disadvantages
Class explosion!
4, Application scenario of command mode
1. The sender and executor of a command have different life cycles. When a command is sent, it is not executed immediately. In other words, the original requester may no longer be there, and the command object itself is still active. At this time, the receiver of the command can be local or another address of the network. The command object can be serialized and passed to another machine.
2. Commands require various management logic, such as unified management of multiple commands.
3. Operations such as undo and retry need to be supported.
The command mode can store the state. When the client needs to undo the effect of the command, the undo() method is called to undo the effect of the command;
The command mode also provides the redo() method for the client to resend the command when needed.
4. Use command mode as an alternative to callBack in an object-oriented system. "callBack" is about first registering a function and then calling this function later.
5. If you update all the data in the system to the log, so that when the system crashes, you can read back all the data update commands according to the log, and call the execute() method again to execute these commands one by one, so as to recover the data update made by the system before the crash.
5, Code instance
1. Command role command
package designMode.advance.command; //Create command interface public interface Command { //Perform action (operation) public void execute(); //Undo action (action) public void undo(); }
LightOnCommand
package designMode.advance.command; public class LightOnCommand implements Command { //Aggregate LightReceiver LightReceiver light; //constructor public LightOnCommand(LightReceiver light) { super(); this.light = light; } @Override public void execute() { //Call recipient's method light.on(); } @Override public void undo() { //Call recipient's method light.off(); } }
LightOffCommand
package designMode.advance.command; public class LightOffCommand implements Command { // Aggregate LightReceiver LightReceiver light; // constructor public LightOffCommand(LightReceiver light) { super(); this.light = light; } @Override public void execute() { // Call recipient's method light.off(); } @Override public void undo() { // Call recipient's method light.on(); } }
TVOnCommand
package designMode.advance.command; public class TVOnCommand implements Command { // Aggregate TVReceiver TVReceiver tv; // constructor public TVOnCommand(TVReceiver tv) { super(); this.tv = tv; } @Override public void execute() { // Call recipient's method tv.on(); } @Override public void undo() { // Call recipient's method tv.off(); } }
TVOffCommand
package designMode.advance.command; public class TVOffCommand implements Command { // Aggregate TVReceiver TVReceiver tv; // constructor public TVOffCommand(TVReceiver tv) { super(); this.tv = tv; } @Override public void execute() { // Call recipient's method tv.off(); } @Override public void undo() { // Call recipient's method tv.on(); } }
NoCommand
package designMode.advance.command; /** * No command, i.e. empty execution: used to initialize each button. When the empty command is called, the object does nothing * In fact, this is a design mode, which can save air-to-air judgment * @author Administrator * */ public class NoCommand implements Command { @Override public void execute() { } @Override public void undo() { } }
2. Receive role Receiver
package designMode.advance.command; public class LightReceiver { public void on() { System.out.println(" The lights are on.. "); } public void off() { System.out.println(" The lights are off.. "); } }
package designMode.advance.command; public class TVReceiver { public void on() { System.out.println(" The TV is on.. "); } public void off() { System.out.println(" The TV is off.. "); } }
3,Controller
package designMode.advance.command; public class RemoteController { // On button command array Command[] onCommands; Command[] offCommands; // Execution of revoked orders Command undoCommand; // Constructor, complete button initialization 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(); } } // Give our buttons the commands you need public void setCommand(int no, Command onCommand, Command offCommand) { onCommands[no] = onCommand; offCommands[no] = offCommand; } // Press the on button public void onButtonWasPushed(int no) { // no 0 // Find the on button you pressed and call the corresponding method onCommands[no].execute(); // Record this operation for cancellation undoCommand = onCommands[no]; } // Press the on button public void offButtonWasPushed(int no) { // no 0 // Find the off button you pressed and call the corresponding method offCommands[no].execute(); // Record this operation for cancellation undoCommand = offCommands[no]; } // Press the undo button public void undoButtonWasPushed() { undoCommand.undo(); } }
4. Caller role Client
package designMode.advance.command; public class Client { public static void main(String[] args) { //Use the command design mode to complete the operation of the electric light through the remote control //Create the object (recipient) of the light LightReceiver lightReceiver = new LightReceiver(); //Create light related switch commands LightOnCommand lightOnCommand = new LightOnCommand(lightReceiver); LightOffCommand lightOffCommand = new LightOffCommand(lightReceiver); //Need a remote control RemoteController remoteController = new RemoteController(); //Set the command to our remote control, for example, no = 0 is the operation of turning on and off the light remoteController.setCommand(0, lightOnCommand, lightOffCommand); System.out.println("--------Press the on button of the light-----------"); remoteController.onButtonWasPushed(0); System.out.println("--------Press the light off button-----------"); remoteController.offButtonWasPushed(0); System.out.println("--------Press the undo button-----------"); remoteController.undoButtonWasPushed(); System.out.println("=========Using the remote control to operate the TV=========="); TVReceiver tvReceiver = new TVReceiver(); TVOffCommand tvOffCommand = new TVOffCommand(tvReceiver); TVOnCommand tvOnCommand = new TVOnCommand(tvReceiver); //Set the command for our remote control, for example, no = 1 is the operation of turning the TV on and off remoteController.setCommand(1, tvOnCommand, tvOffCommand); System.out.println("--------Press the on button of the TV-----------"); remoteController.onButtonWasPushed(1); System.out.println("--------Press the TV off button-----------"); remoteController.offButtonWasPushed(1); System.out.println("--------Press the undo button-----------"); remoteController.undoButtonWasPushed(); } }