부울 속성이 많은 열거 형


11

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

각 페이지에는 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 개의 부울이있을 것이므로 생성자를 실제로 크게 만들고 페이지를 추가 할 때 선언을 얻는 것이 어려울 수 있습니다. 누구든지 더 나은 솔루션을 가지고 있습니까?

답변:


13

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

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

나는 이것에 대해 생각했지만 여기서 개발자는 "사용 가능한 페이지입니까?", "장바구니가 있습니까?" 등등. 그것들이 많으면 쉽게 잊어 버립니다.
Joffrey

5
@Joffrey 당신이 그것에 대해 생각할 때, 10 개의 부울을 가졌다 고해서 적어도 그들이 생각하는 대답이 아니라 대답을하도록 강요하지는 않습니다. 가장 가능성이 높은 시나리오는 다른 페이지의 정의를 복사하거나 IDE가 모든 매개 변수를로 채우도록 false한 다음 하나 또는 두 개 (아마도 잘못된 것을 추적하기가 어려울 수 있음)로 수정하도록하는 것입니다. 바보로부터 완벽하게 보호 할 수는 없으며 개발자가 올바른 일을하도록 신뢰해야하는 시점이 있습니다.
biziclop

맞다, 나는 이것을 이런 식으로 생각하지 않았다 :) 그리고 나는 부울에 의해 주어진 작은 여분의 "완전한 증거"가 책임의 저하 가치가 있다고 생각하지 않기 때문에 아마도 vararg 솔루션을 사용할 것입니다. 통찰력 주셔서 감사합니다!
Joffrey

1
좋은 해결책입니다. 6502로 코딩 된 부분은 모든 것을 비트로 넣기를 원하지만. :-)
user949300

@ user949300 내가 생각한 첫 번째 vararg와 같은 솔루션은 실제로 비트 마스크였습니다.) 그러나 enum 유형의 진정한 vararg는 더 깨끗합니다
Joffrey
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.