I have a few times needed to try and explain to a developer why they should change a class which has multiple instances of
switch(m_type) {
case TYPE_A:
...
break;
case TYPE_A:
...
break
...
}
Where m_type is a (final) reference to an enum defining what type of instance this is.
Whenever I see this I think it's time to split the class out into multiple subclasses where the concrete class you create then defines the type. The argument I always get back is 'It didn't seem worth creating all these classes with hardly any code in, what are they going to have in there? like 2 methods or something!'
The best explanation I've seen is that unnecessary control logic should be avoided. If the code can be restructured to remove or avoid a branch, if, switch, etc. it should. If not, then use the control statement that is the most appropriate. From here but I'm not convinced this will be well received since the dev in question always thinks their code isn't too complex anyway so probably won't get why it matters.
This is a common enough mistake though with a very common attitude to why it exists, has anyone had any luck helping a developer understand the mistake they are making?
Thanks,
Robin
The reason is that the programmer has to write the case statements himself, whereas the compiler provides the decision-making when dispatching method calls among subclasses. Less code means less bugs. Especially in a C-like language like Java, where cases fall through. Every case presents an opportunity to (a) put in the wrong case value and (b) forget the break.
Another reason is that when the next programmer comes along and wants to add behavior #2 to this part of the code, that programmer will have to write another switch that duplicates the control logic of the first, then keep them in sync, whereas with the subclass strategy, he can just add a new method.
Of course there are always exceptions. The switch statement is not completely useless. If the code in question really is trivial then maybe let it go. I think that code should be clear and straightforward first, architecturally pure second.
The Single-Choice principle states that, when a list of possible options exists in a program, only one place in the program should know its exhaustive list. It's an important special case of DRY. Ask whoever keeps using switch statements what happens if you need to add to the list of possibilities. The beauty of polymorphism is that code can be written that will handle any possible behavior without knowing the exhaustive list of behaviors.