If-less programming (basically without conditionals)

OopPolymorphismConditional

Oop Problem Overview


I've had a colleague that told me he once worked for a company that had as a policy to never have conditionals ("if" and "switch" statements) in the code and that they let all the decisions in the code be done using polymorphism and (I'm guessing) some other OO principles.

I sort of understand the reasoning behind this, of having code that is more DRY and easier to update, but I'm looking for a more in-depth explanation of this concept. Or maybe it's part of a more general design approach.

If anyone has any resources for this or would be willing to explain or even have some more terms related to this I can use to find more answers I'd be much obliged.

I found one question on SO that was kind of related but I'm unfamiliar with C++ so I don't understand too much of the answers there.

(I'm no OO guru btw but I can manage)

I'm most proficient in PHP, and after that Python so I'd prefer info that uses those languages.

Update: I'll ask my colleague for more info on what he meant exactly.

Update 2015: after some more years of experience in programming I see now that the aim of this policy was probably to prevent programmers from adding functionality in a haphazard way by just adding conditionals (if statements) in certain places. A better way to extend software is to use the "Open/Closed principle" where software is extended by using inheritance and polymorphism. I strongly doubt whether the policy was super strict on all conditionals as it's kinda hard to go completely without them.

Oop Solutions


Solution 1 - Oop

There are some resources on the Anti-IF Campaign site, such as this article.

I believe it's a matter of degree. Conditionals aren't always bad, but they can be (and frequently are) abused.

Additional thoughts (one day later)

Refactoring: Improving the Design of Existing Code is a good reference on this subject (and many others). It covers Replace Conditional with Polymorphism. There's also a new one, Replace Conditional with Visitor, on the web site.

I value simplicity and single responsibility over removing all if statements. These three goals often coincide. Static analysis tools that support the cyclomatic complexity metric can quickly point out code with nested or serial conditionals. The if statements may remain post-refactoring, but could be broken out into smaller methods and/or multiple classes.

Update: Michael Feathers wrote an article on Unconditional Programming.

This is a popular topic: Phil Haack on Death to the IF statement!

Solution 2 - Oop

After some years of programming I return to my own question, the context of which I now understand a little better.

There's a good talk by Sandi Metz where she refactors a really hairy ball of if-statements to something waaay less hairy: https://www.youtube.com/watch?v=8bZh5LMaSmE

Solution 3 - Oop

> I've had a colleague that told me he once worked for a company that > had as a policy to never have conditionals ("if" and "switch" > statements) in the code and that they let all the decisions in the > code be done using polymorphism and (I'm guessing) some other OO > principles.

I think your colleague misunderstood something or used the wrong words to explain it. And you can't completely avoid conditional statements.

There is a thing to say: proliferating of if statements inside OOP may be a symptom of bad programming. Some example:

Don't use if to check return value of the function like a old C-style programming:

int ret = some_func();
if (ret != null)
   //do something

This was typical in C code but with OOP you should use exception:

try{
    do_something();
}catch(Exception e){
    e.printStackTrace(); //why I was not able to do something
    handle(e); //there is something else I could do to handle the occurred error
}

Sometimes if statements proliferation is related to a bad design. Consider the follow example in Java:

BaseClass base;
if (base instanceof DerivedClassOneFromBase){
    DerivedClassOneFromBase d = (DerivedClassOneFromBase)base;
    d.methodOne();
}else if (base instanceof DerivedClassOneFromBase){
    DerivedClassTwoFromBase d = (DerivedClassTwoFromBase)base;
    d.methodTwo();
}

This is another example of bad if statements, probably related to a bad design. If the two derived object would have a common method defined in their base class BaseClass, the you could have called that method instead of checking their concrete type and casting them:

base.commonMethod();

Solution 4 - Oop

I read the post you linked and it seems that they were mostly talking about removing the need for conditionals within a class, not to be confused with all code in general. The idea being that if you need to check an object's state (using a conditional) to determine if it has certain functionality, then in actuality you have two objects (one that supports the functionality and one that does not) and should define them as two related classes instead.

Solution 5 - Oop

Sometimes conditionals inside methods are bad as they are a sign that you are just performing multiple functions or multiple types methods in the one method.

If you have a class called Automobile and subclasses such as Car and Bike, and a method such as:

drive(Automobile a)
   if (a.isCar)
      // do stuff
   else if (a.isBike)
      // do stuff

you are most likey doing something wrong. Even if it is not a switch based on type, it can often be wrong. If the method is performing multiple functions depending on some variable, it is often trying to do more than one thing and probably should be separated into multiple methods.

For example:

save(Car c)
   if (c is new)
      // do some stuff
   else if (c is old)
      // do some stuff

could potentially be broken up into save and update, as they are two different functions. Though it does depend.

Completely banning if statements would be silly though as they have many valid use cases.

Solution 6 - Oop

Avoiding conditionals does not necessarily mean you need to get it done by polymorphism or inheritance, take for example :

You have 3 different folders to store uploaded images, uploaded videos and uploaded pdf

You can write code as :

uploadMedia(mediaType){
   if(mediaType == images){
     uploadTo("myProject/images");
   }else if(mediaType == videos){
     upoloadTo("myProject/videos);  
   }else if(mediaType == pdf){
     uploadTo("myProject/pdf");
  }
}

Another alternative that people might use is switch-case :

uploadMedia(mediaType){
         switch(mediaType){
         case : images
         uploadTo("myProject/images");
         break;
    
         case : videos
         uploadTo("myProject/videos");
         break;
    
         case : pdf
         uploadTo("myProject/pdf");
         break;
    }
}

But then you can totally avoid conditional statement by using something like dictionary/hashmap/json (Depending upon whatever you work with) :

For example :

HashMap<String,String> mediaMap = new HashMap<>();

mediaMap.put("images","myProject/images");
mediaMap.put("videos","myProject/videos");
mediaMap.put("pdf","myProject/pdf");

//mediaType can be images/videos/pdf same as keys of mediaMap
uploadMedia(mediaType){
  uploadTo(mediaMap.get(mediaType));
}

This is sort of pseudo code so there might be syntax mistakes, but overall this concept is also helpful in avoiding conditionals. Also line of code can be reduced.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNiels BomView Question on Stackoverflow
Solution 1 - OopTrueWillView Answer on Stackoverflow
Solution 2 - OopNiels BomView Answer on Stackoverflow
Solution 3 - OopHeisenbugView Answer on Stackoverflow
Solution 4 - Oopuser849425View Answer on Stackoverflow
Solution 5 - OopBobTurboView Answer on Stackoverflow
Solution 6 - OopTGWView Answer on Stackoverflow