繁体   English   中英

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

[英]Reduce the number of variables used in my if-else statements

我知道这听起来很糟糕,但是在我的Java程序中,我有大约100个if-else语句,所有语句都包含3个对于if-else块必须保持唯一的变量,其中1个是用来知道何时第一次击中该变量的标志if-else块,另外两个都是字符串,并且是临时变量,用于保存上一次通过该if-else块时使用的数据,因此可以将其与这段时间内运行的数据进行比较,如果抱歉听起来很草率,我讨厌有那么多if-else块的想法,但是现在我更关心变量,因为如果我为每个块制作3个变量,那就是额外的300个变量。 关于可以减少变量数量的某些建议,我的一个想法是为所有标志分配1个数组,然后为每个if-else块保留2个字符串的2d数组。 谢谢牛肉。

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

编辑:只是为了给出答案的更具体的说明,我想你想要类似的东西:

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

没有看代码很难确定,但是听起来您应该将所有这些封装在数据结构中:

  • 三个变量(state和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;
    }   
}

您的问题中尚不清楚的一个问题是if块的相似性,无论如何,您可能都拥有一个具有相同接口的if块祖先类,并采用上述思想,为每个if块创建一个实例,并带有状态变量作为对象的一部分,然后创建这些对象的集合,然后循环遍历if块的集合,依次调用每个块。 每个if块实例都将继承公共变量,并且对于对象是唯一的(封装),并且每个if块的每种特殊情况都可以具有量身定制的代码。

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

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

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();
   }
 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM