Concise way to enforce implementation of factory in Scala

Viewed 201

Let us assume we have a trait T. What is the best way to achieve the following:

  • Everybody who writes an implementation of T should be forced to provide a possibility that allows a parameter-free initialization of T, i.e., we probably have to enforce the implementation of a configurable factory.
  • All logic/data that only depends on the actual initialization parameters (of a certain implementation A of T) should be handled/stored centrally, but should be available in both the factory and A.

The most simple/concise way I see to achieve this (approximately) would be to add a trait for a factory and link T to this factory:

trait T {
  val factory: TFactory
}
trait TFactory {
  def build(): T
  val description: String   // example for logic/data that only depend on the parameters
}

// example implementation:
class A(val factory: AFactory, paramA: Int, paramB: Int, paramC: Int) extends T

class AFactory(paramA: Int, paramB: Int, paramC: Int) extends TFactory {
  def build = new A(this, paramA, paramB, paramC)
  val description = f"$paramA $paramB $paramC"
}

Obviously this does not really "enforce" the implementation of a factory (as long as there is an alternative implementation available) and obviously it is possible to generate instantiations of A which link to a "wrong" TFactory. What I also don't like about this approach is the repetition of the initialization parameters. I often create yet another class AParams which again wraps all parameters (for instance to facilitate adding new parameters). Thus, I end up with three classes, which imho is a lot of boilerplate for this simple problem.

My question is whether there is a (maybe completely) different approach, which achieves the same primary goals but is more concise?

2 Answers
Related