Switches as well as conditionals with many branches(else ifs) are generally indicative of a different issue all together.
Switches can be a good choice in the case of a clearly defined unchangeable list of things to check against, like days of the week(I pray to god there will only be seven in the future too). They are also sometimes good in the case that you actually have found a use case for the fall through effect you get when you don't use a break. Switches also are very hard to do in a way that enables defensive programming. It's easy for a switch to have 4 or 5 cases, then someone comes in and adds one, comes in and adds another, then another, until you have a giant mess of cases.
Generally, like @rossholloway94
mentioned, Enums are a much better fit. The way that @0xrumple showed in python can be done in many other languages that don't have real Enums, but is essentially an Enum as well. Alternatively, in certain use cases, something like a rule matcher and handler can be a better fit.
class Foo implements RuleHandler {
public function canHandle(condition) : bool {
if(condition === something) { return true; }
}
public function handle(thing) : Bar {
return thing.thing() + thing.otherThing();
}
}
Using a switch can also be indicative that whatever logic you're doing in the switch, is really something that should be on each class to implement which can be similar to the model above. Basically the Strategy design pattern.
//instead of this
function doThingsThing(thing: Thing) : void {
switch(thing.val) {
case 1 { thing.a + thing.b; break; }
case 2 {thing.a * thing.b; break; }
// more cases
default { //this should never happen }
// NEVER DO THIS TO A DEFAULT IF IT SHOULDN'T HAPPEN THROW AN ERROR
}
}
//this
function doThingsThing(thing : Thing) {
thing.doThing();
}
abstract class Thing { abstract function doThing() : Thing; }
class Thingy extends Thing { function doThing() : Thing {this.meh = 2; return this; } }
class OtherThingy extends Thing { function doThing() : Thing { this.meh = this.meh * 2; return this; } }
The reason a switch never feels better than many else ifs is because they are basically the exact same thing. The kind of feel that gets hammered in a lot of beginner tutorials that explain switches is something like "If you have a lot of conditions, use a switch!" and also the examples show how to convert a thing with a lot of else if statements into a switch.
One more time for clarity:
Consider using an if in the case that:
There are a TRULY finite number of cases
The fall through logic will really help(though there are OOP ways of handling this too that I didn't show)
Excellent point! Sometimes you may need lots of if statements, but more often than not, lots of ifs are a sign that your code is just too procedural. By abstracting away code in functions or classes you can often get rid of them.
Haha no offense at all. The rule handler is overkill in A LOT if not most scenarios. That said, it's for sure one of the patterns you would use instead of a switch so I included it. For the trivial example I have though, yeah way overkill. For the slackbot I made a while back I used it and it worked well. github.com/samuraiseoul/starbot/bl... and github.com/samuraiseoul/starbot/bl... are an example where it works well.
Switch
es as well as conditionals with many branches(else if
s) are generally indicative of a different issue all together.Switch
es can be a good choice in the case of a clearly defined unchangeable list of things to check against, like days of the week(I pray to god there will only be seven in the future too). They are also sometimes good in the case that you actually have found a use case for the fall through effect you get when you don't use abreak
.Switch
es also are very hard to do in a way that enables defensive programming. It's easy for aswitch
to have 4 or 5 cases, then someone comes in and adds one, comes in and adds another, then another, until you have a giant mess ofcase
s.Generally, like @rossholloway94 mentioned,
Enum
s are a much better fit. The way that @0xrumple showed in python can be done in many other languages that don't have realEnum
s, but is essentially anEnum
as well. Alternatively, in certain use cases, something like a rule matcher and handler can be a better fit.Using a
switch
can also be indicative that whatever logic you're doing in theswitch
, is really something that should be on each class to implement which can be similar to the model above. Basically the Strategy design pattern.The reason a
switch
never feels better than manyelse if
s is because they are basically the exact same thing. The kind of feel that gets hammered in a lot of beginner tutorials that explainswitch
es is something like "If you have a lot of conditions, use aswitch
!" and also the examples show how to convert a thing with a lot ofelse if
statements into aswitch
.One more time for clarity:
switch
alternative candidates are:Enum
sInterface
s in classesExcellent point! Sometimes you may need lots of
if
statements, but more often than not, lots ofif
s are a sign that your code is just too procedural. By abstracting away code in functions or classes you can often get rid of them.Enums are also good, but they might not fit in cases where there is no ordinal values.
Don't get offended, but the rule handler matcher / OOP ways to return a value reminds me of this meme:
Haha no offense at all. The rule handler is overkill in A LOT if not most scenarios. That said, it's for sure one of the patterns you would use instead of a switch so I included it. For the trivial example I have though, yeah way overkill. For the slackbot I made a while back I used it and it worked well. github.com/samuraiseoul/starbot/bl... and github.com/samuraiseoul/starbot/bl... are an example where it works well.
Aha... Heck yeah, this example is pretty solid 👌