I have an application which should produce cars and operate with them. Car object creation is a complex process so I need a factory for each type of car. Also I want users to be able to provide their own type of cars and factories which produce them. These car types and factories should be plugged to my application as jars (probably there is a better way than jars but I don't see it).
I've come to an idea of making a common CarFactory which accepts the name of the car ("mercedes", "bmw", "nissan", etc) as an argument. CarFactory has a map where each name is mapped to its own factory class. The code looks something like this (sorry I can't provide a working copy because I'm still evaluating it and don't have a version which compiles without errors)
import scala.collection.mutable.Map
class CarFactory {
var knownCarTypes = Map[String, Class[Factory]]()
def create(carType: String) = knownCarTypes.get(carType) match {
case Some(factoryClass) => Some(factoryClass.getMethod("create").invoke(null).asInstanceOf[Car])
case None => None
}
}
}
The knownCarTypes is mutable because I want user factories to register on this map providing what type of car they are responsible for and what is the name of the factory class. So from a user class it looks like this
class Mercedes extends Car
object MercedesFactory extends Factory {
def register() {
CarFactory.knownCarTypes("mercedes") = getClass
}
def create() = new Mercedes()
}
And here is my question. I don't know how to trigger the register() method of a user factory. Is it possible? Is there a better solution than my approach?
I thought about making common trait for factories, find all loaded classes implementing the trait and trigger method via reflection. But it looks quite complex. I hope some design pattern or OOP trick can be used here. What do you think?
Thanks!