I want my client code to look something like this:
val config:Config = new MyConfig("c:/etc/myConfig.txt") println(config.param1) println(config.param2) println(config.param3)
It means that:
- Config Interface Defines Configuration Fields
- MyConfig is a Config implementation - all the necessary wiring is the creation of the desired implementation.
- Data is loaded lazily - this should happen when the field is first set (in this case config.param1)
So, I want the client code to be friendly, with support for interchangeable implementations, with statically typed fields hiding lazy loading. I also want it to be as simple as possible for creating alternative implementations, so Config should guide you a bit.
I am not happy with what I have come up with so far:
trait Config { lazy val param1:String = resolveParam1 lazy val param2:String = resolveParam2 lazy val param3:Int = resolveParam3 protected def resolveParam1:String protected def resolveParam2:String protected def resolveParam3:Int } class MyConfig(fileName:String) extends Config { lazy val data:Map[String, Any] = readConfig // some dummy impl here, should read from a file protected def readConfig:Map[String,Any] = Map[String, Any]("p1" -> "abc", "p2" -> "defgh", "p3" -> 43) protected def resolveParam1:String = data.get("p1").get.asInstanceOf[String] protected def resolveParam2:String = data.get("p2").get.asInstanceOf[String] protected def resolveParam3:Int = data.get("p3").get.asInstanceOf[Int] }
I am sure there are better solutions where you can help :)
I especially don't like the fact that MyConfig defines an intermediate container with some arbitrary keys, and since this is Map [String, Any ], I need to specify the values.
source share