Как я могу избежать повторения if-оператора? - PullRequest
0 голосов
/ 25 марта 2011

Я пишу Java-приложение для обработки файла журнала, содержащего миллионы строк. В программе есть такой псевдокод

if(optionA is On)
  call object A's method

if(optionB is On)
  call object B's method

if(optionC is On)
  call object C's method
...

Опции в IFs - это значение конфигурации, полученное из файла конфигурации. Этот псевдокод называется вкаждая строка журнала, так называемые миллионы времени

Из-за скорости и простоты я хочу удалить этот мульти IF.Видеть такое много IFs мне неприятно.Является ли хороший способ обойти это раздражающее IFs?

Ответы [ 4 ]

1 голос
/ 25 марта 2011

Если объекты имеют общий интерфейс, вы можете создать метод, подобный этому:

private void callOptional(myInterface obj, boolean flag) {
  if (option) obj.method();
}

Таким образом, вы исключили IF.Но у вас все еще есть длинный список общего кода.Чтобы сделать его более СУХИМ, я бы добавил ссылку на объект в список, где вы храните параметры, а затем просто выполните цикл for:

for (OptionObjectPair ooPair : optionObjectList) {
  callOptional(ooPair.obj, ooPair.flag)
}

Затем вы даже можете изменить интерфейс метода callOptional напринять OptionObjectPair напрямую.

0 голосов
/ 25 марта 2011

Это действительно зависит от того, что вы хотите оптимизировать (см. Комментарий templatetypedef).Если вы просто хотите уменьшить объем кода, вы можете сделать что-то вроде этого

// 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();
}
0 голосов
/ 25 марта 2011

Длинные последовательности if операторов не являются всегда плохой вещью.Если вы хотите сделать это правильным способом , вам нужно определить отображение ваших опций на их "обработчики" в структуре данных, а не жестко кодировать их в операторах if.

Выможет определить интерфейс с одним методом и иметь A, B и C (в вашем примере) для его реализации:

public interface OptionHandler { // For lack of a better name...
    void handleOption(); // You could pass parameters here
}

Затем вы можете определить карту параметров для их обработчиков:

private final Map<Option, OptionHandler> optionHandlers = new HashMap<Option, OptionHandler>();

Затем вы замените свою последовательность if операторов на что-то вроде:

for (Option option : options) {
    if (!option.isOn()) {
        // Skip off option
        continue;
    }
    OptionHandler handler = optionHandlers.get(option);
    if (handler != null) {
        handler.handleOption();
    }
}
0 голосов
/ 25 марта 2011

Если метод одинаков для всех объектов, создайте хеш-таблицу для объекта и вызовите метод на основе этого параметра.

HashMap<Option,ActionObject> map ;
for (Option option: map.keySet()) {
    if (optionIsTrue(option)) {  
        map.get(option).performAction() ;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...