Есть два способа определить метод для двух разных классов, наследующих один и тот же признак в Scala.
sealed trait Z { def minus: String }
case class A() extends Z { def minus = "a" }
case class B() extends Z { def minus = "b" }
Альтернатива следующая:
sealed trait Z { def minus: String = this match {
case A() => "a"
case B() => "b"
}
case class A() extends Z
case class B() extends Z
Первый метод повторяет имя метода, тогда как второй метод повторяет имя класса.
Я думаю, что лучше всего использовать первый метод, потому что коды разделены. Однако я обнаружил, что часто использую второй для сложных методов, так что добавление дополнительных аргументов может быть сделано очень легко, например, так:
sealed trait Z {
def minus(word: Boolean = false): String = this match {
case A() => if(word) "ant" else "a"
case B() => if(word) "boat" else "b"
}
case class A() extends Z
case class B() extends Z
Каковы другие различия между этими практиками? Есть ли какие-то баги, которые меня ждут, если я выберу второй подход?
РЕДАКТИРОВАТЬ: я цитировал принцип открытости/закрытости, но иногда мне нужно изменить не только вывод функций в зависимости от новых классов case, но и ввод из-за рефакторинга кода. Есть ли шаблон лучше, чем первый? Если я хочу добавить ранее упомянутую функциональность в первом примере, это приведет к уродливому коду, в котором ввод повторяется:
sealed trait Z { def minus(word: Boolean): String ; def minus = minus(false) }
case class A() extends Z { def minus(word: Boolean) = if(word) "ant" else "a" }
case class B() extends Z { def minus(word: Boolean) = if(word) "boat" else "b" }