Suppose I want to create 2 clients that extends a base trait
trait Clients {
def emitter: Emitter
def push(data: str): Unit
}
case class RestClient(config: RestConfig) extends Clients {
def emitter: RestEmitter = ??? // where RestEmitter extends Emitter
def push(data: str): Unit = ???
}
case class KafkaClient(config: KafkaConfig) extends Clients {
def emitter: KafkaEmitter = ??? // where KafkaEmitter extends Emitter
def push(data: str): Unit = ???
}
next I have a singleton that returns the caller an instance of the client. Reason I have this singleton is I dont want callers to create multiple instances of the client
object ClientFactory {
private var client: Option[Emitter] = None // I hate using this mutable state
def getClient: Emitter = {
if (client.isDefined) client.get
else throw RuntimeException("client has not init yet")
}
def init(config: Config) = {
config match {
case rCfg: RestConfig =>
client = RestClient(rCfg)
case kCfg: KafkaConfig =>
client = KafkaClient(kCfg)
}
}
}
A caller would use it as
ClientFactory.init(some_config)
ClientFactory.getClient.push(some_data)
Is there any better way of defining this singleton ClientFactory
, so that I dont have to use this mutable variable