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
-
Command interface
-
Request class
Write several methods for the implementation class of the command interface to call
-
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
-
Command call class
A List is used to store commands
A method of adding commands
A method of traversing and executing commands
-
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
- In fact, in the above example, there is the concept of responsibility chain, which just changes the calling method to make it more beautiful
- 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
- 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
- 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!