부울 속성이 많은 열거 형 현재 클래스에 정적

현재 웹 응용 프로그램을 개발 중이며 사용자에게 반환 될 페이지를 기반으로 일부 서버 논리를 조정 해야하는 경우가 있습니다.

각 페이지에는 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이해하기 위해서는 지점 의 코드를 읽어야합니다 .

현재 솔루션

if클래스들은 다른 클래스의 다른 사람들이 선언 한 페이지 목록을 사용하여 부분적으로 단순화되었습니다. 이렇게하면 코드가 ( 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
}

그런 다음 조건부 코드는 이제 다음과 같습니다 ( 3 번째 형식 ).

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

읽을 수있는 또한 누군가가 페이지를 추가해야하는 경우 각 부울에 대해 그리고 새 페이지에 대해 이것이 참인지 거짓인지를 강요해야 합니다.

새로운 문제

내가 볼 수있는 한 가지 문제는 이와 같은 10 개의 부울이있을 것이므로 생성자를 실제로 크게 만들고 페이지를 추가 할 때 선언을 얻는 것이 어려울 수 있습니다. 누구든지 더 나은 솔루션을 가지고 있습니까?



답변

아이디어를 한 단계 더 발전 시켜서 부울을 사용하는 대신 페이지 기능에 대한 열거를 정의 할 수 있습니다.

이를 통해 페이지에 기능을 쉽게 추가 / 제거하고 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);
    }
 }


답변