Behavioral Design Pattern — Chain of Responsibility

Erhan Aşıkoğlu
5 min readApr 11, 2021

--

Chain of Responsibility is an another behavioral design pattern that provides separation of command objects from chain of handler objects. Request can visit multiple handlers till to it is handled by responsible handler in chain. Handler can decide by itself to process given request object or to pass the responsibility to the next handler.

Photo by Daniel von Appen on Unsplash

When/Where/Why to use?

Let’s focus on the idea behind the chain of responsibility pattern and in which condition you may need to choose it.

De-coupling

When you want to forward a request to the receiver without needing to know who the sender is, or, sender does not require to know who the receiver is, then we can talk about decupling between sender and receiver. Chain of responsibility pattern provides separation between sender and receiver in this way it breaks the coupling within the communication.

Flexible Hierarchy

The only thing receiver/handler needs to know about is the who will be the next handler, so the hierarchy is very simple in the chain, imagine just like a simple one-way list that only knows next successors. In this way it is very simple to add/remove handler/receiver from the chain, changing the design without breaking the class hierarchy. So with this flexible configurative idea, it becomes candidate for providing loose coupling within the object design.

Decision at Runtime

You can have ability to control order of request handling in runtime.

When you want to delegate incoming request to multiple set of objects without specifying handler explicitly, chain of responsibility pattern will be best choice.

In chain of handlers, request object handling is not assigned to specific handler, instead it is the responsibility of set of handlers that can be dynamically changeable at runtime. This idea saves an object from knowing which object inside the chain is going to process a request, increase loose coupling.

Used By (Examples)

  • Java Util Logger -> Log Levels handling is an appropriate example
  • Spring Security Filter -> Security chain order in spring security another good example for chain of responsibility
  • Javax Servlet Filter -> Same with Spring Security and Delegation of filters according to order rules can count as everyday example for chain of responsibility design patter.

Real Life Scenario

Let’s think about a scenario in your company when you want to change your laptop with a brand new one:

  • First you need to get approval from your Line Manager,
  • Your manager checks the price, if it is under 1000$ then he can confirm and purchase process starts.
  • If laptop price higher than 1000$ he needs to delegate confirmation to Department Manager.
  • Once price lower than 1500$ and purchase type is not a office furniture then Department Manager can approve.
  • When price higher than 1500$ and it is electronic device, request has to be handled by General manager who can approve everything.

This is the typical chain of responsibility scenario, as a client you do not need to know who will approve your purchase request, as a handler your Line Manager has to know he can able to approve under 1000$ request otherwise forward request to next handler.

UML Diagram

UML Diagram Chain Of Responsibility

Sample Implementation

First if you want to jump into code, you can find source code in github .

If we follow UML design we will have following design.

We will have request object which contains type of purchase and amount for simulating conditional checks inside. handlers : PurchaseRequest Class
Request Object

We will have request object which contains type of purchase and amount for simulating conditional checks inside. handlers : PurchaseRequest Class

MainHandler Abstract Class

As you see in abovehandler class, there is a nextHandler aggregation which is known as successor and key part of the chain of responsibility pattern to implement it correctly.

Also, there is a abstract method handlePurchase has to be implemented by each of the concrete handlers.

This is the first concrete handler class that can approve the requests which have amount of under 1000$.

FirstHandler class in chain.

This is the second handler class that can approve amount under 1500$ and purchase type is not furniture.

Another concrete handler example
Demo class

Although there is no clear way to put every screenshot of the codebase, please visit the source code on github. Simply, the main idea to get the chain of responsibility correctly is to use the successor in every concrete method and apply the processor method.

With this implementation when above demo class has be run, It is guaranteed that request object always be handled in any of the handler object inside the chain, but don’t know the who will be handle. (See result of Demo run output below )

Output of Demo class.

Before Using

Photo by janilson furtado on Unsplash
  • According pattern, there isn’t any guarantee on handling/handler. So, we are assuming one of the handler will handle the request, since marking responsible receiver in the chain of handling mechanism is not necessary, there is no guarantee it’ll be handled in the end. ( In our example code, when we remove GeneralManagerHandler from chain, any requests which have amount greater than $1500 will not be handled.)
  • Because there is no guarantee in the handling process, it effects runtime configuration with changing the order or adding/removing handler from chain.
  • Another point that needs to be considered is the increase on number of handlers that needs to be visited for each request or cycle call, can cause increase on process time.
  • Lastly, monitoring of the application behavior is not easy due to fact that debugging option is not easy in in this pattern.

Originally published at http://easikoglu.wordpress.com on April 11, 2021.

--

--