首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala蛋糕模式&自类型注解

Scala蛋糕模式&自类型注解
EN

Stack Overflow用户
提问于 2016-04-12 12:23:24
回答 2查看 230关注 0票数 2

我试图效仿这个博客的例子。我理解这个例子,但很难实现它。

代码语言:javascript
复制
trait Database {
  // ...
}

trait UserDb {
  this: Database =>
    // ...
}

trait EmailService {
  this: UserDb =>
    // Can only access UserDb methods, cannot touch Database methods
}

这个例子提到,完整的数据库功能将被隐藏在EmailService中--这就是我想要的,但不知道如何正确地实现这些特性。

这就是我试图实现的:

代码语言:javascript
复制
trait Database {
    def find(query: String): String
  }

  trait UserDb {
    this: Database =>
  }

  trait EmailService {
    this: UserDb =>
  }

  trait MongoDatabase extends Database {

  }

  trait MongoUserDb extends UserDb with MongoDatabase{

  }

  class EmailServiceImpl extends EmailService with MongoUserDb {
    override def find(query: String): String = {
      "result"
    }
  }

我觉得很奇怪,因为MongoDatabase特性没有要求find实现,而且当我实现EmailService时,它会提示我使用find实现,尽管提到的示例将对EmailService隐藏起来。我在这里错过了什么?

在阅读了你的评论后,我正试图在一个更接近我真正想要做的事情的例子上实现我想要理解的东西。

第一个片段不会编译,但是第二个片段会.最后,我希望有不同的Repository实现,在它们所依赖的数据库之间切换,我是否接近了下面的一个片段?

代码语言:javascript
复制
trait Database {
    def find(s: String): String
  }

  trait Repository {
    this: Database =>
  }

  class UserRepository extends Repository {
    def database = new MongoDB

    class MongoDB extends Database {
      def find(s: String): String = {
        "res"
      }
    }
  }
代码语言:javascript
复制
trait Repository {
    def database: Database

    trait Database {
      def find(s: String): String
    }
  }

  trait UserRepository extends Repository {
    def database = new MongoDB

    class MongoDB extends Database {
      def find(s: String): String = {
        "res"
      }
    }
  }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-12 13:54:30

如前所述,MongoUserDB不会要求实现,因为它是一个trait。但是,由于EmailServiceImpl extends特性,它需要提供一个实现。您正在寻找的东西可以通过添加另一个抽象来完成。我使用serviceDAO架构来完成它。下面是一个有用的例子,你可以用它来看它是否适合你。

代码语言:javascript
复制
//All future versions of DAO will extend this
trait AbstractDAO{
  def getRecords:String
  def updateRecords(records:String):Unit
}
//One concrete version
trait concreteDAO extends AbstractDAO{
  override def getRecords={"Here are DB records"}
  override def updateRecords(records:String){
    //Actual DB calls and operations
    println("Updated "+records)
  }
}
//Second concrete version
trait concreteDAO1 extends AbstractDAO{
  override def getRecords={"DB Records returned from DAO2"}
  override def updateRecords(records:String){
    //Actual DB calls and operations
    println("Updated via DAO2"+records)
  }
}
//This trait just defines dependencies (in this case an instance of AbstractDAO) and defines operations based over that
trait service{
  this:AbstractDAO =>

  def updateRecordsViaDAO(record:String)={  
  updateRecords(record) 
  }
  def getRecordsViaDAO={
  getRecords
  }
}

//Test Stub
object DI extends App{
  val wiredObject = new service with concreteDAO //injecting concrete DAO to the service and calling methods
  wiredObject.updateRecords("RECORD1")
  println(wiredObject.getRecords)

  val wiredObject1 = new service with concreteDAO1
  wiredObject1.updateRecords("RECORD2")
  println(wiredObject1.getRecords)

}

编辑--

下面是您可能要实现的代码,

代码语言:javascript
复制
    trait Database {
    def find(s: String): String
  }

trait MongoDB extends Database{
  def find(s:String):String = { "Test String" }
}
trait SQLServerDB extends Database{
  def find(s:String):String = { "Test String2" }
}

  trait Repository {
    this: Database =>
  }

  class UserRepository extends Repository with MongoDB{  //  UserRepository is injected with MongoDB here
    find("call MongoDB") //This call will go to the find method in MongoDB trait
  }

  class UserRepository1 extends Repository with SQLServerDB{  //  UserRepository is injected with SQLServerDB here
    find("call SQLServerDB") //This call will go to the find method in SQLServerDB trait
  }
票数 1
EN

Stack Overflow用户

发布于 2016-04-12 13:22:35

DatabaseEnailService是隐藏的,而不是对EmailServiceImpl隐藏的。后者是MongoUserDB的一个子类,显然,它可以访问它。MongoUserDB并不“要求”find实现,因为它是一种特征,而且特性可以有抽象的方法。你仍然应该在那里实现它,即使没有被问到;)

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

https://stackoverflow.com/questions/36573174

复制
相关文章

相似问题

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