Тип-класс или добавить метод через неявный? - PullRequest
0 голосов
/ 23 июня 2018

Я проектирую что-то вроде Service s и столкнулся с проблемой дизайна.Вот что у меня сейчас есть:

trait Service {
  def isFailed(): Boolean
  def start(): Unit
  def stop(): Unit
}

И чтобы сгруппировать Service s, связанных друг с другом в группу (чтобы перезапустить / восстановить группу, а не другие сервисы), я создал следующееобъект пакета:

package object app {
  type FaultTolerantServiceGroup = Seq[Service]
  object FaultTolerantServiceGroup{
    def apply(svcs: Service*): FaultTolerantServiceGroup = Seq(svcs: _*)
  }

  class FaultTolerantServiceGroupOps(val F: FaultTolerantServiceGroup){
    def hasFailed: Boolean = F.forall(_.failed())
  }

  trait FaultTolerantServiceGroupSyntax{
    implicit def serviceGroup2Ops(F: FaultTolerantServiceGroup) = new FaultTolerantServiceGroupOps(F)
  }
}

Поэтому я добавил метод hasFailed к FaultTolerantServiceGroup.Но я не уверен в этом решении.

Было бы лучше определить класс типов, скажем

trait Watchable[T]{
     def hasFailed(t: T): Boolean
}

И неявно предоставить экземпляр Watchable[FaultTolerantServiceGroup]?

1 Ответ

0 голосов
/ 23 июня 2018

По моему скромному мнению, неявные функции становятся намного труднее читать потом. Даже при чтении моего старого кода иногда бывает непонятно, когда у объектов есть методы, которые появляются на ровном месте.

Мне еще предстоит увидеть случай, когда о последствиях легче рассуждать, чем о декларативных функциях:

val failedGroup : FaultTolerantServiceGroup => Boolean = _.forall(_.failed())

Результирующий код не выглядит ни лучше, ни хуже, чем подразумевается, но, по крайней мере, очевидно, откуда исходит функциональность:

val group : FaultTolerantServiceGroup = ???

//no implicit
val failed = failedGroup(group)

//with implicits : how does a Seq have a hasFailed method?
val failed = group.hasFailed

Явные функции также облегчают чтение Iterable функций:

val groups : Iterable[FaultTolerantServiceGroup] = ???

val failedGroups = groups filter failedGroup
...