Ways to eliminate switch in code [closed]

2018-12-31 18:08发布

What are the ways to eliminate the use of switch in code?

23条回答
明月照影归
2楼-- · 2018-12-31 19:03

If the switch is there to distinguish between various kinds of objects, you're probably missing some classes to precisely describe those objects, or some virtual methods...

查看更多
美炸的是我
3楼-- · 2018-12-31 19:05

Another vote for if/else. I'm not a huge fan of case or switch statements because there are some people that don't use them. The code is less readable if you use case or switch. Maybe not less readable to you, but to those that have never needed to use the command.

The same goes for object factories.

If/else blocks are a simple construct that everyone gets. There's a few things you can do to make sure that you don't cause problems.

Firstly - Don't try and indent if statements more than a couple of times. If you're finding yourself indenting, then you're doing it wrong.

 if a = 1 then 
     do something else 
     if a = 2 then 
         do something else
     else 
         if a = 3 then 
             do the last thing
         endif
     endif 
  endif

Is really bad - do this instead.

if a = 1 then 
   do something
endif 
if a = 2 then 
   do something else
endif 
if a = 3 then 
   do something more
endif 

Optimisation be damned. It doesn't make that much of a difference to the speed of your code.

Secondly, I'm not averse to breaking out of an If Block as long as there are enough breaks statements scattered through the particular code block to make it obvious

procedure processA(a:int)
    if a = 1 then 
       do something
       procedure_return
    endif 
    if a = 2 then 
       do something else
       procedure_return
    endif 
    if a = 3 then 
       do something more
       procedure_return
    endif 
end_procedure

EDIT: On Switch and why I think it's hard to grok:

Here's an example of a switch statement...

private void doLog(LogLevel logLevel, String msg) {
   String prefix;
   switch (logLevel) {
     case INFO:
       prefix = "INFO";
       break;
     case WARN:
       prefix = "WARN";
       break;
     case ERROR:
       prefix = "ERROR";
       break;
     default:
       throw new RuntimeException("Oops, forgot to add stuff on new enum constant");
   }
   System.out.println(String.format("%s: %s", prefix, msg));
 }

For me the issue here is that the normal control structures which apply in C like languages have been completely broken. There's a general rule that if you want to place more than one line of code inside a control structure, you use braces or a begin/end statement.

e.g.

for i from 1 to 1000 {statement1; statement2}
if something=false then {statement1; statement2}
while isOKtoLoop {statement1; statement2}

For me (and you can correct me if I'm wrong), the Case statement throws this rule out of the window. A conditionally executed block of code is not placed inside a begin/end structure. Because of this, I believe that Case is conceptually different enough to not be used.

Hope that answers your questions.

查看更多
旧时光的记忆
4楼-- · 2018-12-31 19:10

Well, for one, I didn't know using switch was an anti pattern.

Secondly, switch can always be replaced with if / else if statements.

查看更多
倾城一夜雪
5楼-- · 2018-12-31 19:12

I think the best way is to use a good Map. Using a dictionary you can map almost any input to some other value/object/function.

your code would look something(psuedo) like this:

void InitMap(){
    Map[key1] = Object/Action;
    Map[key2] = Object/Action;
}

Object/Action DoStuff(Object key){
    return Map[key];
}
查看更多
心情的温度
6楼-- · 2018-12-31 19:12

Why do you want to? In the hands of a good compiler, a switch statement can be far more efficient than if/else blocks (as well as being easier to read), and only the largest switches are likely to be sped up if they're replaced by any sort of indirect-lookup data structure.

查看更多
登录 后发表回答