Writing in the front

  • Take notes on learning design patterns
  • Improve flexibility in the use of design patterns

Learning to address

https://www.bilibili.com/vide…

https://www.bilibili.com/vide…

Refer to the article

http://c.biancheng.net/view/1…

Project source https://gitee.com/zhuang-kang/DesignPattern

18. Command mode

18.1 Definition and characteristics of command patterns

The Command pattern is defined as encapsulating a request as an object, separating the responsibility for making the request from the responsibility for executing it. In this way, they communicate with each other through the command object, which is convenient to store, transfer, call, increase and manage the command object.

The main advantages of the command mode are as follows.

  1. The coupling degree of the system is reduced by introducing middleware (abstract interface).
  2. Good scalability, adding or removing commands is very convenient. Adding and removing commands in command mode does not affect other classes and satisfies the “Open Closed Principle”.
  3. You can implement macro commands. Command mode can be combined with composite mode to assemble multiple commands into a single composite command, a macro command.
  4. Easy to implement Undo and Redo operations. Command mode can be combined with Memo mode, which is described later, to undo and restore commands.
  5. You can add additional functionality to existing commands. For example, logging is more flexible when combined with the decorator pattern.

Its disadvantages are:

  1. A large number of specific command classes can be generated. Because each specific operation needs to design a specific command class, this will increase the complexity of the system.
  2. The result of the command pattern is actually the result of the execution of the receiver, but the introduction of an additional type structure (the introduction of requester and abstract command interfaces) in order to construct and decouple the request from the implementation in the form of commands adds to the difficulty of understanding. But this is also a common design pattern problem, where abstraction inevitably increases the number of classes, and code pulling is definitely harder to understand than code aggregation.

18.2 Structure and implementation of command pattern

18.2.1 Structure of Command Pattern

  1. The abstract Command class (Command) role: Declares the interface to execute a Command and owns the abstract method execute().
  2. Concrete Command Role: A Concrete implementation of an abstract Command class. It holds the receiver object and calls the functions of the receiver to perform the action the Command is intended to perform.
  3. The implementer/Receiver role: Performs operations related to command functions and is the true implementer of a specific command object business.
  4. Caller/requester (Invoker) role: is the sender of the request, which usually has a number of command objects and executes the request by accessing the command object. It does not access the receiver directly.

18.2.2 Code implementation

Relationship between the class diagram

Command

package com.zhuang.command; /** * @ClassName Command * @Description * @Date 2021/3/27 10:25 * @Created by Dell */ public interface Command { void execute(); // Just define a unified method of execution}

OrderCommand

package com.zhuang.command; /** * @ClassName OrderCommand * @Description * @Date 2021/3/27 10:25 * @Created by Dell */ public class OrderCommand implements Command{private SeniorChef Receiver; private Order order; public OrderCommand(SeniorChef receiver, Order order) { this.receiver = receiver; this.order = order; } @Override public void execute() {System.out.println(Order.getDiningTable ()+" Order.getDiningTable: "); for (String key : order.getFoodDic().keySet()) { receiver.makefood(order.getFoodDic().get(key),key); } try { Thread.sleep(1000); } catch (interruptedException e) {e.printStackTrace(); } System.out.println(Order.getDiningTable ()+" The table is ready "); }}

Order

package com.zhuang.command; import java.util.HashMap; import java.util.Map; /** * @ClassName Order * @Description Order * @Date 2021/3/27 10:34 * @Created by Dell */ public class Order {// Table number private int diningTable; Private Map<String, Integer BB0 FoodDIC = new HashMap<String, Integer>(); public int getDiningTable() { return diningTable; } public void setDiningTable(int diningTable) { this.diningTable = diningTable; } public Map<String, Integer> getFoodDic() { return foodDic; } public void setFoodDic(String name, int num) { foodDic.put(name, num); }}

SeniorChef

package com.zhuang.command; /** * @ClassName SeniorChef * @Description * @Date 2021/3/27 10:27 * @Created by Dell */ public class SeniorChef {Date 2021/3/27 10:27 * @Created by Dell */ Public void makefood(int num, String foodName) {System.out.println(num + "portion" + foodName); }}

Waitor

package com.zhuang.command; import java.util.ArrayList; /** * @ClassName Waitor * @Description * @Date 2021/3/27 10:30 * @Created by Dell */ public class Waitor { Private ArrayList<Command> commands; private ArrayList<Command> commands; public Waitor() { commands = new ArrayList<Command>(); } public void setCommands(Command cmd) { commands.add(cmd); } public void orderUp() {System.out.println(); public void orderUp() {System.out.println(); public void orderUp() {System.out.println(); ); for (int i = 0; i < commands.size(); i++) { Command cmd = commands.get(i); if (cmd ! = null) { cmd.execute(); }}}}

Client

package com.zhuang.command; /** * @ClassName Client * @Description * @Date 2021/3/27 10:44 * @Created by Dell */ public class Client { Public static void main(String[] args) {// create Order Order Order1 = new Order(); order1.setDiningTable(1); Order1.getFooddic (). Put (" scrambled eggs with tomatoes ", 1); Order1.getFooddic (). Put (" can Coke ", 2); Order order2 = new Order(); order2.setDiningTable(2); Order2.getFooddic (). Put (" Sour ", 1); Order2.getFooddic (). Put (" Wang Laoji ", 1); order2.getFooddic (). // Create the receiver SeniorChef Receiver = new SeniorChef(); // Encapsulate the order and receiver as a command object OrderCommand cmd1 = new OrderCommand(Receiver, Order1); OrderCommand cmd2 = new OrderCommand(receiver, order2); Waitor waitor invoke = new waitor (); invoke.setCommands(cmd1); invoke.setCommands(cmd2); // Send the order to the counter and call the chef invoke.orderup (); }}

18.3 Command mode application scenarios

  • The system needs to decouple the caller of the request from the receiver of the request so that the caller and receiver do not interact directly.
  • The system needs to specify the request, queue the request, and execute the request at different times.
  • The system needs to support Undo and Redo operations for commands.

18.4 JDK source code parsing

Runable is a typical command pattern in which Runnable acts as the command, Thread acts as the caller, and the Start method acts as the execution method

Public interface Runnable {public abstract void run(); } public class Thread implements Runnable {private Runnable Target; public synchronized void start() { if (threadStatus ! = 0) throw new IllegalThreadStateException(); group.add(this); boolean started = false; try { start0(); started = true; } finally { try { if (! started) { group.threadStartFailed(this); } } catch (Throwable ignore) { } } } private native void start0(); }

A native method start0() is called, which calls the system method and starts a thread. The receiver is open to the programmer to define the receiver himself.

/** * JDK Runnable command mode * TurnOffThread: */ public class TurnoffThread implements Runnable{private Receiver/implements; public TurnOffThread(Receiver receiver) { this.receiver = receiver; } public void run() { receiver.turnOFF(); }}
/** */ public class Demo {public static void main(String[] args) {Receiver Receiver = new Receiver(); TurnOffThread turnOffThread = new TurnOffThread(receiver); Thread thread = new Thread(turnOffThread); thread.start(); }}

Write in the last

  • If my article is useful to you, please click 👍, thank you!
  • Let me know in the comments section if you have any questions! 💪