从继承的 UI+业务逻辑/等超类迁移到 VIPER

问题描述

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

解决方法

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

所以不,一旦所有 UI、业务逻辑和传感器/数据存储/网络数据采集/交换完全相互分离,视图控制器将不再与 CustomPresenter 或 CustomInteractor 或CustomRouter,尤其是没有从它们继承。 CustomUI 及其子类、CustomPresenter 及其子类(如果有)、CustomInteractor 及其子类(如果有)、CustomRouter 及其子类(如果有)之间的所有交互都将通过纯应用程序域消息传递(或效果事件订阅)interzone通过应用域轻量级实体,即通过 V 视图区域的外观和/或 I 交互器区域的外观与 P 演示者区域进行间接交互。