MVVM 架构|探讨 Singleton pattern 单例模式

说起单例模式,大部分 Swift 工程师都不建议使用它。如果你在 Reddit 搜索关于单例 vs 依赖注入设计模式的讨论,90% 的人都让你远离单例。使用依赖注入而不是单例模式的理由是:更易于测试、解耦和灵活,更加便于团队成员理解模块间的关系、并行开发不同模块、轻松替换实现进行单元测试。

以上理由都很有道理,特别是在企业中需要团队协作的时候。但如果你和我一样是独立开发,事情又变得稍微不一样。

独立开发与单例模式

在独立开发的场景中,我发现单例模式也许是个不错的选择。因此,从最近的 Postix 项目开始,我开始尝试优先使用单例模式而不是依赖注入。

以下是我目前位置发现的优势:

  • 大部分时候,有更好的性能。依赖注入模式下,很容易因为错误的设计导致实例被反复创建和销毁,这会带来性能上的开销,而单例模式不会被销毁重建,因此不存在这个问题。
  • 单例使用更加简单。从 iOS17 开始,苹果推出了最新的 Observation + 环境注入模式,但是在稍微复杂的项目中,很容易造成在 App 文件中有大量的实例需要注入。
  • 单例可以在 View 视图之外访问。使用环境注入的实例,只能在 View 组件中通过 @Environment() 访问,这导致在 ViewModel 和 Manager 组件中只能通过 View 中传递访问,非常不方便。单例模式没有这个问题。
  • 单例更适合 SwiftData。基于和上一点相同的原因,SwiftData 的官方推荐方式是使用 @Environment 访问 modelContainer 实例——但这只适用于 View 组件。通过使用 DataModel.shared.container单例,让在非 View 组件之外访问 modelContainer 变成可能。

不适合单例模式的场景

在 Postix 中,不同的 Page 之间切换时会有动画过渡 —— 这是我不希望的。

0:00
/0:02