首页 > 解决方案 > 从继承的 UI+business-logic/etc 超类迁移到 VIPER

问题描述

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

标签: iosswiftxcodearchitectureviper-architecture

解决方案


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

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


推荐阅读