【问题标题】:SwiftUI and MVVM design patternSwiftUI 和 MVVM 设计模式
【发布时间】:2019-08-17 17:20:18
【问题描述】:

我正在尝试了解如何使用 MVVM 设计模式和 SwiftUI 来实现以下目标。

我希望只有 1 个网络操作队列实例(使用 OperationQueue),其中任何需要发送任何网络请求的视图模型但我听说创建单例不是首选,我应该传递网络队列对象在需要的地方。

因此,如果我在场景委托中创建网络操作队列的实例并将它们传递到 ContentView 初始化程序并将其存储在一个对象中,然后传递到创建的视图中。

根据我的理解,这似乎不是好的 MVVM 设计实践,View 应该只拥有 ViewModel?

实现这一目标的最佳方法是什么?

编辑:多考虑一下,我可以通过它的构造函数将它传递到视图中,然后在构造函数中我可以创建视图模型并直接传递它,因此视图不拥有任何东西。

但我仍然需要一个单例,那么如何将单例作为依赖注入传递而不是全局使用它?

谢谢

【问题讨论】:

标签: ios swift design-patterns mvvm swiftui


【解决方案1】:

我们不应该仅仅为了获取全局变量的简单方法而创建单例,但这并不意味着我们永远不应该使用它们。

在您的情况下,如果我理解正确的话,您基本上是在创建一个可供整个应用程序使用的服务。您可以 A) 创建一个具有所需网络功能的可重用类(并在需要的任何地方实例化)或 B) 创建一个包含单例实例的类,该类可以在任何地方轻松访问。

例如,如果您需要为所有调用者保留一些共同的状态,或者如果您需要维护等待队列,那么单例将是更好的选择。

选项 A

class NetworkService {

    init() {
        // init
    }

    // Your properties and methods
    func someFunction() {}
}

在 ViewModel 中的使用:

let networkService = NetworkService()
networkService.someFunction()

选项 B

class NetworkService {
    static let shared = NetworkService()
    private let queue : Any?

    // Your properties and methods
    func someFunction() {}
}

用法:

NetworkService.shared.someFunction()

不管怎样,这仍然是 MVVM。数据与任何特定视图无关,也与特定模型无关;它只是您可以在任何需要它的 ViewModel 中调用的服务。

【讨论】:

  • 谢谢你,这证实了我的想法 - 是选项 2!
  • 在视图模型中使用NetworkService.shared.someFunction() 会使您的视图模型无法测试。不要使用单例。
  • 嗨@Darko,感谢您的意见。您能否详细说明为什么它无法测试?很想了解原因。谢谢!
  • 因为视图模型会尝试在单元测试中调用单例。这意味着进行真正的网络通话。您想要的是将网络服务作为协议注入。因此,为网络服务创建一个协议,并将网络服务的一个实例注入到视图模型 init 中。在单元测试中,您创建一个遵循相同协议的 MockNetworkService 并注入该协议。您的 Mock 当然不会进行真正的网络调用。这就是松耦合和依赖注入的基本原理。
猜你喜欢
  • 1970-01-01
  • 2014-08-31
  • 1970-01-01
  • 2020-04-24
  • 1970-01-01
  • 2011-06-25
  • 1970-01-01
  • 2012-03-29
  • 2013-03-04
相关资源
最近更新 更多