I've developed a lot of code in Java and dabbled in Groovy and Haskell which has now led me to Scala.
I feel relatively comfortable with the functional side of Scala, but I'm finding myself a bit shaky on object oriented design in Scala, because it feels a bit different to Java, in particular due to traits/mix-ins.
I aim to write code that is as testable as possible, which in my Java development has always translated into focus on
- Immutability where possible
- Prefer injection of state by constructors
- ALWAYS go for composition instead of inheritance (heavily influenced by, and likely an over-reaction to this post on SO)
Now I'm trying to land on my feet in this new Scala territory, and I'm having a hard time figuring out what approach I should go for here, in particular whether I should start using inheritance for some purposes.
Programming Scala (Wampler and Payne; O'Reilly, 2nd Edition) has a section with considerations ("Good Object-Oriented Design: A Digression"), and I've read a number of posts on SO, but I haven't seen explicit mentions of the design consideration of testability. The book offers this advice on using inheritance:
- An abstract base class or trait is subclassed one level by concrete classes, including case classes.
- Concrete classes are never subclassed, except for two cases:
- Classes that mix in other behaviors defined in traits (...)
- Test-only versions to promote automated unit teting.
- When subclassing seems like the right approach, consider partitioning behaviors into traits and mix in those traits instead.
- Never split logical state across parent-child type boundaries.
Some digging on SO also suggests that sometimes mix-ins are preferable to composition.
So in essence I have two questions:
Are there common cases where it would be better, even considering testability, to use inheritance?
Do mix-ins offer good ways to enhance the testability of my code?