Traditionally baked Scala cake

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.

t4ilmu

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!

Un comentario en “Traditionally baked Scala cake

Deja un comentario