Разоблачить частный случай класса Scala - PullRequest
0 голосов
/ 24 апреля 2020

У меня есть ситуация, когда кодовому пути даны некоторые Path, которые он использует для запроса к базе данных. Бывает, что иногда некоторым из этих путей нужно go через службу перевода, чтобы сопоставить их с обновленными Path с до запроса. По сути, упрощенный поток - это

val paths: List[Path] = getPaths()

val pathTranslationOpt: Option[Map[Path, Path]] = getTranslationOpt()

paths.foreach { p =>
  val pathToUse = 
    pathTranslationOpt
      .flatMap(_.get(p))
      .getOrElse(p)

  someFunctionsUsingThePath(pathToUse)
}

. Меня беспокоит ситуация, когда кто-то случайно вызывает someFunctionsUsingThePath с p, забывая выполнить перевод. Это может быть замечено во время компиляции, слегка изменяя код

val paths: List[Path] = getPaths()
 // let NewPath be a case class defined in the scope of the translate function as 
// case class NewPath(path: Path)
val pathTranslationOpt: Option[Map[Path, NewPath]] = getTranslationOpt()

paths.foreach { p =>
  // Have the function explicitely take a NewPath so the user cannot forget to call the translation service
  someFunctionsUsingThePath(
    newPathOpt = 
      pathTranslationOpt.flatMap(_.get(p)),
    fallbackPath = p
  )
}

Это кажется мне более безопасным, так как забывание вызова службы перевода приводит к ошибке времени компиляции. Тем не менее, небрежный пользователь может просто передать Some(NewPath(p)) вызову функции, победив цель.

Есть ли способ сделать NewPath таким, чтобы его можно было свободно использовать, но только сконструировать из перевода?

1 Ответ

2 голосов
/ 24 апреля 2020

Попробуйте:

case class NewPath private(path: Path)

object NewPath {
  def apply(path: Path): NewPath =
    NewPath(
      pathTranslationOpt.flatMap(_.get(path)).getOrElse(path)
    )
}

def someFunctionsUsingThePath(path: NewPath) = ???

paths.foreach { p =>
  someFunctionsUsingThePath(NewPath(p))
}

NewPath можно создать только с помощью метода apply в объекте-компаньоне, который преобразует путь при необходимости, но в противном случае оставляет его без изменений.

...