Как внедрение зависимостей должно обрабатывать транзитивные зависимости? - PullRequest
1 голос
/ 20 февраля 2020

Я думаю о том, как структурировать некоторый код в Scala, который имеет признаки, зависящие от других признаков, и мне интересно, является ли внедрение зависимостей с самопечатанием лучшим подходом для этого.

В приведенном ниже примере кода черта Adder ссылается на функциональность черты HasLogger посредством самописи. Класс Doubler расширяется Adder и, следовательно, также требует HasLogger. Класс Foo также требует HasLogger для Adder, но также использует его напрямую.

Если бы мы изменили один из классов так, чтобы он больше не использовал Adder, как бы мы узнали можем ли мы также удалить HasLogger? (В этом случае это легко проверить, но со многими зависимостями это не будет очевидно). Также, если бы было много классов, подобных Doubler, был бы повторяющийся код, поскольку каждый из них должен был бы расширять как HasLogger, так и Adder. Это ситуация, когда Adder следует расширять HasLogger вместо использования самонабора?

trait HasLogger {
  val logger: Logger = new Logger

  class Logger {
    def log(msg: String): Unit = println(msg)
  }
}

trait Adder {
  this: HasLogger =>
  def add(x: Int, y: Int): Int = {
    logger.log(s"Adding $x and $y")
    x + y
  }
}

class Doubler extends HasLogger with Adder {
  def double(x: Int): Int = add(x, x)
}

class Foo extends HasLogger with Adder {
  def logInt(x: Int): Unit = logger.log(x.toString)

  def add3(x: Int, y: Int, z: Int): Int = add(add(x, y), z)
}
...