正文
Clean-Architectrue架构图
摘自The Clean Architecture
(https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)
分层思想
上图显示了整洁架构的示意图,其中每个同心圆层代表了软件开发中的不同层,越是靠近中心,同心圆层所代表的东西越抽象。可以这么理解,内部的圆层定义的是规则,外部的圆层定义的是实现机制。
整洁架构试图聚合这样几个特点:
-
框架无关,即架构设计不依赖任何一个既有的开发框架,因此理论上可以使用任何框架来实践整洁架构。
-
业务规则的可测性,即可以方便地测试业务逻辑所涉及的代码,不依赖UI、数据库或者 Web 服务等外部元素。
-
功能实现不依赖 UI 的实现细节,比如同样一套后台系统可以用在 Web 应用,也可以用在 App 原生应用。
-
业务逻辑不依赖数据库的实现细节,可以把数据保存在 Oracle、SQL server、Mongo、Mysql 等任意一种数据库中,同时业务逻辑不需要做任何改变。
-
总结起来就是:业务逻辑对外界实现完全没有依赖,任你外面的实现细节如何改变,核心业务逻辑不需修改。
依赖规则
为了实现上面所讲的特点,只需要遵循依赖规则:只允许外部圆层的代码依赖内部圆层的代码,反之则禁止。换言之,内部同心圆层的代码不知道任何外部同心圆层的代码,比如内层的代码一律禁止引用外层声明的函数、类、变量或其他任何元素。
其实上面的规则还隐含着另一个规则:当有数据传递时,只允许外部圆层接受内部圆层的数据格式,反之则不允许。这也是为避免外部的代码逻辑影响内部的代码逻辑(思考一下为什么)。
整洁架构中的术语介绍
-
实体(Entities)层:主要封装企业范围的业务规则,可以认为是代码要实现的核心业务规则,比如电商里涉及到的购物规则。
-
用例(Use Cases)层:主要封装特定于应用的业务规则,比如电商里普通用户购物与管理员管理货物信息,二者所涉及的用例是不一样的。
-
接口适配(Interface Adapters)层:主要包含各种适配器,负责把从实体层和用例层流出来的数据转换成为更外面一层需要的数据格式(比如转换成为适合数据库保存的格式,或者适合 Web 页面展示的格式)。
-
框架与驱动(Frameworks and Drivers)层:这是最外面的一层,是很多工具(或库)的具体实现细节所在层,比如 Web 框架(考虑一个应用可以做成网页版应用,也可以做成单机版应用)、数据库工具包(考虑各种 ORM 的实现,以及各种数据库的驱动依赖包实现)等。
值得说明的是,虽然整洁架构的示意图中只显示了四层结构,但是可以根据业务规模调节层数,也就是说层数不是关键,关键在于分层思想以及依赖规则。
一个关键点——控制反转
依赖规则里规定“只能外层的代码依赖内层代码”,但是在实际代码中势必会出现这种场景:外层的代码调用内层的代码处理数据,数据经过内层代码作用后需要再反传给外层进行其他处理(比如把处理好的数据保存到数据库,保存到数据库的逻辑在外层)。Clean-Architectrue架构图的右下角给出了一种示意,那么如何让这种场景满足依赖规则呢?答案就是控制反转。