架构演化学习考虑(3)
架构演化学习考虑(3)
接上一篇咱们持续对指令形式进行学习。
在这节内容中,咱们聊一下经典的指令形式,还记得上一篇文章最初咱们完结的简略的指令形式吗?来看代码,非常简略易解。
public interface ICommand
{
void Execute();
}
public class PlayMusicCommand : ICommand
{
public void Execute()
{
Debug.Log("你说家是仅有的城堡,跟着稻香一路奔驰~");
}
}
var Start()
{
var command = new PlayMusicCommand();
command.Execute();
}
以上最简的指令形式中,咱们能够别离出一些人物。
ICommand:接口 对应经典指令形式中的 Command的人物
PlayMusicCommand:类 承继接口,是接口的详细完结,对应经典指令形式中的ConcreteCommand人物。
Start办法:是指令的宣布者,对应经典指令形式中的Invoker人物
由此咱们提炼完结经典指令形式的三个人物。
经典指令形式的完结完善
还差一个Receiver,即指令的接收者或履行者,组成经典指令形式的四种(也有说五种)人物:
- Command:笼统指令(指令接口)
- ConcreteCommand:详细指令
- Invoker:指令的调用者,发起者,触发者。
- Receiver:指令的接收者,被Command拜访和操作。
- 客户端:创立详细指令目标并设置其接收者,将指令目标交给调用者履行(假如涉及到5部分的话)
咱们还以产品购买为例,用以上涉及到的人物方法来完结购买货品这样一个操作。
namespace TestCommand
{
//售货员 对应Receiver
public class Salesperson
{
public void SellGoods(int id,int count)
{
for (int i = 1; i <= count; i++)
{
Debug.Log($"编号为{id}的产品售出1件!");
}
Debug.Log($"编号为{id}的产品总售出{count}件!");
}
}
//指令接口 对应Command
public interface Command
{
void Execute();
}
//详细完结 对应ConcreteCommand 详细指令
public class BuyCommand : Command
{
public Salesperson salesPerson;
public int goodsId;
public int count;
public void Execute()
{
salesPerson.SellGoods(goodsId,count);
}
}
//触发者 指令的发送者
//顾客
public class Customer
{
private List<Command> mCommands = new List<Command>();
public void AddCommand(Command command)
{
mCommands.Add(command);
}
//触发指令
public void triggerCommands()
{
mCommands.ForEach(command=>command.Execute());
mCommands.Clear();
}
}
//客户端人物
void Start()
{
var customer = new Customer();
var salesperson = new Salesperson();
//2 号产品购买五件 的指令
customer.AddCommand(new BuyCommand()
{
salesPerson = salesperson,
goodsId = 2,
count = 5
});
//让顾客宣布购买指令
customer.triggerCommands();
}
}
其大体思路如下:对应着经典指令形式的五部分
总算将经典形式的五部分完结完整了,指令形式梳理到这儿差不多完毕了,那么这对架构规划有啥启示和运用考虑呢?
当然有。
在项目中,咱们对坐落底层部分的数据模块拜访时就能够运用指令形式,Recever为底层的System或许数据Model,ConCreteCommand为对应的详细操作(对数据进行查和改、解锁成果体系的成果),而触发器Involver则是架构,也便是说整个项目的依靠联系的总掌控者,而客户端则对应体现层的操控逻辑。
不知道有没有对”架构“这个触发者的认知有没有愈加详细一些呢?
笔者是这样了解”架构“的身份的,好比是一个交换机接线员,当咱们需求和朋友电话时分,则要拿起自己这边的话筒传呼接线员,告知TA自己朋友的电话机号,然后接通之后,完结咱们对朋友沟通的需求。当然这个比如不一定非常精确,但很大程度上让咱们对”架构“的知道没有那么笼统。
好,在回到经典形式,来看一看此形式有什么优点。
指令形式的优点
优点之一是将Invoker和Receiver彻底解耦。
那这个功用如同观察者形式也能够完结吧,那么和观察者形式比照有些不同呢?答案还在指令自身,指令除了将invoker和receiver解耦,还能够进行自在扩展。我能够购买、也能够退货,也能够替换产品等等一些操作。当然从Invoker这边能够对指令进行存储(运用堆或许栈或许List等容器),从而能够完结回退恢复、行为树等功用。
关于指令形式的另一点考虑:
咱们将视角聚集在指令形式的Command中,也便是结构图上的”订单模板“。有了模板就好进行拓宽,这儿简略聊聊,指令形式中的开闭准则。
指令形式中的开闭准则
开闭准则咱们比较了解:
开闭准则:一个类应当对扩展敞开、对修正封闭
当一个结构模块或体系开发成型之后,除非遇到一些bug或许功用缺点,不然不应该对结构模块或许体系进行修正,这便是对修正封闭。而需求新增加功用或许拓宽时分,能够经过扩展的方法来增加一些功用,也便是对扩展敞开。
而依据指令形式中的各个人物,在拓宽功用时分有着不同的准则和效果:
- Invoker:封闭修正
- Recever:封闭内部修正
- Command: 拓宽的规范
- ConcreteCommand :敞开完结的拓宽
笔者的项目功底尚浅,仅仅简略的聊一下涉及到开闭准则,愿咱们多写代码多实践,
渐渐将这些考虑在实践项目中有所运用和体会,逐步提高自己的编程和架构规划能力。
好,关于指令形式咱们就聊到这儿了,接下来还会持续更新此系列内容,谢谢各位与我一同考虑和体悟!