How can I avoid repeated if-statement?
I write a java application to handle log file had millions of line In program there is such a pseudo code
if(optionA is On)
call object A's method
if(optionB is On)
call object B's method
if(optionC is On)
call o开发者_高级运维bject C's method
...
The options in IFs are config value get from a config file This pseudo code called in each log line, so it called millions of time
Because of speed and simplicity, I want to remove this multi IFs. To see such a many IFs are unpleasant to me. Is theare a good way to get around this annoying IFs?
If the objects share a common interface, you could create a method like this:
private void callOptional(myInterface obj, boolean flag) {
if (option) obj.method();
}
That way you have eliminated the IFs. But you still have a long list of common code. To make it more DRY, I'd add the object reference to the list where you store the options and then just do a for loop:
for (OptionObjectPair ooPair : optionObjectList) {
callOptional(ooPair.obj, ooPair.flag)
}
You can then even change the interface of the callOptional method to take an OptionObjectPair directly.
Long sequences of if
statements are not always a bad thing. If you want to do it the right way though, you have to define the mapping of your options to their "handlers" in a data structure instead of hardcode it in if statements.
You can define a one-method interface and have A
, B
and C
(in your example) implement it:
public interface OptionHandler { // For lack of a better name...
void handleOption(); // You could pass parameters here
}
You can then define a map of the options to their handlers:
private final Map<Option, OptionHandler> optionHandlers = new HashMap<Option, OptionHandler>();
You would then replace your sequence of if
statements with something like:
for (Option option : options) {
if (!option.isOn()) {
// Skip off option
continue;
}
OptionHandler handler = optionHandlers.get(option);
if (handler != null) {
handler.handleOption();
}
}
It really depends what you want to optimize (see templatetypedef's comment). If you just want to reduce code footprint you may do something like this
// let's assume you have an Option interface with isTrue() method
// let's assume you have an Action interface with performAction() method
Map<Option,Action> actions = new HashMap<Option,Action>();
// initialize actions with instance of your objects so that you have:
// optionA -> actionA
// optionB -> actionB
// etc.
// this is done only once
Option[] currentOptions;
// read the current option values and put them in an array
for (int i = 0; i < currentOptions.lengt; i++) {
if (currentOptions[i].isTrue())
actions.get(currentOptions[i]).performAction();
}
If the method is the same for all objects, then create a option-to-object hash table and call the method based on the option.
HashMap<Option,ActionObject> map ;
for (Option option: map.keySet()) {
if (optionIsTrue(option)) {
map.get(option).performAction() ;
}
}
精彩评论