软件架构编年史:整洁架构

简介: 软件架构编年史:整洁架构

Robert C. Martin(大名鼎鼎的 Uncle Bob)于2012年在他的一篇博客中发表了整洁架构的观点,并在一些会议上做了关于该架构的演讲。


整洁架构借助了许多或熟悉或陌生的概念、规则和模式,说明了如何将它们融会贯通产生出一种构建应用的标准套路。


◐ 站在 EBI 架构、六边形架构和洋葱架构的肩膀上



整洁架构的核心目标与端口和适配器(六边形)架构以及洋葱架构是一致的:

  • 工具无关
  • 传达机制无关
  • 独立的可测试性


下面这张图发表在整洁架构的博客中,揭示了该架构的总体思路:


image.png

Robert C. Martin 2012, The Clean Architecture


正如 Uncle Bob 自己在博客中所说,上面这张图试图将最新的架构观点整合成一个可操作的思路。


我们来对比一下整洁架构和六边形架构以及洋葱架构的示意图,看看它们在哪些方面是一致的:


image.pngimage.png


外化工具和传达机制


六边形架构聚焦于使用接口和适配器将工具和传达机制从应用中外化出去。这也是洋葱架构的核心基石之一,就像图中呈现的那样,UI、基础设置和测试全部都在示意图的最外层。整洁架构也有完全一致的特征,UI、Web、DB 等等都在最外层。最终,所有的应用核心代码都是独立于框架/库的。


依赖方向


六边形架构中并没有明确地告知我们依赖的方向。然而,我们可以轻易地推测出来:应用拥有接口,它们必须由适配器实现或使用。所以适配器依赖接口,依赖位于圆心的应用。外部依赖内部,依赖的方向就指向圆心。在洋葱架构的示意图中,也没有发现关于依赖方向的表示,但是,Jeffrey Palermo 在他的第二篇博客中清楚地表明了所以依赖都指向圆心。整洁架构则非常明确的指出依赖的方向是指向圆心的。它们都在架构层级引入了依赖倒置原则。内圈不能知道外圈的任何信息。还有,当数据跨越界限进行传递时,数据总是以最方便内圈使用的格式提供。


分层


六边形架构示意图只展现了两个层次:应用内部和应用外部。而洋葱架构引入了 DDD 中定义的应用层次的混合:控制用例逻辑的应用服务;封装了领域逻辑的领域服务,这些逻辑既不属于实体也不属于值对象;还有实体、值对象等等...和洋葱架构相比,整洁架构保留了应用服务层(用例)和实体层,当好像漏掉了领域服务层。然而,读过 Uncle Bob 的博客后,我们会发现,他认为任何领域对象都是实体,而非只有 DDD 中的“实体”才是实体:“一个实体可以是一个拥有方法的对象,或者是一组数据结构和函数”。实际上,他为了简化示意图而将最中间的两层合并了。


独立的可测试性


三种架构风格共同遵守的规则,让它们将应用和业务逻辑隔离了出来。这意味着任何情况下我们都可以简单地 mock 外部工具和传达机制,独立地对应用的代码进行测试,而不需要使用数据库或 HTTP 请求。


正如我们所见,整洁架构包含了六边形架构和洋葱架构的规则。截至目前,整洁架构好像没有加入什么新鲜的概念。但是,在整洁架构示意图的右下角,还有一张小图...


◐ 站在 MVC 和 EBI 的肩膀上



整洁架构示意图的右下角的这张小图说明了控制流是如何工作的。这张小图并没还有提供太多信息,但博客中的说明和 Robert C. Martin 的会议演讲拓展了该话题。


image.png


我们在上图的左侧看到的是 MVC 中的视图和控制器。双实线另一层的所有形状都是 MVC 中的模型。这些模型也代表着 EBI 架构(我们可以清楚的看到边界、交互器和实体),六边形架构中的“应用”、洋葱架构中的“应用核心”,以及前面整洁架构示意图中的“实体”层和“用例”层。


假设有一个 HTTP 请求按照控制流到达了控制器。控制器接下来会:

  • 拆解请求;
  • 使用相关数据创建一个请求模型;
  • 执行交互器(作为交互器接口的,即边界的,实例被注入到控制器中)中的方法并将请求模型传递给它;
  • 交互器会:
  • 使用实体网关实现(作为实体网关接口的实例被注入到交互器中)查找相关实体;
  • 编排实体之间的交互;
  • 用操作的数据结果创建响应模型;
  • 将响应模型交给展示器进行填充;
  • 将展示器返回给控制器;
  • 使用展示器生成视图模型;
  • 将视图模型绑定到视图;
  • 将视图返回给客户端。


这里只有“展示器”的用法我有些疑问,我在项目中的实际做法和这里不太一样。我会将某种 DTO 类型的数据返回给交互器,而不是注入一个填充了数据的展示器对象。


我通常会采用实际上是一种 MVP 实现,控制器在其中负责从客户端接收数据并响应它。


◐  总结



我不认为整洁架构是革命性的,因为它实际上并没有带来突破性的概念或模式。


但是,我认为它是相当重要的成果:

  • 它发掘了某种程度上被遗忘了的概念、规则和模式;
  • 它澄清了一些实用且重要的概念、规则和模式;
  • 它告诉我们如何把所有的概念、规则和模式整合起来,形成一种构建复杂应用并保持可维护性的标准套路


Uncle Bob 关于整洁架构的工作总会让我想起牛顿。引力始终是存在的,每个人都知道松手让苹果远离地面的高处落下,它会落向地面。牛顿做的事情“只不过”是写了一篇论文披露这个事实。这件事请很“简单”,但却让人们开始思考它并基于它创造更新的想法。


换句话说,我认为 Robert C. Martin 就是软件开发领域的牛顿[*注]


◐   引用来源



  • 2012 – Robert C. Martin – Clean Architecture (NDC 2012)
  • 2012 – Robert C. Martin – The Clean Architecture
  • 2012 – Benjamin Eberlei – OOP Business Applications: Entity, Boundary, Interactor
  • 2017 – Lieven Doclo – A couple of thoughts on Clean Architecture
  • 2017 – Grzegorz Ziemoński – Clean Architecture Is Screaming


* 我知道牛顿爵士的成就远不止这些,但我只想强调我认为 Robert C. Martin 的观点到底有多重要。

相关文章
|
6月前
|
存储 监控 微服务
微服务和单体架构是两种不同的软件架构风格
微服务和单体架构是两种不同的软件架构风格
81 1
|
6月前
|
前端开发 Java 测试技术
使用整洁架构优化你的 Gradle Module
使用整洁架构优化你的 Gradle Module
72 0
|
4月前
|
人工智能 供应链 架构师
软件架构一致性问题之Serverless架构处理架构一致性问题如何解决
软件架构一致性问题之Serverless架构处理架构一致性问题如何解决
53 2
|
6月前
|
存储 监控 微服务
微服务和单体架构是两种不同的软件架构风格,每种都有其自身的优缺点
【1月更文挑战第1天】微服务和单体架构是两种不同的软件架构风格,每种都有其自身的优缺点
113 0
|
6月前
|
架构师 微服务
什么是软件架构?架构的本质是什么?
定义 ”架构是什么“ 是件非常困难的事情,不同的组织对于软件架构有不同的定义,每个人心中也有自身对于系统架构定义的认知。就好比我们无法百分之百表述模型而只能产出模型不同维度的视图,对架构进行完备的定义是不可能的。
133 4
|
6月前
|
前端开发 Oracle 安全
软件架构设计 C/S与B/S架构的区别
C/S是Client/Server的缩写。服务器通常采用高性能的PC、工作站或小型机,并采用大型数据库系统,如Oracle或SQLServer。
74 0
|
6月前
|
缓存 监控 Java
DP读书:鲲鹏处理器 架构与编程(十四)ACPI与软件架构具体调优
DP读书:鲲鹏处理器 架构与编程(十四)ACPI与软件架构具体调优
152 1
|
6月前
|
安全 前端开发 Linux
DP读书:鲲鹏处理器 架构与编程(十一)鲲鹏生态软件架构 AND 硬件特定软件
DP读书:鲲鹏处理器 架构与编程(十一)鲲鹏生态软件架构 AND 硬件特定软件
81 0
|
6天前
|
缓存 负载均衡 JavaScript
探索微服务架构下的API网关模式
【10月更文挑战第37天】在微服务架构的海洋中,API网关犹如一座灯塔,指引着服务的航向。它不仅是客户端请求的集散地,更是后端微服务的守门人。本文将深入探讨API网关的设计哲学、核心功能以及它在微服务生态中扮演的角色,同时通过实际代码示例,揭示如何实现一个高效、可靠的API网关。
|
4天前
|
Cloud Native 安全 数据安全/隐私保护
云原生架构下的微服务治理与挑战####
随着云计算技术的飞速发展,云原生架构以其高效、灵活、可扩展的特性成为现代企业IT架构的首选。本文聚焦于云原生环境下的微服务治理问题,探讨其在促进业务敏捷性的同时所面临的挑战及应对策略。通过分析微服务拆分、服务间通信、故障隔离与恢复等关键环节,本文旨在为读者提供一个关于如何在云原生环境中有效实施微服务治理的全面视角,助力企业在数字化转型的道路上稳健前行。 ####