object oriented analysis - Scala put method in trait or in case class? -
there 2 ways of defining method 2 different classes inheriting same trait in scala.
sealed trait z { def minus: string } case class a() extends z { def minus = "a" } case class b() extends z { def minus = "b" } the alternative following:
sealed trait z { def minus: string = match { case a() => "a" case b() => "b" } case class a() extends z case class b() extends z the first method repeats method name, whereas second method repeats class name. think first method best use because codes separated. however, found myself using second 1 complicated methods, adding additional arguments can done example this:
sealed trait z { def minus(word: boolean = false): string = 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 what other differences between practices? there bugs waiting me if choose second approach?
edit: quoted open/closed principle, sometimes, need modify not output of functions depending on new case classes, input because of code refractoring. there better pattern first one? if want add previous mentionned functionality in first example, yield ugly code input repeated:
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" }
i choose first one.
why ? merely keep open/closed principle.
indeed, if want add subclass, let's case class c, you'll have modify supertrait/superclass insert new condition... ugly
your scenario has similar in java template/strategy pattern against conditional.
update:
in last scenario, can't avoid "duplication" of input. indeed, parameter type in scala isn't inferable.
it still better have cohesive methods blending whole inside 1 method presenting many parameters method union expects.
just imagine ten conditions in supertrait method. if change inadvertently behavior of 1 of each? each change risked , supertrait unit tests should run each time modify ...
moreover changing inadvertently input parameter (not behavior) not "dangerous" @ all. why? because compiler tell parameter/parameter type isn't relevant more. , if want change , same every subclasses...ask ide, loves refactoring things in 1 click.
as link explains:
why open-closed principle matters:
no unit testing required.
no need understand sourcecode important , huge class.
since drawing code moved concrete subclasses, it's reduced risk affect old functionallity when new functionality added.
update 2:
here sample avoiding inputs duplication fitting expectation:
sealed trait z { def minus(word: boolean): string = if(word) whenword else whennotword def whenword: string def whennotword: string } case class a() extends z { def whenword = "ant"; def whennotword = "a"} thanks type inference :)
Comments
Post a Comment