[英]Protocols with associated type and factory pattern?
我的數據訪問層由通用Repository
協議組成
protocol Repository {
associatedtype T
func getAll() -> Promise<[T]>
}
及其具體實現:
class FirebaseRepository<T: Model>: Repository {
func getAll() -> Promise<[T]> {
fatalError()
}
}
基本上, Repository
可以是RestRepository
、 FirebaseRepository
、 PlistRepositry
等。 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
}
但如您所知,生產代碼中不接受強制可選解包。
如何使具有關聯類型的協議與工廠設計模式一起工作?
您可以使用類型擦除。 下面是一個例子:
protocol CustomProtocol {
associatedtype AssociatedType
func foo(argument: AssociatedType)
func bar() -> AssociatedType
}
如果你想直接使用CustomProtocol
,你會收到你的錯誤:
let array = [CustomProtocol]()
協議“CustomProtocol”只能用作通用約束,因為它具有 Self 或關聯類型要求
所以你可以用同樣的技巧,就像 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>()
}
}
__
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.