一、目录
架构的常识
1. 什么是架构?
2. 为什么需要架构?
3. 架构师的职责软件架构
软件架构分类
典型应用架构
1. 分层架构
2. CQRS
3. 六边形架构
4. 洋葱圈架构COLA 应用架构
1. 分层设计
2. 扩展设计
3. 规范设计
4. COLA 架构总览应用架构的核心
二、架构的常识
1. 什么是架构?
关于架构这个概念很难给出一个明确的定义,也没有一个标准的定义。
系统构架是对已确定的需求的技术实现构架、作好规划,运用成套、完整的工具,在规划的步骤下去完成任务。抽象来说,它是计算机系统结构,或称计算机体系结构,是一个系统在其所处环境中最高层次的概念。
架构始于建筑,是因为人类发展(原始人自给自足住在树上,也就不需要架构),分工协作的需要,将目标系统按某个原则进行切分,切分的原则,是要便于不同的角色进行并行工作。
2. 为什么需要架构?
有系统的地方就需要架构,大到航空飞机,小到一个电商系统里面的一个功能组件都需要设计和架构。
与之相对应的,现在很多敏捷思想提倡 no design,只要 work 就好。期待好的架构可以在迭代中自然涌现。这个想法有点太理想化了,在现实中,只要能 work 的代码,工程师是很少有动力去重构和优化的。
3. 架构师的职责
作为架构师,我们最重要的价值应该是“化繁为简”。但凡让事情变得更复杂,让系统变得更晦涩难懂的架构都是值得商榷的。
架构师的工作就是要努力训练自己的思维,用它去理解复杂的系统,通过合理的分解和抽象,使哪些系统不再那么难懂 。我们应该努力构建易懂的架构,使得在系统上工作的其他人员(例如设计者、实现者、操作员等)可以较为容易地理解这个系统。
三、软件架构
软件架构是一个系统的草图。软件架构描述的对象是直接构成系统的抽象组件。各个组件之间的连接则明确和相对细致地描述组件之间的通信。在实现阶段,这些抽象组件被细化为实际的组件,比如具体某个类或者对象。在面向对象领域中,组件之间的连接通常用接口来实现。
软件架构为软件系统提供了一个结构、行为和属性的高级抽象 ,由构件的描述、构件的相互作用、指导构件集成的模式以及这些模式的约束组成。软件架构不仅显示了软件需求和软件结构之间的对应关系,而且指定了整个软件系统的组织和拓扑结构,提供了一些设计决策的基本原理。
软件架构的核心价值应该只围绕一个核心命题:控制复杂性。他并不意味着某个特定的分层结构,某个特定的方法论(贫血、DDD 等)。
四、 软件架构分类
在介绍应用架构之前,我们先来看一下软件架构的分类。
随着互联网的发展,现在的系统要支撑数亿人同时在线购物、通信、娱乐的需要,相应的软件体系结构也变得越来越复杂。软件架构的含义也变得更加宽泛,我们不能简单地用一个软件架构来指代所有的软件架构工作。按照我个人理解,将软件架构划分为:
在洋葱架构中,明确规定了依赖的方向:
- 外层依赖内层
- 内层对外层无感知
六、COLA 应用架构
COLA 架构是阿里自主研发的应用架构,目前已经开源。在 COLA 的设计中,充分汲取了经典架构的优秀思想。除此之外,补充了规范设计和扩展设计,并且使用 Archetype 的方式,将架构固化下来,以便可以快速的在开发中使用。
COLA 开源地址:https://github.com/alibaba/COLA
6.1. 分层设计
COLA 的分层是一种改良了的三层架构。主要是将传统的业务逻辑层拆分成应用层、领域层和基础实施层。如下图所示,左边是传统的分层架构,右边是 COLA 的分层架构。
其每一层的作用范围和含义如下:
1)展现层(Presentation Layer)
负责以 Rest 的格式接受 Web 请求,然后将请求路由给 Application 层执行,并返回视图模型(View Model),其载体通常是 DTO(Data Transfer Object)。
2)应用层(Application Layer)
主要负责获取输入,组装上下文,做输入校验,调用领域层做业务处理,如果需要的话,发送消息通知。当然,层次是开放的,若有需要,应用层也可以直接访问基础实施层。
3)领域层(Domain Layer)
主要是封装了核心业务逻辑,并通过领域服务(Domain Service)和领域对象(Entities)的函数对外部提供业务逻辑的计算和处理.
4)基础实施层(Infrastructure Layer)
主要包含 Tunnel(数据通道)、Config 和 Common。这里我们使用 Tunnel 概念来对所有的数据来源进行抽象,这些数据来源可以是数据库(MySQL,NoSql)、搜索引擎、文件系统、也可以是 SOA 服务等;Config 负责应用的配置;Common 是通用的工具类。
6.2. 扩展设计
对于只有一个业务的简单场景,对扩展性的要求并不突出,这也是为什么扩展设计常被忽略的原因,因为我们大部分的系统都是从单一业务开始的。但是随着业务场景越来越复杂,代码里面开始出现大量的 if-else 逻辑。此时除了常规的策略模式以外,我们可以考虑在架构层面提供统一的扩展解决方案。
在扩展设计中,我们提炼出两个重要的概念,一个是业务身份 ,另一个是扩展点 。
业务身份是指业务在系统唯一标识一个业务或者一个场景的标志 。在具体实现中,我们使用 BizCode 来表示业务身份,其中 BizCode 采用类似 Java 包名命名空间的方式。例如,我们可以用 “ali.tmall” 表示阿里天猫业务,用 “ali.tmall.car” 表示阿里天猫的汽车业务,而用 'ali.tmall.car.aftermarket' 代表这是阿里天猫的汽车业务的后市场场景。
每个业务或者场景都可以实现一个或多个扩展点(ExtensionPoint) ,也就是说一个业务身份加上一个扩展点,可以唯一地确定一个扩展实现(Extension)。而这个业务身份和扩展点的组合,我们将其称之为扩展坐标(ExtensionCoordinate),如下图所示。
这样,通过业务身份+扩展点,我们就可以从框架层面实现对不同租户,不同业务,不同场景的扩展定制了。整个阿里业务中台正是基于这个思想,实现的多业务支撑的。
6.3. 规范设计
任何事物都是规则性和随机性的组合。规范的意义就在于我们可以将规则性的东西固化下来,尽量减少随心所欲带来的复杂度,一致性可以降低系统复杂度。从命名到架构皆是如此,而架构本身就是一种规范和约束,破坏这个约束,也就破坏了架构。
COLA 制定了一些列的规范:包括组件(Module)结构、包(Package)结构、命名等。
比如对于组件,我们要求使用 COLA 的应用都应该遵循如下图所示的组件划分:
6.4. COLA 架构总览
在架构思想上,COLA 主张像六边形架构那样,使用端口-适配器去解耦技术细节;主张像洋葱圈架构那样,以领域为核心,并通过依赖倒置反转领域层的依赖方向。最终形成如下图所示的组件关系。
换一个视角,从 COLA 应用处理响应一个请求的过程来看。COLA 使用了 CQRS 来分离命令和查询的职责,使用扩展点和元数据来提升应用的扩展性。整个处理流程如下图所示:
七、应用架构的核心
纵观上面介绍的所有应用架构,我们可以发现一个共同点,就是“核心业务逻辑和技术细节分离 ”。
是的,六边形架构、洋葱圈架构、以及 COLA 架构的核心职责就是要做核心业务逻辑和技术细节的分离和解耦。
试想一下,业务逻辑和技术细节糅杂在一起的情况,所有的代码都写在 ServiceImpl 里面,前几行代码是做 validation 的事,接下来几行是做 convert 的事,然后是几行业务处理逻辑的代码,穿插着,我们需要通过 RPC 或者 DAO 获取更多的数据,拿到数据后,又是几行 convert 的代码,在接上一段业务逻辑代码,然后还要落库,发消息.....等等。
再简单的业务,按照上面这种写代码的方式,都会变得复杂,难维护。
因此,我认为应用架构的核心使命就是要分离业务逻辑和技术细节。让核心业务逻辑可以反映领域模型和领域应用,可以复用,可以很容易被看懂。让技术细节在辅助实现业务功能的同时,可以被替换。