[learning notes] design mode - command mode (Command/Action/Transaction)

0 design mode

If you don't know about design patterns, you can learn what design patterns are through this article

https://blog.csdn.net/qq_42874315/article/details/120006447

1 command mode

Command pattern is a data-driven design pattern, which belongs to behavior pattern. The request is wrapped in the object in the form of a command and passed to the calling object. Call the object to find the appropriate object that can process the command, pass the command to the corresponding object, and the object executes the command. The order is generally: caller → command → receiver.

2 implementation ideas

We first create the interface Order as a command, and then create the Stock class as a request. The entity command classes BuyStock and SellStock implement the Order interface and will execute the actual command processing. Create a class Broker as the calling object, which accepts orders and can place orders.

Broker objects use the command pattern to determine which object executes which command based on the type of command. The CommandPatternDemo class uses the broker class to demonstrate command patterns.

3 required classes

  1. Command interface

  2. Request class

    Write several methods for the implementation class of the command interface to call

  3. Implementation class of command interface

    Aggregate the request class, construct the assignment to it, and use the request class to call the corresponding method in the implementation method

  4. Command call class

    A List is used to store commands

    A method of adding commands

    A method of traversing and executing commands

  5. Test class

    Use the command call class to receive and execute commands

4 specific implementation

4.1 order (command interface)

/**
 * @Author ChenJiahao((Article 5)
 * @Date 2021/8/25 20:22
 */
public interface Order {
    void execute();
}

4.2 stock (request type)

/**
 * @Author ChenJiahao((Article 5)
 * @Date 2021/8/25 20:23
 */
public 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");
    }
}

4.3 implementation class of command interface

4.3.1 SellStockOrder

/**
 * @Author ChenJiahao((Article 5)
 * @Date 2021/8/25 20:29
 */
public class SellStockOrder implements Order{
    private Stock abcStock;

    public SellStockOrder(Stock abcStock) {
        this.abcStock = abcStock;
    }

    @Override
    public void execute() {
        abcStock.sell();
    }
}

4.3.2 BuyStockOrder

/**
 * @Author ChenJiahao((Article 5)
 * @Date 2021/8/25 20:27
 */
public class BuyStockOrder implements Order{

    private Stock abcStock;

    public BuyStockOrder(Stock abcStock) {
        this.abcStock = abcStock;
    }

    @Override
    public void execute() {
        abcStock.buy();
    }
}

4.4 broker (command calling class)

/**
 * Command call class
 * @Author ChenJiahao((Article 5)
 * @Date 2021/8/25 20:33
 */
public class Broker {
    private List<Order> orderList = new ArrayList<>();

    public void takeOrder(Order order){
        orderList.add(order);
    }

    public void placeOrders(){
        for (Order order : orderList) {
            order.execute();
        }
        orderList.clear();
    }
}

4.5 testing

/**
 * @Author ChenJiahao((Article 5)
 * @Date 2021/8/25 20:35
 */
public class Test {
    public static void main(String[] args) {
        Broker broker = new Broker();
        broker.takeOrder(new BuyStockOrder(new Stock()));
        broker.takeOrder(new SellStockOrder(new Stock()));
        broker.placeOrders();
    }
}

5 extension 1

5.1 problems in the above examples

Every time you add a command, you need to write another line of code, which is not beautiful

The concept of responsibility chain is introduced to realize chain addition command

5.2 modify the instance to realize the chain addition command

  1. In fact, in the above example, there is the concept of responsibility chain, which just changes the calling method to make it more beautiful
  2. You only need to change the return value of the takeOrder method in the original Broker class to Broker, and then return this

Modified Broker

/**
 * Command call class
 * @Author ChenJiahao((Article 5)
 * @Date 2021/8/25 20:33
 */
public class Broker {
    private List<Order> orderList = new ArrayList<>();

    public Broker takeOrder(Order order){
        orderList.add(order);
        return this;
    }

    public void placeOrders(){
        for (Order order : orderList) {
            order.execute();
        }
        orderList.clear();
    }
}

Test class

/**
 * call chaining 
 * @Author ChenJiahao((Article 5)
 * @Date 2021/8/25 20:35
 */
public class Test {
    public static void main(String[] args) {
        Broker broker = new Broker();
        /*broker.takeOrder(new BuyStockOrder(new Stock()));
        broker.takeOrder(new SellStockOrder(new Stock()));*/
        // Modify to chain add
        broker.takeOrder(new BuyStockOrder(new Stock()))
              .takeOrder(new SellStockOrder(new Stock()));
        broker.placeOrders();
    }
}

6 extension 2 (Introducing factory mode + strategy mode)

6.1 problems in extension 1

  1. If you want to add a new command, of course, the implementation class of the command interface is easier to add and complies with the OCP principle. However, if you want to add specific command content, you have to modify Stock, which does not comply with the OCP principle
  2. It is easy to cause confusion when constructing commands. For example, BuyStockOrder can call the sell() method, which is not allowed. This problem will be solved by modifying the code to factory + policy

6.2 modification example: import factory + policy

If you don't know about factory mode + strategy mode, you can learn about it first through this article:

https://blog.csdn.net/qq_42874315/article/details/119877790

6.2.1 unmodified: order (command interface)

/**
 * @Author ChenJiahao((Article 5)
 * @Date 2021/8/25 20:22
 */
public interface Order {
    void execute();
}

6.2.2 add: operatehandler (operation policy interface)

/**
 * @Author ChenJiahao((Article 5)
 * @Date 2021/8/25 21:20
 */
public interface OperateHandler {
    void operateStock(String name,int quantity);
}

6.2.3 add: implementation class of operation policy interface

BuyOperateHandler

/**
 * @Author ChenJiahao((Article 5)
 * @Date 2021/8/25 21:23
 */
public class BuyOperateHandler implements OperateHandler {
    @Override
    public void operateStock(String name, int quantity) {
        System.out.println("Stock [ Name:" + name + "Quantity:" + quantity + "] bought");
    }
}

SellOperateHandler

/**
 * @Author ChenJiahao((Article 5)
 * @Date 2021/8/25 21:24
 */
public class SellOperateHandler implements OperateHandler {
    @Override
    public void operateStock(String name, int quantity) {
        System.out.println("Stock [ Name:" + name + "Quantity:" + quantity + "] sold");
    }
}

6.2.4 add: stockoperatefactory

/**
 * Inventory operation plant
 * @Author ChenJiahao((Article 5)
 * @Date 2021/8/25 21:19
 */
public class StockOperateFactory {
    private static Map<String, OperateHandler> operateStockHandlerList = new HashMap<>();

    public static OperateHandler getOperateStockHandlerList(String operateName){
        return operateStockHandlerList.get(operateName);
    }

    public static void registerOperateStockHandler(String operateName,OperateHandler operateHandler){
        operateStockHandlerList.put(operateName,operateHandler);
    }
}

6.2.5 modify: stock (request type)

Delete the original buy method and sell method

Create a new method operateStock

/**
 * @Author ChenJiahao((Article 5)
 * @Date 2021/8/25 20:23
 */
public class Stock {

    private String name = "ABC";
    private int quantity = 10;

    public void operateStock(String operateName){
        StockOperateFactory.getOperateStockHandlerList(operateName).operateStock(name,quantity);
    }
}

6.2.6 modify: implementation class of command interface

BuyStockOrder

Modify the call buy method in execute instead of calling the operateStock method and import the corresponding operation string buy (key in factory map).

/**
 * @Author ChenJiahao((Article 5)
 * @Date 2021/8/25 20:27
 */
public class BuyStockOrder implements Order {

    private Stock abcStock;

    public BuyStockOrder(Stock abcStock) {
        this.abcStock = abcStock;
    }

    @Override
    public void execute() {
        abcStock.operateStock("buy");
    }
}

SellStockOrder

Modify the call sell method in execute instead of calling the operateStock method and import the corresponding operation string sell (key in factory map).

/**
 * @Author ChenJiahao((Article 5)
 * @Date 2021/8/25 20:29
 */
public class SellStockOrder implements Order {
    private Stock abcStock;

    public SellStockOrder(Stock abcStock) {
        this.abcStock = abcStock;
    }

    @Override
    public void execute() {
        abcStock.operateStock("sell");
    }
}

6.2.7 modify test class

Manually register the operation handler into the factory map

/**
 * Chain call + factory + policy
 * @Author ChenJiahao((Article 5)
 * @Date 2021/8/25 20:35
 */
public class Test {
    public static void main(String[] args) {
        Broker broker = new Broker();
        // Manually register the operation handler in the factory map (the operation registered here can let the operation interface inherit the InitializingBean in the Springboot project, and the subclasses are automatically registered in afterpropertieset())
        StockOperateFactory.registerOperateStockHandler("buy",new BuyOperateHandler());
        StockOperateFactory.registerOperateStockHandler("sell",new SellOperateHandler());
        // Modify to chain add
        broker.takeOrder(new BuyStockOrder(new Stock()))
              .takeOrder(new SellStockOrder(new Stock()));
        broker.placeOrders();
    }
}

7 mind map

8 example source code address

https://github.com/ChenJiahao0205/design-pattern/tree/master

last

I learned it through the video of Mr. Ma soldier and the rookie tutorial. Some of the contents may be the same

To read more articles related to design patterns, welcome to my columns [design patterns learning notes] and [design patterns]

After the release of 23 design pattern articles, I will publish a complete mind map, pay attention and don't get lost

Thank you for reading here. If there are any deficiencies in the article, you are welcome to point out; Yanzu point a praise, Yanzu point a praise, Yanzu point a praise, welcome to pay attention to the five programmers!

Keywords: Java Design Pattern

Added by prion on Sat, 25 Sep 2021 21:52:41 +0300