在蛋糕模式中,如何在没有直接关系的情况下从客户端替换一些内部实现?

时间:2017-12-06 06:49:47

标签: scala dependency-injection

通过jar共享common-project中的模块代码,我希望在编译时更改内部依赖

trait MyTableNames
trait MyDAO extends MyTableNames
trait ActorService { 
  def send(actorMessage: Any) = println("sending message... will reach some Actor and then from actor to DAO")
}
trait MyActor extends MyDAO
object SaveUserActorMessage

trait MyService extends ActorService {
  def addUser() = send(SaveUserActorMessage) // Not aware of dao just sends a message so service is disconnected from DAO.
}

使用common-project通过它共享jar的不同服务器代码 使用此服务的客户端代码仅创建服务。 问题是我需要注射" MyTableNames的其他一些实现

来自另一个重用上述公共项目的项目:

trait MyOwnTableNames extends MyTableNames 
class MyCustomService extends MyService {
  def someOtherAddUser() = addUser() // How do I tell the DAO which the service does not have a direct reference to, to use MyOwnTableNames, in compile time right now as a client code, I only have reference to MyService.  In addition MyService has no direct relation to MyDAO it's only has a relation to ActorService which has no direct relation to DAO only the end actor which processes the message has a reference to DAO.
}

请注意:这个例子我看起来不漂亮"漂亮"并不是严格的蛋糕模式,我必须这样做,以便我可以将它压缩到几行代码,底线是我的客户端代码引用服务并对服务进行操作,然后服务发送一条消息对于演员,最终演员使用DAO,我的问题是DAO最终试图引用我要替换的MyTableNames。我使用干净的scala代码,没有DI框架,我更喜欢避免暗示,如果可能的话只使用蛋糕模式。

1 个答案:

答案 0 :(得分:0)

您可以依靠Scala的线性化来正确排序特征,并且只需执行

class MyCustomService extends MyService with MyOwnTableNames

这里有一个小警告。如果extend MyTableNamesMyTableNames中使用val的某些值,则由于类初始化排序问题,您可以获得NPE。要解决此问题,您必须使用lazy valdef