首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >协议中基于assosiatedType的依赖反转

协议中基于assosiatedType的依赖反转
EN

Stack Overflow用户
提问于 2021-11-22 15:37:11
回答 1查看 145关注 0票数 1

我很难尝试实现依赖反转。环顾四周,找到一篇精彩的文章迅捷式擦除。我不知道如何才能在我的处境中获得优势。以下是我正在努力实现的目标。

网络协议

代码语言:javascript
复制
protocol Networkable {
    associatedtype Response: Decodable

    func request(handler: @escaping((Result<Response, Error>) -> ()))
}

Networkable协议的具体实现

代码语言:javascript
复制
final class Networker<Response: Decodable>: Networkable {
    private let session: URLSession
    private let url: URL

    init(session: URLSession, url: URL) {
        self.session = session
        self.url = url
    }

    func request(handler: @escaping ((Result<Response, Error>) -> ())) {
        session.dataTask(with: url) { data, response, error in
            handler(.success(try! JSONDecoder().decode(Response.self, from: data!)))
        }
    }
}

依赖于ViewModel协议的Networkable

代码语言:javascript
复制
class ViewModel {
    let networker: Networkable
    // Error-> Protocol 'Networkable' can only be used as a generic constraint because it has Self or associated type requirements

    init(netwrorker: Networkable) {
        self.networker = netwrorker
    }

    func execute() {
        networker.request { _ in
            print("Responsed")
        }
    }
}

用法:

代码语言:javascript
复制
class View {
    let viewModel: ViewModel

    init() {
        let networker = Networker<ResponseModel>(session: .shared, url: URL(string: "SOME URL")!)
        self.viewModel = ViewModel(netwrorker: networker)
    }

    func load() {
        viewModel.execute()
    }
}

struct ResponseModel: Decodable {}

问题:

  1. 这是实现依赖反转的正确方法吗?
  2. 如何在网络类上实现通用行为,并且仍然可以进行测试?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-23 16:38:23

您的ViewModel类格式不正确:

代码语言:javascript
复制
class ViewModel<T: Decodable> {
    let networker: Networker<T>
    …
}

否则,您可能会创建一个类型擦除的AnyNetworkable具体类型,您可以将其用于:

代码语言:javascript
复制
class ViewModel<T: Decodable> {
    let networker: AnyNetworkable<T>
    …
}

或者您可以采用更通用的方法,如:

代码语言:javascript
复制
class ViewModel<R, T: Networkable> where T.Response == R {
     let networker: T
}

显然,同样的情况也反映在您的View类型上,您还需要对特定的具体类型的ViewModel进行通用或专门化。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70068400

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档