web-dev-qa-db-ja.com

多数のブールプロパティを持つ列挙型

私は現在、ユーザーに返されるページに基づいてサーバーロジックを調整する必要があることが多いWebアプリケーションに取り組んでいます。

各ページには4文字のページコードが与えられ、これらのページコードは現在、静的文字列としてクラスにリストされています。

_public class PageCodes {
    public static final String FOFP = "FOFP";
    public static final String FOMS = "FOMS";
    public static final String BKGD = "BKGD";
    public static final String ITCO = "ITCO";
    public static final String PURF = "PURF";
    // etc..
}
_

そして多くの場合、コードには次のようなコードがあります(1st form):

_if (PageCode.PURF.equals(destinationPageCode) || PageCodes.ITCO.equals(destinationPageCode)) {
    // some code with no obvious intent
} 
if (PageCode.FOFP.equals(destinationPageCode) || PageCodes.FOMS.equals(destinationPageCode)) {
    // some other code with no obvious intent either
} 
_

これは、これらのページの一般的なプロパティがコードの作成者をここにまとめるように導いた原因を示していないため、読みにくいものです。理解するには、ifブランチのコードを読む必要があります。

現在のソリューション

これらのifsは、さまざまなクラスのさまざまな人々によって宣言されたページのリストを使用して部分的に簡略化されています。これにより、コードは(2nd form)のようになります。

_private static final List<String> pagesWithShoppingCart = Collections.unmodifiableList(Arrays.asList(PageCodes.ITCO, PageCodes.PURF));
private static final List<String> flightAvailabilityPages = Collections.unmodifiableList(Arrays.asList(PageCodes.FOMS, PageCodes.FOFP));

// later in the same class
if (pagesWithShoppingCart.contains(destinationPageCode)) {
    // some code with no obvious intent
} 
if (flightAvailabilityPages.contains(destinationPageCode)) {
    // some other code with no obvious intent either
} 
_

...これは意図をはるかによく表します。だが...

現在の問題

ここでの問題は、ページを追加する場合、理論的には、ページをif()またはそのようなリストに追加する必要があるかどうかを見つけるために、すべてのコードベースを調べる必要があるということです。

これらのすべてのリストを静的定数としてPageCodesクラスに移動した場合でも、新しいページがこれらのリストのいずれかに収まるかどうかを確認し、それに応じて追加するための開発者の訓練が必要です。

新しいソリューション

私の解決策は、各ページに設定する必要のあるいくつかのプロパティが含まれる列挙型を作成することでした(ページコードの有限の既知のリストがあるため)。

_public enum Page {
    FOFP(true, false),
    FOMS(true, false),
    BKGD(false, false),
    PURF(false, true),
    ITCO(false, true),
    // and so on

    private final boolean isAvailabilityPage;
    private final boolean hasShoppingCart;

    PageCode(boolean isAvailabilityPage, boolean hasShoppingCart) {
        // field initialization
    }

    // getters
}
_

次に、条件付きコードは次のようになります(番目の形式)。

_if (destinationPage.hasShoppingCart()) {
    // add some shopping-cart-related data to the response
}
if (destinationPage.isAvailabilityPage()) {
    // add some info related to flight availability
}
_

とても読みやすいです。さらに、誰かがページを追加する必要がある場合、彼/彼女はforcedであり、各ブール値とこれが彼の新しいページの真または偽。

新しい問題

私が目にする1つの問題は、このようなブール値が10になる可能性があることです。これにより、コンストラクターが非常に大きくなり、ページを追加するときに宣言を正しく取得することが困難になる場合があります。誰かがより良い解決策を持っていますか?

11
Joffrey

ブール値を使用する代わりに、アイデアをさらに一歩進めて、ページ機能の列挙型を定義できます。

これにより、ページへの機能の追加/削除が容易になり、30から40の潜在的な機能がある場合でも、ページ定義を即座に読み取ることができます。

public enum PageFeature {
    AVAIL_PAGE,
    SHOPPING_CART;
}

public enum Page {
    FOFP(AVAIL_PAGE),
    FOMS(AVAIL_PAGE),
    BKGD(),
    PURF(SHOPPING_CART, AVAIL_PAGE),

    private final EnumSet<PageFeature> features;

    PageCode(PageFeature ... features) {
       this.features = EnumSet.copyOf(Arrays.asList(features));
    }

    public boolean hasFeature(PageFeature feature) {
       return features.contains(feature);
    }
 }
13
biziclop