Photo by Karine Avetisyan on Unsplash

Pass a request along a chain of handlers

Swift — Problems Catalogue #15

Alex Ilovan
Published in
3 min readNov 22, 2022

--

Problem Definition:

Consider the following scenario. You have to implement a Witch App (taking into account that Halloween was not so long ago). It has a full set of social community features for witches with all the bells and whistles including a summoning portal, a rent a broom and sharing their latest potions.

For this article, we are going to focus only on creating the potion recipes (*only the gist of how to create ingredients that depend on each other for the potion). We need a way to create a request and pass it along to different handlers.

If the handler is compatible with the request then it performs some logic, if not, it passes the request to the next handler.

In our case, it’s a possible solution to create potion recipes that have multiple dependent ingredients on each other. The cool thing about it is that multiple objects can handle the request without coupling to the concrete class of the receivers.

Problem Solution:

Solution —Chain of Responsibility — it’s a behavioral design pattern that allows you to pass a request along a chain of handlers until one of them handles it.

Real-World Usage:

1. Ingredients Enum

First, let’s start by creating an ingredients enum with different wildflowers. *legend says that these were used for different potions

2. Handler Protocol

Second, let’s define a Handler protocol with a few things:

  • a nextHandler variable
  • a handle() method for handling the request
  • a setNext() method for setting the next handler

Also, let’s create some default implementations for the setNext(handler: Handler) & handle(request: Ingredients) methods.

3. Concrete Handlers

Third, let’s create some concrete handler classes that conform to the Handler protocol. One handler for every ingredient. The premise is simple, the handler checks the request if it corresponds to its ingredient then it’s added to the brew. If it doesn’t correspond, it passes the request to the next handler.

4. Cauldron & WitchApp class

Fourth, let’s define our cauldron class where we put everything together. In the brew() method we pass a list of ingredients and a first handler. The method goes through the list of ingredients and checks if the ingredient is compatible with the handler. If it is compatible then the result is printed if not an appropriate message is displayed.

Finally, in our WitchApp test() method, we put everything together and as shown, as a first handler we choose the blackthorn with the following next handlers:

  • Elder
  • Rowan
  • May

Thus creating a chain of handlers or a chain of responsible entities for a particular request.

When we call the brew() method from the cauldron with that list of ingredients and use the blackthorn as a first handler, the method will go through the entire list, adding the ingredients that have a corresponding handler to the brew. When it reaches the .knotweed element, it will say that it’s not compatible with the brew.

From this point on, the sky is the limit 🚀 well…almost.

Of course, this design pattern has its limitations but used in moderation, it’s a great tool in our development toolbox.

This is the next article in the Swift Problems Catalogue series in which I’ll tackle general software development problems. The aim is to have a quick reference guide that can be easily accessed when having a design/algorithm dillemma.

Let me know what you think and don’t be shy to share where and when this pattern simplified your coding experience 🎶

--

--

Alex Ilovan
salt&pepper

🚀Head of Mobile Development @S&P 💻Comp. Engineer 🪐Engineering Manager. You can visit at: https://www.linkedin.com/in/alex-ilovan-129161b4/