MVC的关键是给我们提出了一个原则:怎么对项目进行合理的关注点分离。Model负责业务领域,controller负责对model进行工作安排,而view则负责门面,怎么让外面的人看的满意。
但是MVC只提供了3层,对于再复杂的应用没有提供足够的组织和关注点分离的原则了,这个时候我们来看下Clean Architecture。
本文为系列文章的第七篇,完成的目录请查看Clean Architecture
The Clean Architecture
Clean Architecture是Uncle Bob Martin在2012年写的,文章中收集了一系列类似的架构,它们的共同点如下:
-
框架无关(Independent of Frameworks)
这些架构没有依赖于一些已经存在的库或软件,带来的好处是:你无需要去硬满足框架给你制定的条条框框,框架本身只是你的一个工具。
-
可测性(Testable)
业务逻辑可以在没有UI,Database,Web Server 或任何外部元素的情况下测试
-
UI无关(Independent of UI)
UI可以在不改变业务逻辑的情况下快速改变,譬如可以将Web UI替换为Console UI
-
数据库无关(Independent of Database)
我们可以替换后端的存储,从mysql到nosql,不影响我们的业务逻辑
-
无外部依赖(Independent of any external agency)
我们核心的业务逻辑对任何的外部依赖都是无感的,或者说我们的业务逻辑只关心领域逻辑。
框架无关(Independent of Frameworks)
PHP社区现在异常的活跃,各种框架层出不穷,Laravel,Silex等,没准昨天还流行的框架,今天就又出了一个更好的,因此如果你将自己的核心逻辑绑定到某个框架上,那么sorry,框架的升级或者替换,你都需要重写你代码了。
可测性(Testable)
测试的编写跟项目大小无关,不能因为项目大而没有时间去写测试用例,也不能因为项目小太简单不去写测试。测试的编写随着项目的不断重构,它的意义会越来越大,因为我们无法保证代码的编写都是一个人,每次的修改都不会改变原来的功能,这个时候测试用例的作用就凸显出来了,每次修改后,都运行case,保证功能的正确性。
数据库无关(Independent of Database)
数据库无关这点在实际工作中可能不是那么重要,因为每个公司都有自己的存储服务,像我们公司后端持久化存储一直是mysql,或者说存储一直是兼容mysql的sql的,关注存储的适配有专门的团队来做,应用这边看到的一直就是mysql。
但是对于开源软件就不是了,我们需要考虑后端存储的变化,需要能满足各个存储。
无外部依赖(Independent of any external agency)
通过composer我们能很快利用社区的开源库,加速我们应用的开发。但是社区活跃带来的问题是,库的出现快,消失的也快。因此我们在开发中,必须要考虑尽量减少对外部库的依赖,一个方法就是之前介绍的适配器模式。
The Onion Architecture
The Onion Architecture最初是由Jeffrey Palermo提出的,是clean architecture的一个变种。
Palermo将软件的分层比喻成洋葱一样的一层一层:从里面往外一层一层的看,每一层都依赖着内层,但是内层却不依赖于外层,通过一个图来认识下:
传统的应用开发中,应用是以数据库为中心设计的,先确定数据库中每个表的结构,然后应用在基于数据进行设计,如果将其剥离出来,整个系统变的支零破碎。
在Onion Architecture中,应用核心是领域模型,完全和数据库解耦,在整个应用中,数据库只是应用需要的一个组件,我们可以完全替换存储,而不影响整个应用逻辑。
领域模型和领域服务
在Onion Architecture中最核心是领域模型层,该层只包含了领域模型,彼此之间进行交互,不涉及领域之外的逻辑,在领域模型之外是领域服务层,包括了工厂(factories)、仓库(repositories)和其他的一些使用领域模型的服务。
领域模型和领域服务合起来构成了整个应用的核心。应用其他所有层都依赖于核心的领域模型和领域服务。
应用服务层
应用层包含了具体的应用的实现,以MVC为例子:应用层就是controller。应用层应该只负责启动我们的应用,不会再被其他层依赖了。应用层只是用来调用我们内存的个领域服务和领域模型,我们能很方便的替换应用层。
我们可能感慨是使用的Symfony,但是后来要转换为Laravel,如果我们核心设计的好,应该是很方便就能切换过去的。
用户接口
通过用户接口UI,我们将我们应用的核心领域对象展现给用户,由于没有其他层依赖于UI了,因此我们无压力的替换模型语言,使用新的js框架什么的,so _
基础设施
该层也是在最外层,主要是给领域层提供数据的存取,通过他来获取数据,数据可能是数据库里,也可能是网络,或者其他地方,该层使我们整个应用的数据提供方。
基础层依赖于领域服务和领域层,因为领域层和领域模型给出了基础层必须实现的契约(contract),基础层来实现这些接口给领域层提供数据。
本节只是对clean architecture做了一个概述,下面会对clean architecture的5个特点展开具体的讨论。
这是The Clean Architecture in PHP的第七篇,你的鼓励是我继续写下去的动力,期待我们共同进步。