Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A simple builder pattern in Scala

I'm implementing a very simple builder pattern for a map-like container:

trait KeyValueContainer[K,V] {
  private var props: Map[K, V] = new HashMap[K, V]
  private var built = false

  /**
   * Adds a key/value pair
   */
  def +=(key: K, value: V): KeyValueContainer[K,V] = {
    if (built)
      throw new BuilderException

    props = props + (key -> value)
    this
  }

  def build = {
    built = true
    this
  }
}

class MyContainer extends KeyValueContainer[String, Double]

When using the above "+=" or "build" methods on a "new MyContainer()", the result is of type KeyValueContainer[String,Double] in both occassions...

I'm pretty sure I read somewhere in the past that this could be somehow made to return the actual MyContainer sub-type instead. Would you use method return type covariance for this (Java-style), or is there a more type-safe / better solution to this in your view?

Thanks!

like image 637
Nikolaos Avatar asked Jul 21 '26 12:07

Nikolaos


1 Answers

And here it is:

http://docs.scala-lang.org/overviews/core/architecture-of-scala-collections.html

The pattern relies on how implicits are resolved at compile-time. Basically, if there are multiple implicits in scope, the compiler picks the most specific one (in your case, the subtype builder you need).

In this way, you can do generic implementations in a base-class and get subclass builders through an implicit argument.

Here is an example of what I did for one of my own projects:

https://gist.github.com/hejfelix/8a0270855d498d7981f9

Another important aspect of this pattern is explicit self-typing: http://www.scala-lang.org/node/124

like image 102
Felix Avatar answered Jul 24 '26 04:07

Felix