Swift-使用泛型实现存储库模式
我一直在做一些关于存储库模式的研究,因为我想在我正在从事的新项目中使用它。但是,我在使用泛型时遇到了一些问题 我一直以本指南为例 这很好地解释了这一点。然而,指南遗漏了一个重要的细节。。它使用依赖性注入和泛型 在示例代码中,他展示了这一点Swift-使用泛型实现存储库模式,swift,repository-pattern,Swift,Repository Pattern,我一直在做一些关于存储库模式的研究,因为我想在我正在从事的新项目中使用它。但是,我在使用泛型时遇到了一些问题 我一直以本指南为例 这很好地解释了这一点。然而,指南遗漏了一个重要的细节。。它使用依赖性注入和泛型 在示例代码中,他展示了这一点 class ArticleFeedViewModel { let articleRepo:ArticleRepository init( articleRepo:ArticleRepository = WebArticleRepository() )
class ArticleFeedViewModel {
let articleRepo:ArticleRepository
init( articleRepo:ArticleRepository = WebArticleRepository() ) {
self.articleRepo = articleRepo
}
}
如果您不使用泛型,那么这很好。但一旦您将ArticleRepository更改为Repository示例。。。所以从
protocol ArticleRepository {
func getAll() -> [Article]
func get( identifier:Int ) -> Article?
func create( article:Article ) -> Bool
func update( article:Article ) -> Bool
func delete( article:Article ) -> Bool
}
对此
protocol Repository {
associatedtype T
func getAll() -> [T]
func get( identifier:Int ) -> T?
func create( a:T ) -> Bool
func update( a:T ) -> Bool
func delete( a:T ) -> Bool
}
我再也不能让依赖注射起作用了。因此,如果我尝试重新创建上面所示的模型
class WebArticleRepository: Repository {
func getAll() -> [Article] {
return [Article()]
}
func get(identifier: Int) -> Article? {
return Article()
}
func create(a: Article) -> Bool {
return true
}
func update(a: Article) -> Bool {
return false
}
func delete(a: Article) -> Bool {
return true
}
}
class ArticleFeedViewModel {
let articleRepo:Repository
init( articleRepo:Repository = WebArticleRepository() ) {
self.articleRepo = articleRepo
}
}
这已经不起作用了。我现在得到一个错误,说
协议“存储库”只能用作一般约束,因为
它具有自身或关联的类型要求
你知道我做错了什么吗。似乎添加associatedType会导致此停止工作。我真的很想让这个功能发挥作用,因为我希望能够根据应用程序的当前状态注入本地或基于web的存储库模式
任何帮助都会受到极大的欢迎您还需要将所有其他内容变得通用:
protocol Repository {
associatedtype RepositoryType
func getAll() -> [RepositoryType]
func get( identifier:Int ) -> RepositoryType?
func create( a:RepositoryType ) -> Bool
func update( a:RepositoryType ) -> Bool
func delete( a:RepositoryType ) -> Bool
}
class WebArticle { }
class WebArticleRepository: Repository {
typealias RepositoryType = WebArticle
func getAll() -> [WebArticle] {
return [WebArticle()]
}
func get(identifier: Int) -> WebArticle? {
return WebArticle()
}
func create(a: WebArticle) -> Bool {
return true
}
func update(a: WebArticle) -> Bool {
return false
}
func delete(a: WebArticle) -> Bool {
return true
}
}
class ArticleFeedViewModel<T : Repository> {
let articleRepo: T
init( articleRepo: T) {
self.articleRepo = articleRepo
}
}
// you cannot have the optional parameter in the init, instead, you can extract the following line to a method
ArticleFeedViewModel(articleRepo: WebArticleRepository())
协议存储库{
关联类型RepositoryType
func getAll()->[RepositoryType]
func get(标识符:Int)->RepositoryType?
func create(a:RepositoryType)->Bool
func更新(a:RepositoryType)->Bool
func delete(a:RepositoryType)->Bool
}
类WebArticle{}
类WebArticleRepository:Repository{
typealias RepositoryType=WebArticle
func getAll()->[WebArticle]{
返回[WebArticle()]
}
func get(标识符:Int)->WebArticle{
返回WebArticle()
}
func create(a:WebArticle)->Bool{
返回真值
}
func更新(a:WebArticle)->Bool{
返回错误
}
func delete(a:WebArticle)->Bool{
返回真值
}
}
类ArticleFeedViewModel{
让我们来看看
初始(articleRepo:T){
self.articleRepo=articleRepo
}
}
//在init中不能有可选参数,相反,可以将以下行提取到方法
ArticleFeedViewModel(articleRepo:WebArticleRepository())
在Swift中,您不能使用具有关联类型的协议作为属性/参数等的类型。它应该使您的代码更安全。完美!!谢谢你的帮助!!