Today, we’ll talk about cooking. We’ll bake a pretty cake. Have Igone too far with Masterchef? Nope. Today, we’ll talk about cake-pattern.
Cake-pattern is a depencency injection design pattern. It allows us to establish dependencies among components. It is common that services or repositories that must be implemented require others. In these cases, cake pattern will help to establish this connection.
The basis of this design pattern is to compose our system from smaller components. That is, we are composing our cake from small slices. Besides, we are establishing connections among those slices.
For that, we’ll first create some abstract components with traits, from which real components will inherit. This way, we can be sure that all the components we implement have the same functionality.
trait MyComponent { def service: MyService trait MyService { def saySomething: String } }
In this example, we have a component with a service that contains the method saySomething.
Now, we’ll implement the service. To do so, we have to call a repository. Therefore, we must inject the dependency to that repository. But, as we do not know yet which type of repository it will be (a database implemented in mysql, an in-memory data structure…), we’ll have a dependency to an abstract repository. Further on, when we create our system (aka, our cake), we’ll decide on the type of repository we will work in.
trait MyRepository { def repo: MyRepoService { def getRandomExpression: String } }
In order to create dependencies, we will use self types. Self types will be used in this case to inject a dependency to another component. However, they can also be used to make reference to inner or outer classes. Don’t worry. We’ll take a look at those concepts later. For the time being, we’ll use these self types to put restrictions to the mixin with a component given that, for a component to inherit from this trait, it will also have to inherit from the traits in its self type. Let’s see how it looks:
trait MyComponentImpl extends MyComponent{ self: MyRepository => def service = new MyServiceImpl trait MyServiceImpl extends MyService { def saySomething: String = repo.getRandomExpression() } }
Finally, we can create our system by using the implemented version of our component, and the implemented version of a repository. Once the system (the cake) has been created, we can make use of its functionality:
val system = new MyComponentImpl with MyRepositoryImpl println(system.service.saySomething)
Et voila! Bon appetit!
[…] allow us to perform the dependency injection in our application.A few weeks ago we saw how to use Cake Pattern. If you didn’t like that that much, pay attention […]
Me gustaMe gusta