Skip to main content

Breaking if/else with a Chain

Greetings!

There are If/Else or switch statements in any Software. We need to use that logical branching for object oriented programming as well. The question is how do you use that? are they readable? maintainable? or looks beautiful?

What I normally see in such codes is those are very fragile, hard to read, ugly. Needless to say about the vulnerability of the branching levels in this case.

Most of the developers might add few private methods and call those to show that the code is clean.

This can be solved in multiple ways depending on the situation.

Simple Conditions

When you see such a code, consider it as a candidate for polymorphism. In most of the cases, you can deal this with abstraction. A simple factory will do the rest.

Multi level branches

Complexity arrives with multi levels. It is quite difficult to identify common factors, abstraction. However, it does not mean you can't do it. It depends on the problem at hand. You might still fix this with a simple interface, using known patterns like Template, Command, Strategy, etc. I prefer to solve this using another well known design pattern which is Chain of Responsibility.


The pattern

If you are here, I assume you have enough knowledge on patterns. I'm not going to describe the pattern as you can find many examples like this.


Why

As per the pattern, you handle one condition in one class. It makes easy to add unit test and to maintain. You just plug it to the chain when you get a new condition. You just remove it from the chain when you want to remove a condition.

How

This is the hard part. You need to carefully split the conditions. When it comes to multi levels, you might end up one condition needs the data from another condition. Here we need to tweak the pattern a little. Use a data class and fill it as the chain goes. Chain will be broken or all the conditions will be visited depending on your need. In the best case scenario, we can create fully independent classes. However feel free to accept ordered chain as well.
In above image, I will go with 5 handlers (all the paths which reaches operation 1-4)

How about common logics?

Again, you will need to mix multiple patterns depending on your situation. For an example you can mix Template pattern to handle common parts. Or even a simple delegation also works.

What do we gain?

Readable, maintainable, extendable, beautiful code :) Each operation can easily unit test. How about lots of fun 😉

Common Questions

Q: I have to create lots of classes.
A: Yes, it adheres to single responsibility.

Q: One class needs to know the next in chain.
A: Yes and No, just accept the positives here.

Q: I have to create the chain.
A: Yes, is that hard?

Q: I have to use another conditions' data
A: Use a data object which fills as the chain goes.

Q: I have a condition which depends on another classes' data
A: We have an ordered chain.

Q: Someone might change the order and break the logic.
A: The pattern is widely known and the flow is obvious. Nobody will do that.

Q: I don't know, any developer, may be by accident
A: Isn't he/she a team member?

Q: Yes
A: That's why we have code reviews.

Summary

It is rare to see people use this pattern. I don't know why. Perhaps, thinking part is harder 🤔
Just keep it simple. Look for polymorphism. Try out the CoR. You will not regret.

Happy coding ;)