为了应对 Presenter 过重的问题,我们使用了 Service 来处理某一块具体的业务,我们使用了 Utils、Helper 来处理一些公共的逻辑。哪怕是如此,我们使用 A 框架编写的业务逻辑,到了 B 框架中无法复用。
直到我最近重新接触了 Clean Architectrue,我发现 Presenter 还是可以进一步拆分的。
[h1]整洁的前端架构[/h1]
[h1]Clean Architecture 是由 Robert C. Martin 在 2012 年提出的。最早,我只看到在 Android 应用上的使用,一来 Android 开发使用的是 Java,二来 Android 应用有很重的 View 层。[/h1][h1]与此同时,在 7 年的时间里,由于前后端的分离,UI 层已经从后端的部分消失了。当然了,你也可以说 JSON 也是一种 View(至少它是可见的)。尽管,还存在一定数量的后端渲染 Web 应用,但是新的应用几乎不采用这样的模式。[/h1]但是,在 9012 年的今天,前端应用走向了 MV* 的架构方案,也有了一层很重的 View 层。类似于过去的后端应用,或者后端应用。相似的架构,也可以在前端项目中使用。
[h2]整洁架构[/h2]
Robert C. Martin 总结了六边形架构(即端口与适配器架构):DCI (Data-Context-Interactions,数据-场景-交互)架构、BCI(Boundary Control Entity,Boundary Control Entity)架构等多种架构,归纳出了这些架构的基本特点:
如你所见,作为一个普通(不分前后端)的开发人员,我们关注于业务逻辑的抽离,让业务逻辑独立于框架。
而在前端的实化,则是让前端的业务逻辑,可以独立于框架,只让 UI(即表现层)与框架绑定。一旦,我们更换框架的时候,只需要替换这部分的业务逻辑即可。
为此,基于这个概念 Robert C. Martin 绘制出了整洁架构的架构图:
框架和驱动(Frameworks and Drivers),最外层由各种框架和工具组成,比如 Web 框架、数据库访问工具等。
这个介绍可能有些简单,让我更详细的解释:
实体(Entities),实体用于封装企业范围的业务规则。实体可以是拥有方法的对象,也可以是数据结构和函数的集合。如果没有企业,只是单个应用,那么实体就是应用里的业务对象。这些对象封装了最通用和高层的业务规则,极少会受到外部变化的影响。任何操作层面的改动都不会影响到这一层。
用例(Use Cases),用例是特定于应用的业务逻辑,一般用来完成用户的某个操作。用例协调数据流向或者流出实体层,并且在此过程中通过执行实体的业务规则来达成用例的目标。用例层的改动不会影响到内部的实体层,同时也不会受外层的改动影响,比如数据库、UI 和框架的变动。只有而且应当应用的操作发生变化的时候,用例层的代码才随之修改。
接口适配器(Interface Adapters)。接口适配器层的主要作用是转换数据,数据从最适合内部用例层和实体层的结构转换成适合外层(比如数据持久化框架)的结构。反之,来自于外部服务的数据也会在这层转换为内层需要的结构。
框架和驱动(Frameworks and Drivers)。最外层由各种框架和工具组成,比如 Web 框架、数据库访问工具等。通常在这层不需要写太多代码,大多是一些用来跟内层通信的胶水代码。这一层包含了所有实现细节,把实现细节锁定在这一层能够减少它们的改动对整个系统造成的伤害。
概念就这么扯到这里吧,然后看看相应的实现。
[h2]Clean Architecture 数据流[/h2]
上图中的右侧部分表示的是相应的数据流,数据从 Controller 流出,经过 Use Case(用例)的输入端口,然后通过 Use Case 本身,最后通过 Use Case 输出端口返回给 Presenter。
让我们来看一个较为直观的例子: