Long list of if statements in Java

2019-01-01 08:03发布

Sorry I can't find a question answering this, I'm almost certain someone else has raised it before.

My problem is that I'm writing some system libraries to run embedded devices. I have commands which can be sent to these devices over radio broadcasts. This can only be done by text. inside the system libraries I have a thread which handles the commands which looks like this

if (value.equals("A")) { doCommandA() }
else if (value.equals("B")) { doCommandB() } 
else if etc. 

The problem is that there are a lot of commands to it will quickly spiral to something out of control. Horrible to look out, painful to debug and mind boggling to understand in a few months time.

15条回答
人间绝色
2楼-- · 2019-01-01 08:24

Well there is a command pattern but it may be overkill for what you're doing. Remember KISS.

查看更多
无与为乐者.
3楼-- · 2019-01-01 08:24

if you have multiple imbricated 'if' statements, then this is a pattern for using a rule engine. See, for example JBOSS Drools.

查看更多
只若初见
4楼-- · 2019-01-01 08:25

using Command pattern:

public interface Command {
     void exec();
}

public class CommandA() implements Command {

     void exec() {
          // ... 
     }
}

// etc etc

then build a Map<String,Command> object and populate it with Command instances:

commandMap.put("A", new CommandA());
commandMap.put("B", new CommandB());

then you can replace your if/else if chain with:

commandMap.get(value).exec();

EDIT

you can also add special commands such as UnknownCommand or NullCommand, but you need a CommandMap that handles these corner cases in order to minimize client's checks.

查看更多
荒废的爱情
5楼-- · 2019-01-01 08:25

if it was possible to have an array of procedures(what you called commands) that'd be useful..

but you could write a program to write your code. It's all very systematic if(value='A') commandA(); else if(........................ e.t.c.

查看更多
公子世无双
6楼-- · 2019-01-01 08:26

i usually try to solve it that way:

public enum Command {

A {void exec() {
     doCommandA();
}},

B {void exec() {
    doCommandB();
}};

abstract void exec();
 }

this has many advantages:

1) it is not possible to add an enum without implementing exec. so you won't miss an A.

2) you will not even have to add it to any command map, so no boilerplate code for building the map. just the abstract method and its implementations. (which is arguably also boilerplate, but it won't get any shorter..)

3) you will save any wasted cpu cycles by going through a long list of if's or calculating hashCodes and doing lookups.

edit: if you don't have enums but strings as source, just use Command.valueOf(mystr).exec() to call the exec method. note that you must use the public modifier on execif you want to call it from another package.

查看更多
栀子花@的思念
7楼-- · 2019-01-01 08:33

Well I suggest to create command objects and put them into a hashmap using the String as Key.

查看更多
登录 后发表回答