VIPER 是一个轻量级的 软件架构 框架,用于 Swift。
整洁架构 是 Robert C. Martin 于 2012 年设计的一种软件架构模式,旨在推广软件设计的 SOLID 原则。VIPER 的概念是一种受整洁架构启发的 iOS 架构模式,最初由 Mutual Mobile 的开发者提出,并通过他们在 objc.io 上的文章而普及。此框架是上述架构原则的 Swift 实现,使您能够为 iOS、macOS 和 tvOS 构建 VIPER 应用。
秉承 Swift 的风格,VIPER 仅以 Swift 包的形式提供。
将以下内容添加到您的 Package.swift
的 dependencies:
数组中
.package(url: "git@github.com:thomverbeek/VIPER.git", from: "0.5.1"),
在您的项目或工作区中,选择 File ▸ Swift Packages ▸ Add Package Dependency…
以添加 https://github.com/thomverbeek/VIPER
作为包依赖项。
此软件包捆绑了 viper-tools
,一个命令行实用程序。
cd
进入此 Swift 包,并运行以下命令$ swift run viper-tools
generate
子命令生成新的 VIPER 模块。例如,要在桌面上为 macOS 生成名为 “MyModule” 的模块$ swift run viper-tools generate MyModule ~/Desktop/ --os macOS --verbose
--exclude-directory
标志生成不带目录的文件。当您将 VIPER 模块分组到项目中的 Swift 包中时,这非常有用。VIPER 将应用程序逻辑划分为不同的责任组件
View
: UI 逻辑,包括任何用户交互;Interactor
: 业务逻辑,类似于应用程序用例;Presenter
: 呈现逻辑,将业务逻辑映射到视图逻辑;Entity
: 实体逻辑,由存储库和服务维护;Router
: 导航逻辑,与视图处于同一领域。从概念上讲,这五个组件构成一个集合 Module
,与 iOS 应用程序中的单个屏幕同义。每个模块的生命周期由 View
直观地表示,View
间接持有对所有组件的引用。这些组件以协调的顺序相互通信,一旦 View
关闭,生命周期结束。最终的代码清晰、可测试、模块化,并且可以与大型团队一起扩展。
VIPER 宣言并非没有缺陷
Router
的角色没有明确定义,导致难以实现。VIPER 旨在通过使 Router
能够组装 VIPER 模块来解决组装器问题。但是这种安排危及了单一职责原则,因为它已经承担了导航的责任。说到导航,Router
在 VIPER 模块之间传递信息的任务也仍然不明朗。Entity
组件很可能是在 VIPER 缩写词中“任何其他东西”的代名词。它缺乏明确的定义,暗示实体层专门供 Interactor
与之交互。一种空灵的解释认为,简单的实体构成了 VIPER 模块各个层之间所有消息传递的基础。在实践中,Entity
很可能包含 Interactor
可能参与的任何存储库或服务。由于不清楚这些存储库或服务来自何处,VIPER 定义可能需要包含依赖注入。在野外有许多实现试图满足这些要求以及其他一些要求,但它们仍然有些不足。VIPER 作为框架可能难以掌握和完全实现,而 Swift 语言由于其语言怪癖和类型安全限制,又增加了更多障碍。大多数框架只是尝试将原始 Objective-C 示例代码翻译成 Swift,迫使开发人员手动连接组件并在类型之间强制转换。这些挫败感最终导致了此框架的开发,以便将 VIPER 带给大众。
此框架利用泛型、静态作用域和函数式响应式编程原则的组合,将 VIPER 提炼成一个不到 300 行代码的单个文件,包括注释。查看 VIPER.swift
。
Router
中提取组装责任,并将其授予 Module
。Entities
来定义 Interactor
的依赖项,并使用 Builder
为 Router
提供依赖注入。Interactor
指定为状态的持有者,并使用 PresenterModel 在业务逻辑和呈现逻辑层之间进行通信。Presenter 使用 PresenterModel 来查询其状态并更新其 ViewModel,而无需暴露 Entity 层。此设置拥抱了诸如使用 Combine 的响应式编程等现代实践。所有这一切都产生了一个简单而精密的 VIPER 架构实现。因此,它简称为 “VIPER”。
它是一个单向的 viper,正如徽标上所描绘的那样。
Yan Heere 感谢他以 Swift 风格快速设计了令人愉悦的衔尾蛇徽标。
OneSadCookie 感谢他多次关于 VIPER 和衔尾蛇名称的午餐讨论。