The cake pattern is a lie

I thought the cake pattern is dead. I thought we all realised what a terrible mistake it was. I thought that I would see it only in old code which I have to maintain occasionally.

I was so happy to see the voting board during Scalar 2018 conference. I was happy because nobody voted for cake pattern as their method of dependency injection.

The whiteboard voting results — Scalar 2018
The whiteboard voting results — Scalar 2018

Unfortunately, I was wrong. I was wrong because a few days ago I read an article written by someone who rediscovered cake pattern and tried to apply it in Swift. The article is almost a year old, so the post is not old enough to ignore it.

I thought I would never again need to explain why the cake pattern is, in fact, an anti-pattern. Let’s do it one more time. Hopefully, for the last time ;)

What is cake pattern?

Let’s look at one of the first blog posts about cake pattern that was also used as an example in the blog post above.

In the end we have code which looks like this:

1
2
3
4
5
6
7
object ApplicationLive {
  val userServiceComponent = new DefaultUserServiceComponent with UserRepositoryJPAComponent {
    val em = Persistence.createEntityManagerFactory("cake.pattern").
                         createEntityManager()
  }
  val userService = userServiceComponent.userService
}

What is wrong with that?

  • I can bypass the user service and call functions from UserRepositoryJPAComponent directly.

  • I can override one of the UserRepositoryComponent functions and change the behaviour of the whole component. For example, I can delete a user instead of persisting the user:

1
2
3
override def userUpdater = new UserUpdater {
  def save(user: User) { em.remove(user) }
}

Not a cake

I was told that this pattern is called a “cake” because it introduces layers in your code. Does it? I can access all functions of my dependencies and all functions of my transitive dependencies. Where are the layers?

It does not look like a cake to me.

It would be more appropriate to call it an “Eintopf pattern.” You take all your classes, mix them, and keep your fingers crossed.

What is so terrible about the Scala implementation of cake pattern?

First of all, a class should not become its dependencies. When you inject dependencies you are supposed to introduce a “has a” relationship between your classes. A dependency is something that a class is supposed to have.

When you use the “cake pattern” your dependency becomes a part of the class. Instead of creating a “has a” relationship, you have a “is a” relationship.

Interface segregation principle

Additionally, the “cake pattern” violates the interface segregation principle. Your class exposes public functions that are not related to its primary responsibility. In fact, such a mix of classes has more than one responsibility, so we may argue whether the single responsibility principle is violated as well.

Open-close principle

The most terrible consequence of cake pattern is the violation of the “open-close principle.” A class can override any public function of its dependencies. I was supposed to depend on those classes, not modify their behavior. The only thing stopping me from doing that is common sense.

Someone may say that the problems with “cake patterns” are caused by its misuse, not be the pattern itself. In my opinion, you cannot use this pattern correctly. It is useless. It does not solve any problems and create a lot of new ones.

You can achieve the goal (passing the dependencies) much easier, use the constructor and pass the dependency as a parameter.

I think that “cake pattern” was another thing created by programmers because they were bored. Something created to feel smarter. Something you can show to others and make them feel stupid for a while (until they learn your new, clever pattern).

It is great that people want to learn something from Scala and use it in their programming languages. Please don’t repeat our mistakes and don’t use that terrible pattern.

The cake is a lie ;)

Did you enjoy reading this article?
Would you like to learn more about software craft in data engineering and MLOps?

Subscribe to the newsletter or add this blog to your RSS reader (does anyone still use them?) to get a notification when I publish a new essay!

Newsletter

Do you enjoy reading my articles?
Subscribe to the newsletter if you don't want to miss the new content, business offers, and free training materials.

Bartosz Mikulski

Bartosz Mikulski

  • Data/MLOps engineer by day
  • DevRel/copywriter by night
  • Python and data engineering trainer
  • Conference speaker
  • Contributed a chapter to the book "97 Things Every Data Engineer Should Know"
  • Twitter: @mikulskibartosz
Newsletter

Do you enjoy reading my articles?
Subscribe to the newsletter if you don't want to miss the new content, business offers, and free training materials.