A use case of using chain of responsibility pattern to scale strategy
Tags: designpatterns, kotlin
Published: 2020-09-27 18:00:14

---
title: A use case of using chain of responsibility pattern to scale strategy
published: true
date: 2020-09-27 17:50:46 UTC
tags: designpatterns, kotlin
canonical_url: https://le0nidas.gr/2020/09/27/a-use-case-of-using-chain-of-responsibility-pattern-to-scale-strategy/
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/7d5dto7x1cr5gc14bdfy.png
---

Lets say we have a simple application that executes certain actions dictated by an external service.

More particular the external service sends a response that looks like this:
{% gist https://gist.github.com/le0nidas/7ab8bf47cae35fedce9f96c0651c2e0f %}

the supported actions are:
{% gist https://gist.github.com/le0nidas/5e3e3b8897053e2f288ab580dd6efdf3 %}

and there is an executor to help as translate the response to an actual action execution:
{% gist https://gist.github.com/le0nidas/ce975687f159a14eada5d8bc8694e931 %}

This is an implementation of the [Strategy Pattern](https://refactoring.guru/design-patterns/strategy) where every strategy is a certain action allowing us to add as many actions as we want as long as there is a one-to-one relation with what the response sends:

{% gist https://gist.github.com/le0nidas/99e91b07ad88852ea8e77d241ab13a16 %}

#### The problem

One day the external service decides to add a _print error_ action but it does not do it by having a new _action value_. Instead it decides to have an _is error_ flag which must be taken under consideration when the action value is _print_!

So the response is now this:
{% gist https://gist.github.com/le0nidas/9216f59de5a6e367f3c73b192800fefb %}

leading us into having an `if` in the print action’s code
{% gist https://gist.github.com/le0nidas/09bb9fc47620e59a76b58392c463afa6 %}

which defeats the purpose of the strategy pattern and violates the [SRP](https://en.wikipedia.org/wiki/Single-responsibility_principle). Each strategy should do one thing and one thing only. By having an if in the strategy we allow it to implement two actions thus having two reasons to change.

#### Adding a chain

What we need is a way to allow the representation of a single _action value_ from multiple strategies where each one implements a unique action depending on the values of the response.

This is where the [Chain of Responsibility Pattern](https://refactoring.guru/design-patterns/chain-of-responsibility) comes in helping as into having multiple actions tied together, passing the response to each other until one of them can execute it.

There are two ways to implement the pattern depending on the size and state of your project.

##### Using inheritance

If you have a small project with just a few actions and you don’t mind touching many files you can use inheritance and have each action containing the next in the chain:

{% gist https://gist.github.com/le0nidas/68313941ca058f7799c0d83969402538 %}

which can be used as such:

{% gist https://gist.github.com/le0nidas/b5defdca861702d7a12502872dd2a26a %}

##### Using composition

If we do not wish to change any of the existing actions then composition is the only way.

What we need is a way to wrap an existing action in an object that will (a) hold the next action in the chain and (b) decide which action will be executed, the wrapped or the next one:

{% gist https://gist.github.com/le0nidas/5cb0ee65f1b8a3e57688d59dbdbe1d59 %}

Using `ChainAction` results in this:

{% gist https://gist.github.com/le0nidas/941b8ef8d83c4c0160d6e3a7826015c9 %}

This way we can scale the strategy pattern both vertically, one strategy per _action value_, and horizontally, one strategy per _action value_ sub cases.