gpt4 book ai didi

swift - 具有关联类型和工厂模式的协议(protocol)?

转载 作者:可可西里 更新时间:2023-11-01 01:56:10 25 4
gpt4 key购买 nike

我的数据访问层由一个通用的Repository 协议(protocol)组成

protocol Repository {
associatedtype T
func getAll() -> Promise<[T]>
}

及其具体实现:

class FirebaseRepository<T: Model>: Repository {
func getAll() -> Promise<[T]> {
fatalError()
}
}

基本上,Repository可以是RestRepositoryFirebaseRepositoryPlistRepositry等,Repository是业务逻辑使用的:

/// My business logic
class ModelService<T: Repository> {
private let repository: T

public init(repository: T) {
self.repository = repository
}
}

当我尝试将工厂模式应用于存储库时,问题就来了。这是我首先进来的:

/// Returns a concrete Repository implementation
class RepositoryFactory {
func makeRepository<T: Model>(type: T.Type) -> Repository {
return FirebaseRepository<T>()
}
}

这肯定会导致编译器错误:

Protocol 'Repository' can only be used as a generic constraint because it has Self or associated type requirements

我想到的唯一可行的选择是:

func makeRepository<T: Model>(type: T.Type, U: Repository) -> U {
return FirebaseRepository<T>() as! U
}

但如您所知,强制可选解包在生产代码中是 Not Acceptable 。

如何使具有关联类型的协议(protocol)与工厂设计模式一起工作?

最佳答案

您可以使用类型删除。这是一个例子:

protocol CustomProtocol {
associatedtype AssociatedType
func foo(argument: AssociatedType)
func bar() -> AssociatedType
}

如果你想直接使用CustomProtocol,你会收到你的错误:

let array = [CustomProtocol]()

Protocol 'CustomProtocol' can only be used as a generic constraint because it has Self or associated type requirements

因此您可以像 Swift 对它们的序列所做的那样使用相同的技巧:

public struct AnyCustomProtocol<T>: CustomProtocol {
func bar() -> T {
fatalError("Needs implementation")
}
func foo(argument: T) {

}
}

let array = [AnyCustomProtocol<Any>]() // works fine

在这种情况下,您的问题解决方案看起来像这样:

    class Promise<T> {

}

protocol Model {

}

protocol Repository {
associatedtype T
func getAll() -> Promise<[T]>
}

class FirebaseRepository<T: Model>: AnyRepository<T> {
override func getAll() -> Promise<[T]> {
fatalError()
}
}

class AnyRepository<T>: Repository {
func getAll() -> Promise<[T]> {
fatalError()
}
}


class RepositoryFactory {
func makeRepository<T: Model>(type: T.Type) -> AnyRepository<T> {
return FirebaseRepository<T>()
}
}

__

要进一步阅读,您可以查看 thisOfficial docs on Generics

关于swift - 具有关联类型和工厂模式的协议(protocol)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53249303/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com