Skip to content

Implementing a chain of responsibility

Few months ago I was working with my team on an application that gives discounts on credit card POS according to a sequence of rules. Basically the client should have monthly revenue, sign a determined type of contract and have a determined model of POS.

While discussing with the teams, we have came out with some approches like many if’s clauses and using the factory design pattern to create the validation rule according to previous conditions. But looking to those proposed solutions, none of them was clean enough. I knew that there should be a design pattern to come to rescue.

A little parenthesis here. I am an advocate that design patterns shouldn’t be memorized in depth. Instead developer’s should have a overview of the design pattern and when there is a situation with lot of code repetition of a complex if structure. Then there should be design pattern to help. In this case, there are a lot of resources where you can read and choose the right pattern. The parenthesis ends here.

After some research I stumbled upon the Chain of Responsability pattern. This pattern is a of type behavioral and it aims to pass a request in a chain and the receiver decides if he process or pass the request.

Example

In this example we have a bank that will offer a cashback for the clients that fulfill three conditions:

  • The client must be of the Prime segment
  • Have at least $3000 in expenses per month in the credit card
  • Must be a bank’s client for 2 years

The image below illustrates how the chain is organized. It starts with the ValidationService that calls the SegmentRule, if the validation is successful, then it calls the MonthlyExpensesRule and finally with all gone right the TimeAsClientRule is called. If any of the rules fail, it will move to ValidationFail and the chain is broken.

The implementation will follow the class structure described in the diagram:

Below you can find the implementation of the scenario.

The Rule interface shown below is the interface that every validation implements

The class TimeAsClientRule below is responsible for validating if the client has an open account for at least two years

On the class SegmentRule, the client’s segment is validate to check what is his current segment

The MonthlyExpensesRule class is responsible for validating the previous month expenses

In the codes shown above, you can note the classes have the member variable nextRule, and the next Rule to be called is passed on the constructor of each Rule class. Thus when the nextRule.validate() is called, The next rule on the chain will be called.

You can access the whole project on:
https://github.com/pedroveras/chain-of-responsibility

Published inDesign Pattern

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *