In this blog post, we will be discussing factory pattern use cases and implementations in Akka to create actors.
Factory of Actors
As we already know, in order to create an actor, we need to instantiate an object of akka.actor.Props
class with all the configurations needed to create an actor. It is this configuration object that is utilized by actorOf()
factory method available in akka.actor.ActorSystem
and akka.actor.ActorContext
to create an actor and return a reference to the same as akka.actor.ActorRef
.
As we can see, actors can't be instantiated directly. They are instead created via Props
configuration object (There in fact is a great stackoverflow post that discusses the reasoning behind such an implementation, if you're interested.) while Akka already provides a factory pattern implementation out of the box that accepts these configuration objects to create actors.
Factory of Props
The recommended practice to create actors however advocates to provide factory methods to define Props
configurations on the companion object of each Actor itself. This avoid the problems related to closing over parent actor's state while creation of a child actor.
Here, the factory that knows how to create actors is supplied a Props
configuration object from a factory that knows how to create a props configuration object so as to create an actor.
What if you're not sure up until at runtime, which actor to instantiate?
Let's discuss a small Translation App to understand this use cases and involved factory pattern implementation.
![actors](https://shivamkapoor.com/content/images/2019/06/translator-Page-1.jpg)
What we have here are three actors definitions. TranslatorSupervisor
, EnglishTranslator
and DutchTranslator
.
Based on Locale
, the TranslatorSupervisor
is expected to create one of the translator actors. Evidently, this can only be known at runtime.
![translators](https://shivamkapoor.com/content/images/2019/06/translator-Page-2.jpg)
This runtime decision can of course be abstracted in a factory as we know by it's definition.
Here, we can see that the TranslatorPropsFactory
variant of factory of props implementation returns an appropriate Props
configuration object based on current Locale
, thusly making it possible to decide which actors to create at runtime.
If you still however wish to keep the factory of individual props close to respective actor definitions, as per recommended practices already discussed above, the TranslatorPropsFactory
and pertaining translator actors companion object implementation would look something like this:
Conclusions
1. Akka already provides a factory implementation out of the box to create actors. This implementation however accepts a Props
configuration object to create actors i.e., an actor can only be created via a Props
configuration object.
2. Since actorOf
factory implementations comes already implemented, runtime creation of actors can be achieved via factory of props.
You can find a working implementation of the Translation app discussed above here on github.