On summer nights, the street is always lively and extraordinary. People like to eat barbecue and drink beer with friends of about three or five. It's just like eating kebab and singing songs.
Walking down the street, I suddenly found that there were not many people in a barbecue stall, so you came up and said to your boss, "Come on, 10 strings of mutton, 3 strings of chicken wings ....... After that, you will wait, and you will find that there are more and more people talking to your boss about your requirements. It is obvious that the boss is helpless. First, the boss should remember who came first, who later, who gave money, who didn't give money, who don't put chilies ...... Wait, there are too many problems, and so many people are staring at the boss's kebab, which leads to criticism, which is too much, and which is missing or something, which is really messy.
So you chose to go to a barbecue shop not far away. After you sat down, you directly told the waiter what to eat and how much to eat. After the waiter wrote down the order, he directly sent the order to the kitchen, then entertain other new customers. As a programmer, you are immersed in meditation ......
The two situations tonight exactly show a design pattern in software design, that is, the Command pattern mentioned in the title. Let's take a look at how to map the actual situation to the Command pattern.
First, we can abstract the business model of barbecue stalls to obtain the following class diagrams:
The structure is very simple. There are two classes, but because of the simplicity, there are too many hidden problems. from the perspective of programming, the customer is the "behavior requestor", and the boss of the kebab is the "behavior implementer". In the above case, the coupling between the two is very high, this is a taboo in programming. If the behavior requestor wants to cancel his own request, this tight coupling relationship is really troublesome. so how can we improve it?
Let's take a look at the abstract of the barbecue shop. Its structure is as follows:
From the above class diagram, we can see that we have added a waiter class to decouple the customer and the kebab. On the one hand, the waiter must accept the order from the customer, on the other hand, the chef is notified to implement the customer's requirements. we use the specific code implementation to illustrate how to implement the relationship in the class diagram in the Code. As for the code implementation of the first class diagram, it is relatively simple and left for readers to implement it, I will not go into details here.
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ConsoleApplication1{ //客户端代码实现 class Program { static void Main(string[] args) { //开店前的准备 Barbecuer boy = new Barbecuer(); Command bakeMuttonCommand1 = new BakeMuttonCommand(boy); Command bakeChickenWingCommand1 = new BakeChickenWingCommand(boy); Waiter girl = new Waiter(); //开门营业,顾客点菜 girl.SetOrder(bakeMuttonCommand1); girl.SetOrder(bakeChickenWingCommand1); //点菜完毕,通知厨房做菜 girl.Notify(); Console.Read(); } } //烤串者类 public class Barbecuer { public void BakeMutton() { Console.WriteLine("烤羊肉串"); } public void BakeChickenWing() { Console.WriteLine("烤鸡翅"); } } //抽象命令类 public abstract class Command { protected Barbecuer receiver; public Command(Barbecuer receiver) { this.receiver = receiver; } abstract public void ExcuteCommand(); } //具体命令类 //烤羊肉串命令 class BakeMuttonCommand:Command { public BakeMuttonCommand (Barbecuer receiver):base(receiver ) { } public override void ExcuteCommand() { receiver.BakeMutton(); } } //烤鸡翅命令 class BakeChickenWingCommand : Command { public BakeChickenWingCommand(Barbecuer receiver) : base(receiver) { } public override void ExcuteCommand() { receiver.BakeChickenWing(); } } //服务员类 //public class Waiter //{ // private Command command; // public void SetOrder(Command command) // { // this.command = command; // } // public void Notify() // { // command.ExcuteCommand(); // } //} //改写后的服务员类******************************************************************************* public class Waiter { private IList<Command> orders = new List<Command>(); //设置订单 public void SetOrder(Command command) { if (command.ToString() == "命令模式.BakeChickenWingCommand") { Console.WriteLine("服务员:鸡翅没有了,请点别的烧烤"); } else { orders.Add(command); Console.WriteLine("增加订单:" + command.ToString() + "时间:" + DateTime.Now.ToString()); } } //取消订单 public void CancelOrder(Command command) { orders.Remove(command); Console.WriteLine("取消订单:" + command.ToString() + "时间:" + DateTime.Now.ToString()); } //通知全部执行 public void Notify() { foreach (Command cmd in orders) { cmd.ExcuteCommand(); } } }}
First, let's look at the aggregation relationship between the waiter class and the abstract command class. Why? Simply put, the waiter can accept various commands, and the waiter and each command class are independent of each other, so it is an aggregation relationship. in the code, we declare a container (list type) for storing specific commands in the waiter class, and then use the instance of the specific command class as the parameter of its method to operate on it.
The second is the inheritance relationship between the abstract command class and the specific command class. This is very simple and should not be much, that is, when creating a specific class, add the following after the class name: followed by the parent class name (C # language ).
In addition, it is the dependency between the kebab and the specific command class. When we define a specific class, the parameter of the class constructor is set as the kebab, which expresses the following, the execution of a specific command class depends on the specific implementer. Then, in the method body, the method of the kubernetes is called through the Instance Object of the kubernetes class to complete the actions and operations required by the specific command.
Finally, there is an association between the client class, the waiter class, And the kebab class. This relationship is expressed by adding the reference of the waiter class and the kebab class to the client class, it is to instantiate the specific object of a kebab class and the specific object of a waiter class in the client code.
The above is the implementation method of various relationships in the class diagram in the code. We can use this method to analyze the various relationships in the structure charts of other design patterns, in this way, the conversion between class diagrams and code can be easily achieved.
Finally, the definition of the command mode is given: encapsulate a request as an object, so that you can parameterize the customer with different requests; queue requests or record request logs, and supports unrecoverable operations. We can compare the above examples to understand the definition of the command mode, so that we can visually understand what the command mode is like.
Thoughts on kebabs-command mode