8

私のJavaアプリケーションには、たった1つのアクションを決定する膨大な条件があります。私の質問は、見栄えを良くする方法です (私は NetBeans を使用しているので、コードの書式設定機能によって壊れないソリューションを好みます)。また、if/elseステートメントの量をできるだけ少なくしたいと思います。これにより、高速になると思います

元のコードがめちゃくちゃだったので、アクション ダイアグラムを作成しました: 条件だらけの複雑なアクション図. 遊びたい場合はコピーしてください。この図は、Google ドキュメントを使用して作成したため、 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();
    }
}

気に入らない点が 2 つあります。条件が明確でないこと (特に、完全なメソッド名と構成文字列を展開する場合) と、プロセス メソッド呼び出しが 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 に答える