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.
Well there is a command pattern but it may be overkill for what you're doing. Remember KISS.
if you have multiple imbricated 'if' statements, then this is a pattern for using a rule engine. See, for example JBOSS Drools.
using Command pattern:
then build a
Map<String,Command>
object and populate it withCommand
instances:then you can replace your if/else if chain with:
EDIT
you can also add special commands such as
UnknownCommand
orNullCommand
, but you need aCommandMap
that handles these corner cases in order to minimize client's checks.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.
i usually try to solve it that way:
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.Well I suggest to create command objects and put them into a hashmap using the String as Key.