The cake falls

(I’m running out of snappy cake-related puns here, but I’m saving “the cake is a lie” for a special occasion.)

So after thinking about my interface / implementation dilemma for a while (recap: I’m aiming to separate out the implementations of hexmap from their interface), I decided to approach it from a Java vantage point and see how I’d implement the same thing in Java.  The immediately obvious thing that jumped out at me was that the specific problem I was dealing with was sort of a classic application of plain old vanilla inheritance from an abstract class.  Having drunk deeply from the well of Spring over my last several years of Java experience, plain old inheritance had begun to seem in some ways like a quaint relic of a bygone era (having been replaced in many cases by service composition).

At any rate, a quick bit of refactoring to get rid of traits altogether got me back to a fairly sane codebase, where I’ve got this:

abstract class HexMap (h: Int, w: Int) {
  val height = h
  val width = w
  // This is where the magic happens
  def data(addr: Address): HexData
}
abstract class HexData(a: Address) {
  def toJson(): JObject = JObject(List()) // default: empty JSON object
}

case class ColorData(a: Address, color: String) extends HexData (a) {
  override def toJson(): JObject = {
    ("color" -> color)  // json {"color": "foo"} via JsonDSL
  }
}
class RandomColorMap(h: Int, w: Int) extends HexMap(h, w) {
  private val store: Map[Address, ColorData] = createRandomMap()
  def data(addr: Address): ColorData = {
    store(addr)
  }
  // Note, we're able to access width and height here
  private def createRandomMap(): Map[Address, ColorData] = {
    val pairs = for (x <- 0 until width; y <- 0 until height) yield {
      val addr = Address(x, y)
      addr -> ColorData(addr, randomColor())
    }
    pairs toMap
  }
}

I will come back and revisit this later; I’m certain there’s a way traits could be useful in this code, but for now I’m leaving them aside and pressing on with more actual program functionality.

As far as that is concerned, my next worry is persisting the hexmap the user sees in their Scalatra session, so that when the user asks for a random path from the server, he or she gets one within the actual bounds of the actual map he or she is seeing. The Scalatra session docs make this look fairly straightforward; we’ll see.

Advertisements