写在前面
最开始做架构最好的方式都是基于模仿的,我们可以找到一个类似于我们现有系统的业界解决方案,阅读并分析,看看究竟哪些可以抽象摘借出来为我所用。比如在软件系统重构过程中有一些现有的模式是可以直接复用的,相信在平时的重构过程中有些模式你已经使用过了。
可复用的架构模式
列出以下几个自己平时习惯套用的模式:
- 分层模式;
- 管道模式(过滤器模式);
- 聚合网关模式;
- MVC模式;
- 事件驱动模式;
多层模式
多层模式是我们做架构设计时最常用的一种模式,我们习惯的基于三层方式对我们的整体架构进行分层,比如说最上层的是展现层,中间是逻辑层,最下面是持久层,比如这样:
其实分层设计和分模块分领域设计的思路是一致的,都是通过代码聚合的方式将能力收敛,达到边界清晰的目的,以后每个模块和分层可以独立演进,互不影响,提高了开发效率与扩展性。
当问你分层对于系统带来了哪些好处呢?有人会说实现了更好的解耦,但是分的层越多一定越好吗?
答案肯定是否定的,因为过度的分层反而带来了治理的无序,我个人更将这种分层或分模块看成是一种能力标准化的方式,因为我们目的是提供某种程度上的标准化能力,而这部分能力是需要基于具体支撑的场景来抽象的,也就最终影响到了分层与合并,进而回答那个分层多少的问题。
每一层都是一组模块,这组模块组合起来就是某种标准化能力的收敛。需要注意的是层的依赖必须是单向的,也就是上层依赖于下层,反过来是不行的。理想态是每层是一个完整的分区,对外提供公开的接口。
比如表现层是对于展现的标准化实现,这种展现可能是有用户界面的,或者是通过提供某种聚合形式的api json result间接达成了某个UI上的展现,比如多客户端的展示,甚至是一些IOT设备上的报文、心跳信息等。
分层可以用于单实例的代码逻辑分层,也就是独立部署的进程里面进行分层,另一种方式的分层是物理部署节点的分层,比如网关层独立部署,逻辑层按读写分离独立部署,持久层只做多数据源的聚合于路由,几层都只干了逻辑分层的一部分能力,但又是独立部署的。
分层是技术性的分区架构,而不是一个领域的分区架构。分层是围绕于组件形成的,而不是领域本身。
大部分场景可以依据分层方式实现,属于一种通用普世的解决方案。
管道模式
还有一种常见的模式是管道模式,或是过滤器模式。
说道过滤器模式,大家可能最先想到的是如tomcat或filter这种实现方式,任务过滤器顶多是实现大型系统里面某个组件功能的,很难提升到架构设计维度吧。
其实不是的。
我们接触到的很多系统都有管道模式的影子,特别是那些具有状态机驱动的场景,比如订单有明确的状态机,配送有明确的状态机,很多都可以抽象出一个明确流转不可逆的状态机的,这些具有明确状态机流转特点的系统都可以以管道模式进行设计。
他的设计特点围绕于输入、流转、输出过程中数据流的变化。
引入管道模式去解决复杂业务时,可以设计成一个个的松耦合的组件,组件之间有简单的通用交互机制,可以灵活集合,组件也更易复用,你的数据流转也更清晰。
而一个重复请求的幂等处理或是路由处理,可以很简单的基于状态机将其路由到某个指定的逻辑,精简了链路,去除了没有必要的逻辑处理。
比如以IM系统会话来说,其包括会话创建,会话排队,会话分配,会话聊天,会话结束。我们只需要在会话创建时,建立相关会话上下文,其他后续流程就不需要对上下文信息进行过分的校验与考虑了,只做”读行为“即可,大大降低了编码复杂度和理解成本。
当然管道模式有他的好处,其缺点也极其明显,需要有明确的流转特征的系统,而上下文信息的解析与泛解析成本会比较高,所以我一般会将流程层独立抽象出一层,降低其与领域层直接产生关系,这样可以在扩展状态机时减少开发成本。
聚合网关模式
你可以认为是网关模式,如果没有网关模式的话,一个客户端对应一个server这样很多资源与逻辑是难以复用的,所以好的方式是抽象出一个网关做资源聚合,复用到多个客户端,同时可以提高管控与弹性伸缩的能力。
网关中一般有两个组件,”接收逻辑“与”处理逻辑“,前者负责接收请求,将其发送到处理器,处理器处理之后异步响应回来。
这种模式适用于那些对于吞吐量有高要求,但是处理周期长特点的业务系统。
其缺点也很明显,就是处理逻辑会成为系统的性能瓶颈,故障点。
MVC模式
MVC是我们常用的一种模式,一般用于那些直接和客户端打交道的系统,因为端对于UI及UI所需的格式有一定的要求,而UI部分往往是一个改动频次较高的部分,所以MV就是需要做好UI及UI背后的数据源支撑。
- 模型:包含属性的数据模型
- 视图:数据源及展示交互的组合
- 控制器:承接模型与视图之间的衔接逻辑
事件驱动模式
计算机最常处理的场景就是对于事件的响应,可以将特定业务抽象成事件,并广播出去,这样的好处是,扩展能力好。
而大型系统对于事件的产生与处理使用的还是比较多的,微服务架构下的事件通知往往是基于MQ实现的。
每个事件可以建立独立部署或独立处理逻辑的组件,当事件进入队列后,可以引入调度器根据策略进行调度,或是事件处理器主动拉取事件进行事件处理。
分布式架构下,常用的场景是对于状态机的事件订阅,比如订单的达成、支付,配送状态的变更、流转时间等,其他团队基于事件监听异步跨服务的进行异步逻辑处理。
写在后面
知道了这些模式了,可以在系统设计时有意识的看看是否可以适用,一步步找到不同模式所特有的场景,这种实现可大可小,可以用作模块设计,也可以用作微服务系统的组合搭建。