views:

848

answers:

9

Are there instances where switch(case) is is a good design choice (except for simplicity) over strategy or similar patterns...

+4  A: 

For one, readability.

John T
Meaningfully named classes with meaningfully named methods are much more readable to other programmers than anonymous blocks that have to be duplicated because they are nested inside switches or anywhere else to be fair. If statements are just as bad.
+1  A: 

it's usually ok, as long as you only have one switch in one place. when you have more than one (or many), then it's time too consider alternatives.

Ray Tayek
A: 

The "strategies" could be created with a switch.

That could be the starting point and from there let the polymorphism do the job.

Other that comes to mind need for extra speed at the cost of flexibility. There are cases.

OscarRyz
+3  A: 

Yes, definitely. Many times your switch is only relevant to a very small part of your overall logic and it would be a mistake to create whole new classes just for this minor effect.

For example, let's say you have a database of words, the user input another word, and you want to find that word in the database but include possible plurals. You might write something like (C++)


vector<string> possible_forms;
possible_forms.push_back(word);
char last_letter = word[word.size() - 1];
switch (last_letter) {
  case 's':
  case 'i':
  case 'z':
    possible_forms.push_back(word + "es");
    break;
  case 'y':
    possible_forms.push_back(word.substr(0, word.size() - 1) + "ies");
    break;
  default:
    possible_forms.push_back(word + "s");
}

Doing this with strategies would be overkill.

lacker
What about 'person', 'sheep', or words that are already plural? Plurality forms part of the type of a given word. With polymorphism, we are fine, we can add these in later *with no code change*. With a switch, you have to modify and grow your code. English has so many rules, I wouldn't be surprised if the 'minor effect' of the switch above grew into a 'major maintenance problem', a 1000+ lines long. I have seen single switches in other people's code nearly 3000 lines long before. So, no, there are always better choices than using switch.
This code is currently 15 lines long. If someone else rewrites it into 1000+ lines while keeping it as a single switch statement, that's their fault, not the fault of the initial switch statement.
lacker
+9  A: 

First of all, Simplicity often is a good design choice.

I never understood this bias against switch/case. Yes, it can be abused, but that, so can just about every other programming construct.

Switching on a type is usually wrong and probably should be replaced by polymorphism. Switching on other things is usually OK.

James Curran
Switches choose behaviour - therefore implying that there is a behavioural type involved, i.e. whatever is being switched on 'is' or 'has' a set of distinguishable types, otherwise it wouldn't be possible to use a switch. Therefore we always switch on a type, and I agree with you that switching on a type is 'wrong' (in that it is hard to maintain and reuse the behaviour).
A: 

No, the switch statement is probably only a good design choice in simple situations.

Once you are passed a simple situation switch statements become very painful to keep updating and maintaining. This is part of the reason design patterns came about.

javelinBCD
+18  A: 

Use Switches when you're testing on values of primitives. (ie. integers or characters).

Use polymorphism when you are choosing between different types.

Examples : Testing whether a character the user has entered is one of 'a', 'b' or 'c' is a job for a switch.

Testing whether the object you're dealing with is a Dog or Cat is a job for polymorphic dispatch.

In many languages, if you have more complicated values you may not be able to use Switch anyway.

interstar
Switches always involve a behavioural type because they are choosing behaviour. Values don't have behaviour. The user didn't enter 'a', 'b' or 'c', they made a choice and the program's behaviour depends on the type of that choice. The key they pressed was simply a temporary reference for that type, just as a pointer can refer to a class. Polymorphism would be a clearer way to model this.
A: 

If it was always wrong, it wouldn't be included in so many languages. On the other hand there's a lot of easy ways to write bad code with a switch statement. Go ahead and use them, but pay extra attention to what you're doing if you do.

Ant P.
Well, that isn't exactly right. There are still languages using the goto statement, and that is still the spaghetti of all evil ;-)
Gamecat
Well, it is not *always* wrong, but quite often. Taking in account if "switch" is present in some language (and thus is ok) is at least misleading. My rule of thumb, is to use "switch" for small constructs, and look at it as CodeSmell, thus probably candidate for refactoring.
Victor Farazdagi
A: 

My view is that switch is always wrong:

The body of a case is code and is behaviour, therefore, the thing in the case (the 'value') has a behavioural type, therefore, polymorphism would be a better choice.

This implies that values are in fact types, e.g. the number 1 is a type of everything that equals 1 in some way. All that remains is for us to map 1-ness to the behaviour for our specific case, and we have polymorphism with all those other types (a Good Thing).

This is easier done in some languages than others, unfortunately, most languages in common use are pretty awful, so the path of least resistance is the wrong one, and people end up writing switches or if statements (same thing).