8

在我的 java 应用程序中,我有大量的条件只决定一个动作。我的问题是如何让它看起来不错(我使用 NetBeans,所以我更喜欢不会被其代码格式化功能破坏的解决方案)。我还希望有尽可能少的 if/else 语句,因为我认为它会使其更快。

我原来的代码是一团糟,所以我做了一个动作图:充满条件的复杂动作图. 如果您想玩它,请复制一份。请记住,该图对于 UML语法并不完美,部分原因是我使用谷歌文档制作的。

这是代码:

if (!config.get("checkForSpecials") || event.isNotSpecial()) {
    if (config.get("filterMode").equals("blacklist")) {
        if (!itemFilter.contains(event.getItem().getName())) {
            item.process();
        }
    } else if (config.get("filterMode").equals("whitelist")) {
        if (itemFilter.contains(event.getItem().getName())) {
            item.process();
        }
    } else {
        item.process();
    }
}

有两点我不喜欢它 - 条件不太清楚(特别是当我展开完整的方法名称和配置字符串时),以及 process 方法调用存在 3 次这一事实。

4

4 回答 4

7

将布尔值分解并缓存来自方法调用的返回值有助于澄清代码。

此外,将所有结果绘制在逻辑表上会有所帮助。我使用这个工具来提供帮助。

使用链接工具:

A: config.get("filterMode").equals("blacklist")
B: config.get("filterMode").equals("whitelist")
C: filterContainsName (see below)

该工具产生:

(!A && !B) || (!A && C) || (A && !C)

这导致下面的代码(用一个小调整替换(!A && C)(B && C)

boolean filterContainsName = itemFilter.contains(event.getItem().getName());
boolean useBlacklist       = config.get("filterMode").equals("blacklist");
boolean useWhitelist       = config.get("filterMode").equals("whitelist");

if (!config.get("safeMode") || event.isSafe()) {
    if((!useBlackList && !useWhiteList) ||
       ( useWhiteList &&  filterContainsName) ||
       ( useBlackList && !filterContainsName)) {
        item.process();
    }
}
于 2013-01-10T21:13:54.860 回答
4

使用地图。映射的键是条件/案例,值是包含该条件逻辑的单个方法类/匿名用户接口。每当您遇到某种情况/情况时,您只需在地图中查找并执行相关功能。这样,您甚至可以将您的逻辑按条件拆分为单独的类(如果为了代码美观而需要)。作为额外奖励,当条件数 > 10 时,您可能会获得性能奖励。

于 2013-01-10T21:06:27.040 回答
3

对我来说看起来不错。也许您可以隔离调用方法的有效条件item.process()以使其更易于理解。

if (!config.get("safeMode") || event.isSafe()) {
    if (isItemValidForProcess(config, itemFilter, event)) {
        item.process();
    }
}

boolean isItemValidForProcess(config, itemFilter, event) {
    String filterMode = config.get("filterMode");
    if (filterMode.equals("whitelist")) {
        return itemFilter.contains(event.getItem().getName());
    }
    if (filterMode.equals("blacklist")) {
        return !itemFilter.contains(event.getItem().getName());
    }
    return true;
}
于 2013-01-10T21:14:26.160 回答
0

信不信由你,该图并没有那么复杂:) 没有循环,它是线性的。

这是一个实现它的伪代码

void action()

    if <sort out specials>
        if <is it special>
            return;

    if <check for unsafe items>
        if not <safe items list contains item>
            return;

    if <filter status = on>
        if < filter mode = whitelist>
            if not <item is on filter>
                return;
        else // black list
            if not <item is on filter>
                return;

    // finally!            
    [process item]

对于非常复杂的图表,答案是 ... goto ...

于 2013-01-10T22:58:25.033 回答