How to Get Rid of Annoying IFs Forever
By: Maximiliano Contieri
Tags: Software Development, Programming, If, Polymorphism, Software Engineering

Why the first instruction we learn to program should be the last to use.

Nobody uses GOTO instruction anymore and few programming languages still support it.

We have matured and confirmed spaghetti code is unmaintainable and error prone. Structured Programming solved that problem years ago.

We got rid of the sentence thanks to Edsger Dijkstra’s incredible paper: Go To Statement Considered Harmful.

Next evolution step will be removing most IF statements

IFs/Cases and Switches are GOTOs disguised as structured flow.

Our tool will be Object Oriented Programming principles.

Photo by Przemysław Bromberek in Pixabay

The Problem

Most IF sentences are coupled to accidental decisions. This coupling generates ripple effect and make code harder to maintain.

Ifs are considered as Harmful as GOTOs.

If sentences violate open/closed principle. Our designs will be less extensible and closed to extension.

What is more, Ifs are open doors to even worse problems, like switches, cases, defaults, return, continue and breaks.

They make our algorithms darker and force us to build accidentally complex solutions.

People out of software development cannot explain why we use this branching sentence. This is a code smell.

Solutions

Before we move on and remove IF sentences we should decide if it's an essential one or an accidental If.

To check this out we will look for answers in real world through bijection.

Essential Ifs

Let’s see an essential IF statement

We should decide whether to remove this if sentence or not.

We must understand whether it is represents a business rule (essential) or an implementation artifact (accidental).

In the case above we will honor our bijection. So we will NOT replace the if.

People In real world describe age constraints in natural language using IFs

Accidental Ifs

Let us dive now into bad IFs.

The movie rating IF is not related to a real world If but to accidental (and coupled) implementation.

Our design decision was to model ratings with strings.

This is a classic neither open to extension, nor closed to modification solution.

Let’s see what happens with new requirements.

We can detect some Code Smells:

Code is polluted with IFs. A default statement is missing. New ratings will bring new IFs. The strings representing ratings are not first class objects. A typo will introduce hard to find errors. We are forced to add getters on Movies to take decisions.

The Recipe

Let’s fix this mess with these steps:

1 — Create a Polymorphic Hierarchy for every IF condition (if it doesn’t already exist). 2 — Move every IF Body to the former abstraction. 3 — Replace IF Call by polymorphic method call.

On our example:

With this outcome:

1- Code is polluted with IFs

We should add no more IFS. Extending the model will be enough.

2- A default statement is missing

In this case default behaviour is not needed since exceptions break flow. In many times a Null Object will be enough.

3- New ratings will bring new IFs

We will be address it with polymorphic new instances.

4- The strings representing ratings are not first class objects. A typo will introduce hard to find errors.

This is hidden in Ratings implementation.

5- We are forced to add getters on Movies to take decisions.

We will clear this, favoring Demeter’s law.