减少我的if-else语句中使用的变量数

问题描述:

我知道这听起来很糟糕,但在我的Java程序中,我有大约100条if-else语句,全部包含3个变量,这些变量必须保持对这些if-else块的唯一性, 1是一个标志,用于知道何时第一次触及if-else块,其他2个都是字符串,并且是临时变量,用于保存上次运行该if-else块时使用的数据,所以它可以与这段时间的数据进行比较,如果听起来很sl sorry,抱歉,我讨厌有这么多if-else块的想法,但现在我更关心变量,因为如果我为每个块创建3个变量这是一个额外的300个变量。我可以实现的任何建议,以减少变量的数量,我有一个想法是1阵列的所有标志,然后2d阵列持有2个字符串为每个if-else块。谢谢牛肉。减少我的if-else语句中使用的变量数

编辑:显示前2个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(':', '.')); 
        } 
       } 
+3

显示该代码的第一部分if/else块。 – nos

+0

@nos参考编辑示例代码 – Beef

编辑:只是为了给出答案的一个更具体的论证,我觉得你想要的东西,如:

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 

很难说没有看到你的代码,但它听起来像y OU应该封装所有这在数据结构中:

  • 三个变量(状态和falg)
  • “东西”来表示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; 
    } 
} 
+0

请参阅编辑以查看代码示例 – Beef

+0

@Beef:if/else块的逻辑是否存在任何模式?你有没有任何理由为什么你到处调用'parseDouble' *而不是只在一个地方? –

+0

我在每个地方都使用'parseDouble'的原因是,每次进入if-else块时,finalStart和finalEnd的值都会不同,并且可能会返回到块,因此如果它进入AC101,它会保存那些临时工,在它回到AC101之前可能会跳到50个其他块,但是我仍然需要获得AC101数据以便它回来时,如果这有意义的话 – Beef

声明一个具有三个字段的类。为需要维护的实例数量创建此类的数组。

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

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

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

考虑使用多态性。

每个块都有行为和数据。因此,使每个块实现一个接口的对象。

每个块对象可以保存到状态对象,如@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(); 
    } 
} 

的一个问题,这不是你的问题清楚是多么的相似,如果块,在任何情况下,你可能有一个,如果块祖先类具有共同inteface并采用上面的思路,创建一个实例每个if块,将状态变量作为对象的一部分,然后创建这些对象的集合,然后循环遍历每个依次调用每个对象的集合。每个if-block实例都会继承公共变量,并且对于对象来说是唯一的(封装),并且每个块都可以针对每个if块的每种特殊情况定制代码。

定义每个实例的代码开销会更大,并且执行时间会更长,但是您不必创建独立变量,并且您可以混合匹配并根据需要动态更改if块的顺序。