如何在Scala中动态处理自类型注释

时间:2019-08-20 10:06:28

标签: scala inheritance traits self-type

我试图在这里为我的项目使用蛋糕模式。哪个工作正常。

这是一个伪代码。

trait Source {
  def dataset: String
}

trait FileSource extends Source{
  def path: String
  override def dataset: String = // Something here
}

trait DBSource extends Source{
  def ip: String
  override def dataset: String = // Something here
}

trait Processor {
  self: Source =>
  val name: String
  def output: String = transform(self.dataset)
  def transform: (String => String)
}

trait FilterWhilteSpace extends Processor {
  self: Source =>
  override val name: String = "filter_whitespaces"
  override def transform: (String => String) = _.replaceAll("\w", "")
}

trait MaskPassword extends Processor {
  self: Source =>
  override val name: String = "mask_password"
  override def transform: (String => String) = // Something here
}

class FilterWhilteSpaceForFile extends FilterWhilteSpace with FileSource {
  override def path: String = "abcd"
}

class FilterWhilteSpaceForDB extends FilterWhilteSpace with DBSource {
  override def ip: String = "localhost"
}

class MaskPasswordForDB extends FilterWhilteSpace with DBSource {
  override def ip: String = "localhost"
}

问题就在这里,来自本地DBSource的数据被读取了两次(在FilterWhilteSpaceForDB中一次,在MaskPasswordForDB中第二次)。我们可以创建一个可以同时使用的LocalDBSource实例还是可以解决我的Source自类型注释依赖项?

class LocalDBSource extends DBSource {
  override def ip: String = "localhost"
}

1 个答案:

答案 0 :(得分:0)

问题是您的设计从Processor继承了Source,这意味着Processor的每个实例都有自己的Source实例。您需要将Source层次结构与Processor层次结构分开:

trait Source {
  def dataset: String
}

case class FileSource(path: String) extends Source {
  def dataset: String = ???
}

case class DBSource(ip: String) extends Source {
  def dataset: String = ???
}

trait Processor {
  def source: Source  
  val name: String  
  def output: String = transform(source.dataset)  
  def transform: String => String
}

case class FilterWhilteSpace(source: Source) extends Processor {
  val name: String = "filter_whitespaces"
  def transform: String => String = _.replaceAll("\\w", "")
}

case class MaskPassword(source: Source) extends Processor {
  val name: String = "mask_password"
  def transform: String => String = ???
}

val db = DBSource("localhost")
val a = FilterWhilteSpace(db)
val b = MaskPassword(db)

还请注意,实现抽象方法并不是优先考虑的,因此您不需要override关键字。仅在替换现有的具体实现时使用override