从继承的 UI+business-logic/etc 超类迁移到 VIPER

Migrating to VIPER from inherited UI+business-logic/etc superclass

我决定尝试将我现有的项目架构迁移到 VIPER。 VIPER 似乎很受欢迎,因为它分离模块的方式。但是,我有 2 个从 CustomVC 继承的类似视图控制器。这 2 个视图控制器调用超级方法来设置 UI 和 运行 一些业务逻辑。如果我在 CustomVC 中保留 UI 功能,我是否应该将业务逻辑移至类似的 CustomPresenter superclass?我应该将常见的导航行为移动到类似的 CustomInteractor class 吗?好的,我这样做了,然后呢:2 个视图控制器模块是否继承自 CustomPresenter and/or CustomInteractor classes?在答案中,考虑到 VIPER 架构目标,请指导我在这种情况下可以接受什么。 谢谢。

  • https://TheSwiftDev.com/the-ultimate-viper-architecture-tutorial 中所述,它以 purest/original 形式教授 VIPER(没有近年来出现的一些切线),VIPER 完全是关于 [= 的区域(或层) 38=] 通过应用程序域数据结构(其中许多是 VIPER 首字母缩写词中更简单的 E 实体)和每个区域作为其域间发布的应用程序域消息 API 在区域间相互通信的功能。实际上,VIPER 的每个 V I P R 区域都向其他区域展示了一种立面:
  1. 同时将 UI/Apple-think/Android-think 隔离在 V 视图区内,因为此类 UI 问题不纯粹是应用程序域;
  2. 同时将 sensor/datastore/networking/Apple-think/Android-think quarantined/divorced 保持在 I 交互区内,因为此类 data-acquisition/data-exchange 问题不纯粹是应用程序域;
  3. 同时将 navigation/Apple-think/Android-think/iOS-think/MacOS-think quarantined/divorced 保持在 R 路由器区域内,因为此类导航问题不纯粹是应用程序域(例如,弹出模式对话框或非金属对话框或附加到滚动日志 window-窗格的末尾?取决于哪个 OS/platform) 考虑到所有这些:
  • 以 UI 为中心的 CustomVC 及其以 UI 为中心的子类进入 VIPER 中的 V 视图区域。 V 视图区域周边的立面将基于区域间应用程序域实体的消息转换为区域内 UI Apple 思维框架或 Android 思维框架的概念、构造和方法调用。
  • 业务逻辑(根据定义显然是纯粹的应用程序域)进入 VIPER 的 P 演示区。 P presenter zone中是否有CustomPresenter superclass direct analogue,或者P presenter zone是否根据P presenter zone自身需求进行不同的建模,是设计师的选择,兼顾当地口味。我的观点是,那里没有严格的规则可以热心遵守;并不是每一种在 V view 区组织代码的方式都是在 P presenter 区组织代码的方式。
  • 导航进入 VIPER 中的 R 路由器区域。 R 路由器区域周边的外观将基于区域间应用程序域实体的消息转换为区域内导航概念、构造和 Apple 思维框架或 Android 思维框架的方法调用。例如,iOS 上的导航可能与 MacOS 上的导航和同一应用程序的 Android 端口上的导航不同,因为弹出模式对话框与半永久非模式对话框相比 window-pane 在某些平台上可能存在于您的应用程序设计的 UI 中,但在其他平台上不存在。特别是对于导航,在处理当前仅 iOS 的应用程序时,请考虑片刻,是否可以在桌面 MacOS 应用程序或 Android 端口上以不同的方式完成应用程序。如果您当前的应用程序架构类似于 Massive View Controller,您可能会将导航与 UI 混合在一起(这是大量 Massive View Controller 反模式的一个症状);然后,您将需要仔细梳理 UI 之外的导航,以便导航和 UI 得到 quarantined/divorced 彼此分开。 R router zone 中是否有 CustomRouter superclass direct analogue 或 R router zone 是否因 R router zone 自身的需要而对其进行不同的建模是设计者的选择,同时考虑到当地的口味。我的观点是,那里没有严格的规则可以热心遵守;并不是每一种在 V view zone 中组织代码的方式都是在 R router zone 中组织代码的方式。
  • 传感器、数据存储和网络进入 VIPER 的交互区。 I interactor zone 外围的外观将基于区域间应用程序域实体的消息转换为 intrazone sensor/datastore/networking 概念、构造和方法调用 Apple-think 框架或 Android-think 框架或第 3 方libraries/frameworks。特别是在这个区域中,稍微考虑一下 quarantine/divorce 是否如此干净和完美,以至于您可以将非应用程序域基础设施 X 换成不同的非应用程序域基础设施 Y,例如换出数据库而不是 Apple Core Data,也许你的应用程序已经过时了。 I interactor zone 中是否有 CustomInteractor 超类直接模拟,或者 I interactor zone 是否根据 I interactor zone 自身的需要对其进行不同的建模是设计者的选择,同时考虑到当地的品味。我的观点是,那里没有严格的规则可以热心遵守;并不是每一种在 V view 区组织代码的方式都是在 I interactor 区组织代码的方式。
  • 纯应用领域的通用语interzone是E实体区的部分简单实体,但现在越来越多的也是反应式功能编程精简版效果事件订阅和流程,例如RxSwift 或领域。 RxSwift 如果 lingua-franca interzone 编程语言是 Swift (或其 Android 类似物 RxKotlin 或 RxJava 或 ZIO+CatsEffect 如果在 Scala 中如果 lingua-franca interzone 编程语言是其中之一这 3 种语言)可以由设计者选择作为官方应用程序域的纯度。 Realm 比较混乱,因为它做了很多 RxSwift 做的事情,但是当 Realm 处于区域间通用语时,现在数据存储交互区域中的 Realm 没有被隔离在它适当的数据存储交互隔间中,所以现在 Realm 不能将来可以很容易地换成一些更好的数据存储技术。这个故事的主要寓意是:明智地公开设计和选择包含纯应用程序域通用语实体、消息传递、哲学、依赖关系等区域间的内容,因为随着应用程序向新操作系统的发展,这是您需要保持不变的部分,新平台,新基础设施。

所以不,一旦所有 UI、业务逻辑和 sensor/datastore/networking data-acquisition/exchange 完全彼此分离,视图控制器将不再直接执行任何操作使用 CustomPresenter 或 CustomInteractor 或 CustomRouter,尤其是不继承它们。 CustomUI 及其子类与 CustomPresenter 及其子类(如果有)与 CustomInteractor 及其子类(如果有)与 CustomRouter 及其子类(如果有)之间的所有交互都将通过纯应用程序域消息传递(或效果-event subscription) interzone via app-domain lightweight entities—i.e., indirect interaction through V view zone's façade and/or I interactor zone's façade 与 P presenter zone.