A friend of mine sent me a link to an Italian website sponsoring a campaign to rid software of the IF statement, especially 'type determinant' IF statements. Here is a link to the original page, and here is my rough translation of it:
The anti IF campaign. "if you want to stop, you can"
Objective:
The objective of this campaign is to make developers more aware of how to use object oriented design principles effectively. The first step towards reaching this objective is becoming aware of the consequences of using IF statements and other imperative programming techniques in the context of an Object Oriented language. The major objective of the campaign is to help developers understand how principles of OO design make it possible to achieve software that is more effective in terms of flexibility, changeability, descriptiveness, and testability.
Why:
The campaign was born from one of Francesco Cirillo's ideas: "Many teams want to be agile but don't know how to reduce the complixity of their code. We can start to achieve this by using OO techniques to remove type-determining IF statements from our code."
The fundamental problem is that type-determining IF statements create dipendencies, and coupling across modules (methods, objects, components, etc.) and increase the possible paths through the code, reducing the readability. The IF statement seems to be a quick and easy way to achieve functionality but with complex IF statements you quickly get to apoint where the software is no longer able to be modified and is full of duplication. Here is a simple example
// classe Bond
double calculateValue() {
if(_type == BTP) {
return calculateBTPValue();
} else if(_type == BOT) {
return calculateBOTValue();
} else {
return calculateEUBValue();
}
}
Every additional type added to the system obliges us to modify this piece of code. Objects give us an effective instrument for making sure that changes in requirements don't translate into changes in our code.
// classe Bond
double calculateValue() {
_bondProfile.calculate();
}
// classe AbstractBondProfile
abstract double calculate();
// classe BTPBondProfile
double calculate() {
...
}
// classe BOTBondProfile
double calculate() {
...
}
// classe EUBondProfile
double calculate() {
...
}
What is the advantage of removing the IF? In the fact that tomorrow the request for a new type of Loan requires simply creating a new class with the only additional logic being how to calculate the value of the loan.
The solution isn't always to create a new abstract class of interface, but the solution always increases the flexibility, descriptiveness, and testability of the software.
I agree with them, but would like to point out that you don't need that stinky old abstract class! If you apply a dynamic language such as Ruby to the problem, Duck typing removes the need for such an empty construct. And meta-programming can go a long way in removing unnecessary IF statements from your code. These guys should definately have some meta-programming examples of reducing cyclomatic complexity on their page.