Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I was reading this article and was wondering, do we get rid of all switch statements by replacing them with a Dictionary or a Factory so that there are no switch statements at all in my projects.

Something did not quite add up.

The question is, do switch statements have any real use or do we go ahead and replace them with either a dictionary or a factory method (in using a factory method, of course, there will be a minimum use of switch statements for creating the objects using the factory...but that is about it).

share|improve this question
9  
Assuming you implement a factory, how will you decide which type of object to create? –  CodeART May 4 '12 at 7:05
1  
Very related: programmers.stackexchange.com/questions/146771/… –  pdr May 4 '12 at 7:20
    
@CodeWorks: I will, of course, have conditions somewhere, deciding which concrete implementation to use. –  Kanini May 4 '12 at 7:25
    
@CodeWorks: With a virtual constructor, obviously. (And if you can't implement a factory pattern that way, you need a better language.) –  Mason Wheeler May 4 '12 at 18:57
add comment

6 Answers

up vote 29 down vote accepted

Both switch statements and polymorphism have their use. Note though that a third option exists too (in languages which support function pointers / lambdas, and higher-order functions): mapping the identifiers in question to handler functions. This is available in e.g. C which is not an OO language, and C# which is*, but not (yet) in Java which is OO too*.

In some procedural languages (having no polymorphism nor higher-order functions) switch / if-else statements were the only way to solve a class of problems. So many developers, having accustomed to this way of thinking, continued to use switch even in OO languages, where polymorphism is often a better solution. This is why it is often recommended to avoid / refactor switch statements in favour of polymorphism.

At any rate, the best solution is always case dependent. The question is: which option gives you cleaner, more concise, more maintainable code in the long run?

Switch statements can often grow unwieldy, having dozens of cases, making their maintenance hard. Since you have to keep them in a single function, that function can grow huge. If this is the case, you should consider refactoring towards a map based and/or polymorphic solution.

If the same switch starts to pop up in multiple places, polymorphism is probably the best option to unify all these cases and simplify code. Especially if more cases are expected to be added in the future; the more places you need to update each time, the more possibilities for errors. However, often the individual case handlers are so simple, or there are so many of them, or they are so interrelated, that refactoring them into a full polymorphic class hierarchy is overkill, or results in a lot of duplicated code and/or tangled, hard to maintain class hierarchy. In this case, it may be simpler to use functions / lambdas instead (if your language allows you).

However, if you have a switch in a single place, with only a few cases doing something simple, it may well be the best solution to leave it like it is.

*I use the term "OO" loosely here; I am not interested in conceptual debates over what is "real" or "pure" OO.

share|improve this answer
4  
+1. Also, those recommendations tend to be worded, "prefer polymorphism to switch" and that's a good word choice, very much in keeping with this answer. It acknowledges that there are circumstances where a responsible coder might make the other choice. –  Carl Manaster May 4 '12 at 13:30
1  
And there are times when you want the switch approach even if there are a gazillion of them in your code. I've got a piece of code in mind that generates a 3D maze. Memory use would go way up if the one-byte cells in the array were replaced with classes. –  Loren Pechtel Feb 14 '13 at 4:32
add comment

This is where I go back to being a dinosaur...

Switch statements are not bad in an of themselves, its the use that's made of them that's at issue.

The most obvious one is the "same" switch statement repeated over and over again through your code that is bad (been there, done that, would make every effort not to again) - and its this latter case that you may be able to deal with using polymorphism. There's usually something fairly horrid about nested cases too (I used to have an absolute monster - not entirely sure how I deal with it now other than "better").

Dictionary as switch I find more challenging - fundamentally yes if your switch covers 100% of the cases, but where you want to have default or no action cases it starts to get a bit more interesting.

I think its a question of avoiding repetition and of making sure we're composing our object graphs in the right places.

But there's also the comprehension (maintainability) argument and this cuts both ways - once you understand how it all works (the pattern and the app in which its implemented) its easy... but if you come to a single line of code where you have to add something new you then have to jump all over the place to work out what you need to add/change.

For all that our development environments are massively capable I still feel that it is desirable to be able to understand code (as if it were) printed out on paper - can you follow the code with your finger? I accept that actually no, with a lot of good practice today you can't and for good reasons but that means that getting up to speed with code is harder to start (or maybe I'm just old...)

share|improve this answer
4  
I had a teacher who said that ideally code should be written "so that someone who knew nothing about programming (like maybe your mother) could understand it." Unfortunately that is an ideal, but maybe we should include our moms in code reviews anyway! –  Michael K May 4 '12 at 12:35
    
+1 for "but if you come to a single line of code where you have to add something new you then have to jump all over the place to work out what you need to add/change" –  quickly_now May 5 '12 at 5:26
add comment
do we get rid of all switch statements by replacing them with a Dictionary or a Factory so that there are no switch statements at all in my projects.

No. Such absolutes are rarely a good idea.

Many places, a dictionary/lookup/factory/polymorphic dispatch will provide a better design than a switch statement but you still have to populate the dictionary. In certain cases, that will obscure what is actually going on and simply having the switch statement in-line is more readable and maintainable.

share|improve this answer
    
And really, if you unrolled the factory and the dictionary and the lookup, it would turn out to be basically a switch statement: if array[hash(search)] then call array[hash(search)]. Although it would be runtime-extendable which compiled switches are not. –  Zan Lynx May 4 '12 at 20:07
add comment

Seeing as how this is language-agnostic, fall-through code works best with switch statements:

switch(something) {
   case 1:
      foo();
   case 2:
      bar();
      baz();
      break;

   case 3:
      bang();
   default:
      bizzap();
      break;
}

Equivalent with if, with a very awkward default case. And keep in mind that the more fall-through there is, the longer the condition list will get:

if (1 == something) {
   foo();
}
if (1 == something || 2 == something) {
   bar();
   baz();
}
if (3 == something) {
   bang();
}
if (1 != something && 2 != something) {
   bizzap();
}

(However, given what some of the other answers say, I feel like I've missed the point of the question...)

share|improve this answer
add comment

Switch-statements vs subtype-polymorphism is an old problem and is often referred to in the FP community in discussions on the Expression Problem.

Basically, we have types (classes) and functions (methods). How do we code stuff so that its easy to add new types or new methods latter on?

If you program in OO style, its hard to add a new method (since that would mean refactoring all the existing classes), but its very easy to add new classes that use the same methods as before.

On the other hand, if you use a switch statement (or its OO equivalent, the Observer Pattern) then its very easy to add new functions but its hard to add new cases/classes.

Its not easy to have good extensibility in both directions, so when writing your code, determine whether to use polymorphism or switch statements depending on which direction you are more likely to extend latter on.

share|improve this answer
add comment

Switch statements as case differentiation do have a real use. Functional programming languages use something called pattern matching which allows you to define functions differently depending on the input. However in object oriented languages the same goal can be reached more elegantly by using polymorphism. You simply call the method and depending on the actual type of the object, the corresponding implementation of the method will be executed. This is the reason behind the idea, that switch statements are a code smell. However, even in OO languages, you might find them useful to implement the abstract factory pattern.

tl;dr - they are useful, but quite often you can do better.

share|improve this answer
1  
I smell some bias there - why is polymorphism more elegant than pattern matching? And what makes you think polymorphism doesn't exist in FP? –  tdammers May 4 '12 at 8:24
    
@tdammers First of all I did not mean to imply that polymorphism does not exist in FP. Haskell supports ad hoc and parametric polymorphism. Pattern matching makes sense for an algebraic datatype. But for external modules this requires exposing constructors. Clearly this breaks encapsulation of an abstract data type (realized with algebraic datatypes). That is why I feel that polymorphism is more elegant (and possible in FP). –  scarfridge May 4 '12 at 15:20
    
You are forgetting polymorphism through typeclasses and instances. –  tdammers May 4 '12 at 16:12
    
Heve you ever heard of the Expression Problem? The OO and the FP are better in different situations, if you stop to think about it. –  missingno May 4 '12 at 20:13
    
@tdammers What kind of polymorphism do you think I was talking about when I mentioned ad hoc polymorphism? Ad hoc polymorphism is realized in Haskell through type classes. How can you say I forgot it? Simply not true. –  scarfridge May 5 '12 at 19:25
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.