Уменьшите количество переменных, используемых в моих операторах if-else - PullRequest
1 голос
/ 20 сентября 2011

Я знаю, это звучит ужасно, но в моей java-программе у меня есть около 100 операторов if-else, все из которых содержат 3 переменные, которые должны оставаться уникальными для этих блоков if-else, 1 - это флаг, используемый для определения того, когда это происходит в первый раз. когда он попадает в этот блок if-else, а остальные 2 являются строками и временными переменными, хранящими те данные, которые использовались в прошлый раз, когда он проходил через этот блок if-else, так что их можно сравнить с данными, проходящими через это время, извините, если это звучит неаккуратно, я ненавижу идею иметь так много блоков if-else, но сейчас я больше беспокоюсь о переменных, потому что если я сделаю 3 переменные для каждого блока, который является дополнительными 300 переменными. Любые предложения о том, что я мог бы реализовать, чтобы уменьшить количество переменных, одна идея у меня была 1 массив для всех флагов, а затем 2d массив, содержащий 2 строки для каждого блока if-else. Спасибо Говядина.

Отредактировано: , чтобы показать пример первых двух блоков if-else, все остальные имеют один и тот же код внутри только с разными именами для флага и временных переменных ex. ac101Flag, tempAC101Start, tempAC101End

                // AC 101
                if (room.equals("FEB 2009") || room.equals("FEB 2011") ||room.equals("FEB 2013") || room.equals("FEB 2015") || room.equals("FEB 2017") ||
                        room.equals("FEB 2021") || room.equals("FEB 2023") || room.equals("FEB 2025") || room.equals("FEB 2027") || room.equals("FEB 2029")) {
                    instanceNum = 4;
                    devID = 130200;
                    if (ac101Flag == false) {
                        Delete();
                        Insert();
                        ac101Flag = true;
                        tempAC101Start = Double.parseDouble(finalStart.substring(0, 5).replace(':', '.'));
                        tempAC101End = Double.parseDouble(finalEnd.substring(0, 5).replace(':', '.'));
                    }
                    //Insert();
                    else if (tempAC101Start <= (Double.parseDouble(finalStart.substring(0, 5).replace(':', '.'))) && tempAC101End >= Double.parseDouble(finalEnd.substring(0, 5).replace(':', '.'))) {

                    }
                    else
                    {
                        Insert();
                        tempAC101Start = Double.parseDouble(finalStart.substring(0, 5).replace(':', '.'));
                        tempAC101End = Double.parseDouble(finalEnd.substring(0, 5).replace(':', '.'));
                    }   
                }
                // AC 102
                else if(room.equals("FEB 1130")) {
                    instanceNum = 4;
                    devID = 130400;
                    if (ac102Flag == false) {
                        Delete();
                        Insert();
                        ac102Flag = true;
                        tempAC101Start = Double.parseDouble(finalStart.substring(0, 5).replace(':', '.'));
                        tempAC101End = Double.parseDouble(finalEnd.substring(0, 5).replace(':', '.'));
                    }
                    //Insert();
                    else if (tempAC101Start <= (Double.parseDouble(finalStart.substring(0, 5).replace(':', '.'))) && tempAC101End >= Double.parseDouble(finalEnd.substring(0, 5).replace(':', '.'))) {

                    }
                    else
                    {
                        Insert();
                        tempAC101Start = Double.parseDouble(finalStart.substring(0, 5).replace(':', '.'));
                        tempAC101End = Double.parseDouble(finalEnd.substring(0, 5).replace(':', '.'));
                    }   
                }

Ответы [ 4 ]

2 голосов
/ 20 сентября 2011

Единственная проблема, которая не была ясна в вашем вопросе, заключалась в том, насколько похожи блоки if. В любом случае у вас может быть класс предшественников блока if с общим интерфейсом, и, следуя приведенным выше идеям, создайте экземпляр для каждого блока if,с переменными состояния в качестве части объекта, затем создайте коллекцию этих объектов, а затем просто переберите коллекцию блоков if, вызывающих каждый из них по очереди.Каждый экземпляр if-блока наследовал бы общую переменную и был бы уникальным для объекта (инкапсуляция), и каждый блок мог бы иметь специальный код для каждого особого случая для каждого блока if.

Издержки кода для определения каждого экземпляра были быбольше, и время выполнения будет больше, но вам не нужно будет создавать отдельные переменные, и вы будете динамически смешивать, сопоставлять и изменять порядок блоков if, если хотите.

2 голосов
/ 20 сентября 2011

РЕДАКТИРОВАТЬ: просто чтобы дать более конкретную демонстрацию ответа, я думаю, что вы хотите что-то вроде:

class Foo // Rename this!
{
    private double start;
    private double end;
    private boolean flag;

    public void handleValue(double newStart, double newEnd)
    {
        // Insert code here
    }
}

private static void insertFoo(Map<String, Foo> map, String... rooms)
{
    Foo foo = new Foo();
    for (String room : rooms)
    {
        map.put(room, foo);
    }
}

...
HashMap<String, Foo> map = new HashMap<String, Foo>();
insertFoo(map, "FEB 2009", "FEB 2011", ...);
insertFoo(map, "FEB 1130");

Тогда в вашем цикле просто используйте:

Foo foo = map.get(room);
foo.update(start, end); // Parsed from the current finalStart/finalEnd

Трудно сказать наверняка, не видя ваш код, но он звучит , как будто вы должны заключить все это в структуру данных:

  • Три переменные (состояние и Фальг)
  • «Нечто» для представления состояния части if. Точная природа этого будет зависеть от того, что у вас есть

Затем вы можете просмотреть список этих ConditionBlock объектов (или как вы их называете) и проверить, «совпадает» ли блок в текущем контексте, обновив его, где необходимо.

Если вы можете дать нам небольшой пример исходного кода, мы, вероятно, сможем довольно легко его реорганизовать.

РЕДАКТИРОВАТЬ: Поскольку я, по-видимому, не ясно о введении локальных переменных для разбора в одном месте, я бы сделал что-то вроде этого (как один сначала шаг):

// TODO: Don't use double here - it's completely inappropriate. Use
// BigDecimal if you absolutely must, but preferrably use a time-related
// type, e.g. something from Joda Time (http://joda-time.sf.net)
double parsedStart = Double.parseDouble(finalStart.substring(0, 5)
                                                  .replace(':', '.'));

// TODO: Put all of these constants in a HashSet<String> and use contains
if (room.equals("FEB 2009") || 
    room.equals("FEB 2011") ||
    room.equals("FEB 2013") || 
    room.equals("FEB 2015") || 
    room.equals("FEB 2017") ||
    room.equals("FEB 2021") || 
    room.equals("FEB 2023") || 
    room.equals("FEB 2025") || 
    room.equals("FEB 2027") || 
    room.equals("FEB 2029")) {

    instanceNum = 4;
    devID = 130200;
    // TODO: Change to if (!ac101Flag)
    if (ac101Flag == false) {
        // TODO: Rename these methods to follow Java naming conventions
        Delete();
        Insert();
        ac101Flag = true;
        tempAC101Start = parsedStart;
        tempAC101End = parsedEnd;
    }
    //Insert();
    else if (tempAC101Start <= parsedStart && tempAC101End >= parsedEnd) {

    }
    else
    {
        Insert();
        tempAC101Start = parsedStart;
        tempAC101End = parsedEnd;
    }   
}
1 голос
/ 20 сентября 2011

Рассмотрите возможность использования полиморфизма.

Каждый блок имеет поведение и данные.Поэтому сделайте каждый блок объектом, который реализует интерфейс.

Каждый объект блока может удерживать объект состояния, как предлагает @Jon Skeet.

Сначала выберите объект.Это может быть с вашими существующими операторами if или, если возможно, с помощью более простого отображения.

Затем просто вызовите метод для выбранного объекта.

class BlockState {
  boolean hasBeenCalled = false;
  String last1;
  String last2;
}

class Block1 implements Runnable {
   BlockState m_blockState = new BlockState();
   public void run() { ... }
}

... 
class BlockN implements Runnable {
   BlockState m_blockState = new BlockState();
   public void run() { ... }
}

...

class LongChainOfIfs
  void foo() {
     Runnable runnable = null;
     if ( ... ) runnable = ...
     else if ( ... ) runnable = ...
     ...
     else runnable = ...

     runnable.run();
   }
 }
1 голос
/ 20 сентября 2011

Объявите класс, который имеет три поля. Создайте массив этого класса для количества экземпляров, которое вам нужно поддерживать.

private class Vars{
   int val1;
   String val2, val3;
}

private Vars[] allVars = new Vars[300];

void myMethod(){
   if (condition1){
       allVals[0].val1 = ...;
   }
}
...