洋葱模型
  洋葱模型,是从冰山模型上演变而来的,用来进行层次分析的模型,这是Redux的洋葱模型。

  action从最外层传入,层层传递直至核心后,经过逐层事件触发,再次被分发出来,执行后续操作。

  洋葱模型如今已经广泛应用于各个领域,进行更直观清晰的分层剖析。

The Clean Architecture
  Robert C·Martin是《Clean Code》的作者,我们习惯称他为Uncle Bob。2012年8月13日,他在他的个人Blog上,提出了著名的The Clean Architecture。

  Uncle Bob利用洋葱模型,设计出了The Clean Architecture。

  这种架构的核心在于依赖的规则:源码依赖只能指向内部,内圈的部分,并不知道关于外圈的任何事情,即内部不依赖外部,外部依赖于内部。一般来说,越深入则代表软件级别越高,外部是机制,而内部是策略。

  The Clean Architecture可以给软件带来如下优点:

独立的框架:框架可作为工具,不与系统混在一起;
可测试:没有UI、数据库和Web服务器,数据也可以测试;
UI独立:UI改变更容易,而不会影响业务规则;
数据库独立:业务规则不会和数据库绑定,可以任意切换数据库;
外部代理独立:业务规则可以对外部世界无感知。

  The Clean Architecture也符合领域驱动设计DDD(Domain Driven Design)的思想,代码即方案。DDD是30年来业务软件开发实践经验的结晶。在传统编码模式中,如MVC架构,久而久之会演变为Massive View Controller,即重量级视图控制器,代码也将变为“面条代码”,而后面所有维护的人员,都将陷入耦合和臃肿的代码泥潭中,被代码所蛊惑,无法自拔,重心离要解决的问题越来越远,越走越偏,所以我们更需要使用模型来交流。

  DDD希望,即使不是开发人员,在参与开发的各方,也都能理解软件模型。

  在The Clean Architecture中,将软件分为四个层次,即Entities、Use Cases、Interface Adapters、Frameworks and Drivers。

Entities:Enterprise Business Rules,业务实体;

Use Cases:Application Business Rules,封装和实现业务功能,负责实体的数据处理转换,与数据库和UI无关;
Interface Adapters:接口适配器层,如MVC中的Controllers,MVP中的Presenters;
Frameworks and Drivers:由UI、数据库框架、Web框架等框架和工具构成。

  这种由外向内的结构在改进的MVP架构中,可以表现为View -> Presenter -> Interactor -> Entity,通过这些原则将系统进行分层,将会创建一个可测试的架构体系。

  现在,The Clean Architecture已经成为了开发界的Vans。

  这是2016年,在Android端实践过The Clean Architecture的开发者Dario Miličić的感受。

For me, this has been the best way to develop apps so far. Decoupled code makes it easy to focus your attention on specific issues without a lot of bloatware getting in the way. After all, I think this is a pretty SOLID approach but it does take some time getting used to.

  他说,”对于我来说,这是目前最好的App开发方式。解耦的代码使你更容易将注意力集中在具体问题上,而不是被臃肿的代码所妨碍。我认为这是一个相当可靠的方法,但它需要一段时间去适应。”

MVP-Clean
Android Architecture Blueprints
  The Clean Architecture也是MVP和MVVM都在追求的结构。

  Google官方发布了安卓架构蓝图Android Architecture Blueprints,其中包括MVP + Clean Architecture,在MVP-Clean中,其在传统的MVP上,基于The Clean Architecture,对MVP做了改进。

  MVP起源于20世纪90年代,最初用于C++底层编程,后来被迁移到Java中进而推广,旨在促进自动化单元测试。这是安卓架构蓝图的MVP模型,拥有基本的Model-View-Presenter结构。

  经过Clean改进的安卓架构蓝图MVP,其洋葱模型如下所示:

  它在UI层和存储层添加了Domain,将应用分为三层,如下图所示:

  Domain层负责提供业务逻辑,Domain层和Use Cases上很完美的解决了代码重复的问题,即相同的业务逻辑可以使用Use Case进行复用。

  Domain层的所有代码也可以进行单元测试,也可以扩展使用集成测试,覆盖了一些数据边界后,MVP-Clean架构可以很快地为App提供良好的自动化测试基础。

  通过Domain层的Use Cases,模块的职能一目了然,这是符合DDD的思想的,即使是其他非开发人员参与到项目中,通过Use Cases也能快速清晰地明白每个模块都负责什么样的业务,拥有什么样的功能。

  安卓架构蓝图中的Use Cases提供一个CallBack,包括数据处理成功和处理失败的回调,而Presenter负责根据回调后的结果,处理View的界面显示,Presenter控制器不再单一的控制View和Model,承担过重的业务逻辑,而相同的业务逻辑不能复用。MVP-Clean的Presenter因为有了Use Cases,使得自身更加干净,分离出来的业务逻辑和数据处理等由Use Cases承担,其他业务也能够良好复用。

VIPER
  VIPER架构在2013年由Jeff Gilbert 和 Conrad Stoll 提出。其最初是为了解决测试编写的难题。因为MVC演变的Massive View Controller的结构,使得Controllers越来越大,而将业务逻辑纯粹转移到Presenter也使得Presenter担任同样过重的职责,业务逻辑也不能够很好的复用。VIPER是在一定程度上基于The Clean Architecture的思想后改进而来的方案。

  使用VIPER架构改进,具有以下优点:

易于测试;
代码结构更清晰,符合DDD;
良好的分离关注点;
责任被划分的很清晰:做什么和怎么做。

  VIPER中各个字母分别代表View、Interactor、Presenter、Entity和Router。

  VIPER符合单一职责原则,Interactor负责控制业务逻辑,Presenter负责控制Interactor和View的交互,View负责设计展示UI。Presenter定义行为,而Interactor定义业务逻辑,各个组件连接结构关系可以用如下图表示:

  这张图清晰表达了数据流和依赖流。View负责通知Presenter生命周期,Presenter向Interactor发送数据,请求数据处理,Interactor知道应该如何处理Entity,Presenter负责更新UI,而WireFrame负责跳转。

Interactor
  Interactor层中主要包含各个业务中的Use Case,不包含任何UI相关的操作,这些Use Case通过Callback回调给Presenter状态,success或error,并传递响应的处理结果。

  因为Interactor更纯粹,只涉及数据操作,所以其对TDD(测试驱动开发)更加友好。

Entity
  实体负责定义数据结构,这里的实体并不像其他经典著作中,需要定义更多的数据处理的行为,在VIPER中,数据处理更多是由Interactor来完成,而Entity更加纯粹。

Presenter
  Presenter承担的是When to do的职责。知道什么时候通知Interactor处理数据,知道什么时候通知View更新UI显示,也知道什么时候应该进行跳转。

Router
  Router负责链接各个模块,Presenter知道何时跳转却不知道如何跳转,Router则承担How to do的职责进行各个模块之间的交互转向。

View
  View负责展示界面,但不知自己应该何时展示,Presenter控制View的展示时机,View只负责绘制自身的表现,而将接口暴露出来,让Presenter控制其行为。

总结
  从臭名昭著的MVC,到MVVM,数据绑定对测试和调试并不友好,而代码复用也存在问题,再到今天过重Presenter的MVP,代码复用仍然存在问题,而Presenter的职责也使得开发人员的重心过多沉溺于如何重构代码之上,甚至久而久之就演变为破窗理论,这些结构都不能够很完美的被接受。

  The Clean Architecture是改善测试、代码混乱和代码复用问题的明星理论,众多权威人士都对其拥有极高的认可度,而VIPER在IOS系统已获得了更多的认可,VIPER也是对The Clean Architecture的比较美的诠释。

  VIPER和MVP-Clean还是有非常多的相似点,MVP-Clean更像是VIPE架构,而缺少了一层Router。

  如果对于组件化来说,Router这层是必不可少的,而MVP-Clean解决了代码复用和测试等问题,VIPER则将二者巧妙并自然地衔接起来,安静地谱写着一篇美妙的乐章。(本章节图片来自网络)

05-18 20:47