What is?

Command Pattern is a data-driven design Pattern, which belongs to behavior Pattern. The request is wrapped in the object as a command and passed to the calling object. The calling object looks for a suitable object that can handle the command and passes the command to the corresponding object, which executes the command.

Why use him?

In some situations, such as “record, undo/redo, transaction” processing of behavior, such tight coupling that cannot resist change is not appropriate. In this case, how to decouple the “behavior requester” from the “behavior implementor”? Loose coupling can be achieved by abstracting a set of behaviors as objects. Execute commands through caller to call receiver in order: caller → command → receiver.

A, role,

  1. Received The actual command execution object
  2. Command Abstracts a Command class
  3. Invoker uses the entry of the command object
  4. The client client
  5. ConcreteCommand Implements the command class

How to decouple command mode?

Invoker is also programmed for an interface, but instead of being implemented by a Receiver, the interface is implemented by a command object. Invoker just calls the execute method of the command object. It has no idea what happens in the execute method. The command object is the bridge between the Invoker and the Receiver. With command objects, we can make Invoker call a method of a class, etc., as needed.

Three, code,

package com.godliang.design.command; import com.sun.org.apache.xpath.internal.operations.Or; import java.util.ArrayList; import java.util.List; import java.util.Stack; /** * @author GodLiang * @version 1.0 * @date 2021/2/9 19:34 * @description: TODO command pattern */ Public Class CommandPatternDemo {public static void main(String[] args) {// Create the request class Stock abcStock = new Stock(); BuyStock buyStockOrder = new BuyStock(abcStock); SellStock sellStockOrder = new SellStock(abcStock); Broker = new Broker(); // Add the command executor broker. TakeOrder (buyStockOrder); broker.takeOrder(sellStockOrder); // Batch execute broker.placeOrders(); broker.undoOrders(); }} /** * class Stock {private String name = "ABC"; private int quantity = 10; public void buy(){ System.out.println("Stock [ Name: "+name+", Quantity: " + quantity +" ] bought"); } public void sell(){ System.out.println("Stock [ Name: "+name+", Quantity: " + quantity +" ] sold"); Void execute(); void execute(); void execute(); /** */ void undo(); } /** * class Stock implements Order {private Stock abcStock; public BuyStock(Stock abcStock){ this.abcStock = abcStock; } @Override public void execute() { abcStock.buy(); } @Override public void undo() { abcStock.sell(); } /** * class Stock implements Order {private Stock abcStock; public SellStock(Stock abcStock){ this.abcStock = abcStock; } @Override public void execute() { abcStock.sell(); } @Override public void undo() { abcStock.buy(); Private List<Order> orderList = new ArrayList<Order>(); @param order */ private Stack< order > orderStack = new Stack<>(); public void takeOrder(Order order){ orderList.add(order); } public void placeOrders(){ for (Order order : orderList) { order.execute(); // add orderStack.add(order); Public void undoOrders(){do {Order Order = orderStack.pop(); order.undo(); }while (! orderStack.empty()); }}Copy the code

Four, advantages and disadvantages

Advantages:

  1. The coupling degree of the system is reduced.
  2. New commands can be easily added to the system.
  3. You can easily set up a set of commands
  4. You can undo or reset a command

Disadvantages:

  1. Because each small command needs to re-implement a command implementation class. Can lead to too many classes. Can affect reading and use