
                            
                            因收到Google相关通知，网站将会择期关闭。相关通知内容
                            
                            
                            11  解决技术改造困局的钥匙：整洁架构
                            有个“大师与太空”的梗是这样说的：大师通常都站得很高很高、高瞻远瞩，站得有多高呢？都是站在太空里的，所以很多人追随大师容易缺氧。因此，我们学习大师的理论，就要脚踏实地、踏踏实实地将其落地到项目应用中，重新落地到“地面”上，这些理论才是有用的，落地 DDD 同样是这样。

如何落地 DDD 呢？除了在项目中实践 DDD，领域建模，按照 DDD 的思想设计开发以外，还需要一个支持 DDD 与微服务的技术中台。在 DDD 实现过程中，这个技术中台应当能够封装那些烦琐的聚合操作、仓库与工厂的设计，以及相关的各种技术。有了这个技术中台的支持，开发团队就可以把更多的精力放到对用户业务的理解，对业务痛点的理解，快速开发用户满意的功能并快速交付，而不再受限于那些烦琐的技术细节，从而降本增效。这样，不仅编写代码减少了，技术门槛降低了，还使得日后的变更更加容易，技术更迭也更加方便。

那么，如何设计这样一个技术中台呢？首先应当从现有系统的设计痛点开始分析。

底层技术的更迭

这些年，随着互联网、大数据、人工智能等新技术层出不穷，整个 IT 产业的技术架构也在快速迭代。


过去，我们说“架构是软件系统中最稳定不变的部分”；
而现在，我们说“好的架构源于不停地演变”。


因此，如今的架构设计需要思考如何让底层的架构更易于技术更迭、易于架构调整，以应对不断演进的新技术、新框架，从而获得行业竞争的技术优势。

然而，在实际项目中，特别是很多运行了七八年、十多年的老项目，要做一次技术升级，那叫一个费劲，就像脱一层皮那么痛苦。为什么技术升级那么费劲呢？究其原因，是在系统设计开发时，大量的业务代码依赖于底层的技术框架，形成了耦合。

譬如，过去采用 hibernate 进行数据持久化，每个模块的 DAO 都要继承自 HibernateDaoSupport。这样，所有的 DAO 都与 Hibernate 形成了一种依赖。当系统架构由 Hibernate2 升级成 Hibernate3，甚至升级成 MyBatis，就不是改换一个 jar 包那么简单了。

技术框架一换，底层的类、接口、包名都变了，就意味着上层的所有模块的 DAO 都需要改，改完了还要测试。这样的技术升级成本极高，风险极大，需要我们认真去思考解决方案。



总之，老系统技术架构升级成本极高的根源，在于业务代码与底层技术框架的耦合。因此，解决思路就是对它们进行解耦。如何解耦呢？就是在上层业务代码与底层技术框架之间建立“接口层”。





如何在业务代码与底层框架之间建立“接口层”呢？如上图所示，上层业务代码在进行持久化时，各个模块的 DAO 不再去调用底层框架，而是对接口层的 DaoSupport 进行调用。DaoSupport 接口是我们自己设计的，它应当满足上层的所有业务需求，比如各种类型的 insert、 update、delete、get、load、find，并让这个接口保持稳定。上层业务代码的设计实现都依赖于 DaoSupport 接口，只要它稳定了，上层业务代码就稳定了。

接着，在 DaoSupport 接口的基础上编写实现类，由实现类去调用底层技术框架，实现真正的持久化。


起初使用 Hibernate2 作为底层框架，所以为 Hibernate2 编写了一个实现类。
当 Hibernate2 升级成 Hibernate3 时，为 Hibernate3 写一个实现类。
当底层框架要升级成MyBatis 时，再为 MyBatis 写一个实现类。


这样的设计，当系统进行技术架构升级时，其影响就不再扩展到业务层代码，而仅仅局限于调整接口层的实现类，技术升级的成本将得到大幅度的降低。

整洁架构的设计



通过前面对问题的分析与接口层的设计，可以得出一个非常重要的结论：如何既能轻松地实现技术架构演化，又能保证开发团队的快速交付呢，关键的思路是将业务代码与技术框架解耦。如上图所示，在系统分层时，基于领域驱动的设计，将业务代码都整合在业务领域层中去实现。这里的业务领域层包括了 BUS 层中的 Service，以及与它们相关的业务实体与值对象。

业务领域层设计的实质，就是将领域模型通过贫血模型与充血模型的设计，最终落实到对代码的设计。在此基础上，通过分层将业务领域层与其他各个层次的技术框架进行解耦，这就是“整洁架构”的核心设计思路。



整洁架构（The Clean Architecture）是 Robot C. Martin 在《架构整洁之道》中提出来的架构设计思想。如上图所示，它以圆环的形式把系统分成了几个不同的层次，因此又称为“洋葱头架构（The Onion Architecture）”。在整洁架构的中心是业务实体（黄色部分）与业务应用（红色部分），业务实体就是那些核心业务逻辑，而业务应用就是面向用户的那些服务（Service）。它们合起来组成了业务领域层，也就是通过领域模型形成的业务代码的实现。

整洁架构的最外层是各种技术框架，包括：


与用户 UI 的交互；
客户端与服务器的网络交互；
与硬件设备和数据库的交互；
与其他外部系统的交互。


整洁架构的精华在于其中间的适配器层，它通过适配器将核心的业务代码，与外围的技术框架进行解耦。因此，如何设计适配层，让业务代码与技术框架解耦，让业务开发团队与技术架构团队各自独立地工作，成了整洁架构落地的核心。



整洁架构设计的细化图，图片来自《软件架构编年史》

如图，进一步细化整洁架构，将其划分为 2 个部分：主动适配器与被动适配器。


主动适配器，又称为“北向适配器”，就是由前端用户以不同的形式发起业务请求，然后交由应用层去接收请求，交由领域层去处理业务。用户可以用浏览器、客户端、移动 App、微信端、物联网专用设备等各种不同形式发起请求。然而，通过北向适配器，最后以同样的形式调用应用层。
被动适配器，又称为“南向适配器”，就是在业务领域层完成各种业务处理以后，以某种形式持久化存储最终的结果数据。最终的数据可以存储到关系型数据库、NoSQL 数据库、NewSQL 数据库、Redis 缓存中，或者以消息队列的形式发送给其他应用系统。但不论采用什么形式，业务领域层只有一套，但持久化存储可以有各种不同形式。南向适配器将业务逻辑与存储技术解耦。


整洁架构的落地



按照整洁架构的思想如何落地架构设计呢？如上图所示，在这个架构中，将适配器层通过数据接入层、数据访问层与接口层等几个部分的设计，实现与业务的解耦。

首先，用户可以用浏览器、客户端、移动 App、微信端、物联网专用设备等不同的前端形式，多渠道地接入到系统中，不同的渠道的接入形式是不同的。通过数据接入层进行解耦，然后以同样的方式去调用上层业务代码，就能将前端的多渠道接入，与后台的业务逻辑实现了解耦。这样，前端不管怎么变，有多少种渠道形式，后台业务只需要编写一套，维护成本将大幅度降低。

接着，通过数据访问层将业务逻辑与数据库解耦。前面说了，在未来三五年时间里，我们又将经历一轮大数据转型。转型成大数据以后，数据存储的设计可能不再仅限于关系型数据库与 3NF的思路设计，而是通过 JSON、增加冗余、设计宽表等设计思路，将其存储到 NoSQL 数据库中，设计思想将发生巨大的转变。但无论怎么转变，都只是存储形式的转变，不变的是业务逻辑层中的业务实体。因此，通过数据访问层的解耦，今后系统向大数据转型的时候，业务逻辑层不需要做任何修改，只需要重新编写数据访问层的实现，就可以转型成大数据技术。转型成本将大大降低，转型将更加容易。

最后，就是底层的技术架构。现在我们谈架构，越来越多地是在谈架构演化，也就是底层技术架构要不断地随着市场和技术的更迭而更迭。但是，话虽如此，很多系统的技术架构更迭，是一个非常痛苦的过程。为什么呢？究其原因，是软件在设计时，将太多业务代码与底层框架耦合，底层框架一旦变更，就会导致大量业务代码的变更，各个业务模块的都要更迭，导致架构调整的成本巨大、风险高昂。

既然这里的问题是耦合，解决的思路就是解耦。在平台建设的过程中，除了通过技术选型将各种技术整合到系统中以外，还应通过封装，在其上建立接口层。通过接口层的封装，封装许多技术的实现，以更加简便的接口开放给上层的业务开发人员。这样，既可以降低业务开发的技术门槛，让他们更加专注于业务，提高开发速度，又让业务代码与技术框架解耦。有了这种解耦，就使得未来可以用更低的成本技术更迭，加速技术架构演进，跟上这个快速变化的时代。

总结

整洁架构的中心是基于 DDD 的业务实现，即那些通过领域模型指导设计与开发的 Service、Entity 与 Value Object。整洁架构的最外层是各种硬件、设备与技术框架。而整洁架构最核心的思想，是通过适配器层，将业务实现与技术框架解耦，这也是 DDD 落地到架构设计的最佳实践。

因此，支持 DDD 与微服务的技术中台，就是基于整洁架构的思想，将 DDD 底层的那些烦琐的聚合操作、仓库与工厂的设计，与微服务的技术框架，以及整洁架构中的适配器，统统封装在技术中台中。有了这个技术中台，就能让上层的业务开发人员，更加轻松地运用 DDD 的思想，更加快捷地更迭与交付用户需求，从而在激烈的市场竞争中获得优势。

下一讲将进一步讲解这样的技术中台是如何设计的。

                        
                        
                            