Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift-使用泛型实现存储库模式_Swift_Repository Pattern - Fatal编程技术网

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中,您不能使用具有关联类型的协议作为属性/参数等的类型。它应该使您的代码更安全。

完美!!谢谢你的帮助!!