【问题标题】:Getting around similar-variable repetition in if statements绕过 if 语句中的类似变量重复
【发布时间】:2012-07-11 14:31:14
【问题描述】:

我相信我对避免代码重复这一老生常谈的问题提出了稍微不同的看法。设置是相当标准的——一堆 if 语句采取类似的行动。下面是一个简短的示例。

我正在尝试找出解决此类情况的最佳方法,包括代码效率、紧凑性和程序员的易用性。请注意,解决这些问题的单独解决方案很好,确实更可取,因为我怀疑一个解决方案会满足所有三个问题。

例如,想到的一种可能的解决方案似乎笨拙而缓慢,尤其是在像 android 这样的移动设备上,而且它只有在变量是实例变量时才有效,而不仅仅是本地变量(这可能非常情况就是这样)。这个想法涉及一个 for 语句,其初始化表达式将使用双括号初始化来用与所涉及的变量相对应的字符串填充哈希映射(例如,“installText”映射到“installPermission”),然后 for 循环将包含一个 if- -else-if--else-if 子句,它将使用反射通过存储在 hashmap 中的变量名称来访问变量。

我怎样才能做得更好?提前感谢您的时间和建议!

if (installText.equals("Default")) {
    installPermission = DEFAULT;
} else if (installText.equals("Allow")) {
    installPermission = ENABLED;
} else if (installText.equals("Disallow")) {
    installPermission = DISABLED;
}
if (uninstallText.equals("Default")) {
    uninstallPermission = DEFAULT;
} else if (uninstallText.equals("Allow")) {
    uninstallPermission = ENABLED;
} else if (uninstallText.equals("Disallow")) {
    uninstallPermission = DISABLED;
}
if (runText.equals("Default")) {
    runPermission = DEFAULT;
} else if (runText.equals("Allow")) {
    runPermission = ENABLED;
} else if (runText.equals("Disallow")) {
    runPermission = DISABLED;
}

【问题讨论】:

  • 也许您可以使用Map<String, State>?似乎您的所有 if 语句都可以替换为 fooPermission = map.get(fooText)
  • 我真的很好奇为什么你的变量是基于字符串的。你能解释一下你在这种情况下到底在做什么吗?我们或许可以通过更多信息提出更好的解决方案。

标签: java android loops reflection


【解决方案1】:

您使用的是 Java 7 吗?在这种情况下,您可以使用现在支持 String 值的 switch 语句:

switch(installText) {
    case "Allow":
        installPermission = ENABLED;
        break;
    case "Disallow":
        installPermission = DISABLED;
        break;
    case "Default":
        installPermission = DEFAULT;
        break;  
    default:
        installPermission = DEFAULT;
        break;  
}

【讨论】:

  • 虽然我同意这个开关很棒,但它仍然没有重构代码。
  • 但是它需要更短吗?代码可读、可理解且易于扩展。我没有理由用更多的数据结构来复杂化它。
  • 哦,太好了,我不知道 SE 7 中添加的内容。这在某些情况下肯定会派上用场,而且肯定比众多“ifs”更可取,但有几个问题仍然存在。假设开关在 for 循环中,仍然存在用适当的变量(安装、卸载、运行等,假设更多)替换“installText”和“installPermission”的问题。另外,虽然我是从学术角度提出问题,但我在开发 android 时遇到了灵感,所以这里没有 Java 7。非常感谢您的回答内容!
【解决方案2】:

将值检查提取到一个单独的方法(我正在重新使用 Simeon Visser 的部分答案并进行改进):

public String getPermission(String permission)
{
    String state = null;

    // If this is Java 7:
    /*
    switch(permission)
    {
        case "Allow":
             state = ENABLED;
             break;
        case "Disallow":
             state = DISABLED;
             break;
        case "Default":
        default:
             state = DEFAULT;
             break;  
    }
    */

    // If this is Java < 7:
    if (permission.equalsIgnoreCase("allow"))
        state = ENABLED;
    else if (permission.equalsIgnoreCase("disallow"))
        state = DISABLED;
    else
        state = DEFAULT;

    return state;
}

public void callingMethod(String permission)
{
     installPermission = getPermissionState(permission);
     uninstallPermission = getPermissionState(permission);
     runPermission = getPermissionState(permission);
}

此外,ENABLEDDISABLEDDEFAULT 应该简单地定义为类中的常量:

public static final String ENABLED = "ENABLED";
public static final String DISABLED = "DISABLED";
public static final String DEFAULT = "DEFAULT";

但是,我仍然无法通过反射来理解您的想法......?我认为这里没有必要,除非您有一个用例,其代码目前没有显示......?

【讨论】:

  • 啊,是的,这当然是处理多个变量的可行选择。消除数据结构的复杂性。我仍然对这些替代方案和其他替代方案感兴趣,因为我将这个问题定位为来自学术观点(尽管正如我在对西蒙的回答的评论中指出的那样,灵感来自我正在从事的一个项目安卓)。感谢您的回答!
【解决方案3】:

如果您 100% 确定,字符串值将是这三个值之一。那么你可以这样做:

Map<String,String> map;
map.put("Default", "Default");
map.put("Allow", "Allow");
map.put("Disallow", "Disallow");
installPermission = map.get(installText);
uninstallPermission = map.get(uninstallText);
runPermission = map.get(runText);

干杯

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-07-05
    • 2017-10-25
    • 2015-11-13
    • 2015-06-29
    • 1970-01-01
    • 2021-04-21
    • 2019-08-20
    • 2014-08-26
    相关资源
    最近更新 更多