Architecture Evolution Learning Reflections (3)
Continuing from the previous article, we continue our study of command mode.
In this section, we talk about the classic command pattern, remember the simple command pattern we implemented at the beginning of the last article? Come and see the code, it's very simple and easy to understand.
public interface ICommand
{
void Execute();
}
public class PlayMusicCommand : ICommand
{
public void Execute()
{
("You said home was the only castle.,With Inari running all the way~");
}
}
var Start()
{
var command = new PlayMusicCommand();
();
}
There are a number of roles that we can isolate in the simplest command model above.
ICommand: interface Corresponds to the role of Command in the classic command model.
PlayMusicCommand: class Inherits the interface and is a concrete implementation of the interface, corresponding to the ConcreteCommand role in the classic command pattern.
Start method: is the issuer of the command, corresponding to the Invoker role in the classic command pattern
From this we distill the three roles that implement the classical command pattern.
A refinement of the classic command pattern implementation
One Receiver, the receiver or executor of commands, is still missing, making up the four (or some say five) roles of the classic command pattern:
- Command: abstract command (command interface)
- ConcreteCommand: specific command
- Invoker: the invoker, initiator, and trigger of the command.
- Receiver: the receiver of the command, accessed and manipulated by Command.
- Client: creates the concrete command object and sets its recipient, gives the command object to the caller for execution (if 5 parts are involved)
Let's also take the purchase of goods as an example, and use the role approach involved above to realize such an operation as purchasing goods.
namespace TestCommand
{
//salesmen homologousReceiver
public class Salesperson
{
public void SellGoods(int id,int count)
{
for (int i = 1; i <= count; i++)
{
($"number{id}of goods sold1classifier for clothes, luggage, decorations; piece of work; a matter, an event!");
}
($"number{id}Total merchandise sold{count}classifier for clothes, luggage, decorations; piece of work; a matter, an event!");
}
}
//command interface homologousCommand
public interface Command
{
void Execute();
}
//concrete realization homologousConcreteCommand Specific commands
public class BuyCommand : Command
{
public Salesperson salesPerson;
public int goodsId;
public int count;
public void Execute()
{
(goodsId,count);
}
}
//ignitor The sender of the order
//patron
public class Customer
{
private List<Command> mCommands = new List<Command>();
public void AddCommand(Command command)
{
(command);
}
//trigger command
public void triggerCommands()
{
(command=>());
();
}
}
//Client Roles
void Start()
{
var customer = new Customer();
var salesperson = new Salesperson();
//2 号商品购买五classifier for clothes, luggage, decorations; piece of work; a matter, an event exclusionary rule
(new BuyCommand()
{
salesPerson = salesperson,
goodsId = 2,
count = 5
});
//让patron发出购买命令
();
}
}
The general idea is as follows: it corresponds to the five parts of the classical command pattern
Finally, the five parts of the classic pattern to achieve a complete, command pattern combing here is almost over, then what is the inspiration for architectural design and application of thinking about it?
Of course there is.
In the project, we can apply the command pattern when accessing the data module located in the bottom part, Receiver is the bottom System or data Model, ConCreteCommand is the corresponding specific operation (check and change the data, unlock the achievement of the achievement of the system), and Trigger Involver is the architecture, that is to say, the whole project's Dependencies of the total controller, while the client corresponds to the performance layer of the control logic.
I wonder if there's any more specific knowledge of "architecture" as a trigger?
The author is this understanding of the identity of the "architecture", like a switchboard operator, when we need to talk to a friend on the phone, it is necessary to pick up their own side of the microphone paging operator, tell TA their friends phone number, and then connected, to complete the exchange of our friends to the needs of the exchange. Of course, this example is not necessarily very accurate, but to a large extent so that we do not know the "architecture" of the abstract.
Okay, in going back to the classic mode and looking at what this mode has to offer.
Benefits of Command Mode
One of the benefits is the complete decoupling of Invoker and Receiver.
Then this function seems toobserver modelIt can also be realized, right, so and the observer pattern compared to some of the differences? The answer lies in the command itself, which in addition to decoupling the invoker from the receiver, can also perform aFree Expansion. I can buy, I can return, I can replace the item, and so on. Of course, from the Invoker side, you can store the commands (using containers such as a heap or a stack or a list), which in turn allows you to implement features such as fallback recovery, behavior trees, and so on.
Another thought on the command pattern:
Let's focus on the Command of the Command pattern, which is the "order template" on the structure picture. With the template, it is good to expand, here is a brief talk, the principle of opening and closing in the command pattern.
The principle of opening and closing in the command model
The principle of opening and closing is more familiar:
Open-Closed Principle: A class should be open to extensions and closed to modifications.
After a structure module or system is developed and molded, unless some bugs or functional defects are encountered, the structure module or system should not be modified, which is closed to modification. And when you need to add new functions or expand, you can add some functions by way of expansion, which is open to expansion.
And depending on the roles in the command model, there are different guidelines and roles when it comes to expanding functionality:
- Invoker: closing modification
- Recever: turns off internal modifications
- Command: Criteria for Expansion
- ConcreteCommand : Open Implementation Extension
The author's project skills are still shallow, just a simple chat involving the principle of opening and closing, may we write more code more practice, the
Slowly apply and experience these thoughts in real projects, and gradually improve your programming and architectural design skills.
Well, about the command mode we talked about here, the next will continue to update this series of content, thank you to think and realize with me!