2013-06-21 1 views
2

나는 데이터 객체의 네 가지 유형이있는 경우했습니다 :생성자 인수에 따라 특정 하위 유형을 인스턴스화

class DataTypeAlpha extends DataType 
class DataTypeBeta extends DataType 
class DataTypeGamma extends DataType 
class DataTypeDelta extends DataType 

와 GUI 프레임 워크에서 네 가지의 TreeNode 유형, 랩 된 데이터 형식에 고유 각각 :

class AlphaTreeNode extends MyAppTreeNode 
... 

이제는 DataType 인스턴스가 있고 MyAppTreeNode의 새 인스턴스가 필요한 패턴이 자주 있습니다. 나는 두 가지 해결책을 본다. 해결책 하나

class DataType { 
    // Instantiates and returns the appropriate MyAppTreeNode for this DataType 
    abstract MyAppTreeNode createTreeNode(); 
} 

용액 2 : 하나의 다형성을 사용

class MyAppTreeNode { 
    static MyAppTreeNode createTreeNodeForDataType(DataType dataType) { 
    if(dataType instanceOf DataTypeAlpha) return new AlphaTreeNode((DataTypeAlpha)dataType) 
    else if (dataType instanceOf DataTypeBety) return new BetaTreeNode((DataTypeBeta)dataType) 
    else if ... 
    else if ... 
    else throw new IllegalArgumentException(); 
    } 
} 

솔루션보다 짧은 "고급"이다. 하지만 DataType 클래스는 내가 사용하는 GUI 프레임 워크에 대한 지식이 없다는 것을 선호합니다. 어쩌면 두 개의 다른 GUI 프레임 워크를 사용할 수도 있습니까?

세 번째 해결책이 있습니까? 이 질문에 Guice 태그를 추가했습니다. Guice 나 다른 의존성 주입 라이브러리에 도움이 될만한 기능이 있습니까? 나는이에 대한 공장 패턴을 사용합니다 물론

  • 하지만 공장 내부에 여전히 문제로 남아있어 :

    비슷한 질문을 통해 찾고.

+0

제네릭과 비슷한 일반적인 해결책을 사용하는 방법은 무엇입니까? http://insidecoding.com/2011/09/07/the-generic-dao-pattern-in-java-with-spring-3-and-jpa-2-0/ –

답변

1

당신은 이것을 위해 방문자에 영감을받는 방법을 사용할 수 있습니다. 일반적으로 모든 DataType 객체는 accept 메서드를 갖지만 일반 방문자 패턴과 달리 자식을 통과하지 않으며 값을 반환합니다. 너무 많은 혼동을 피하기 위해 대신 operator에 대해 accept에 전달 된 호출 객체를 허용합니다. 트릭은 acceptoperators이 제네릭 유형을 반환하도록하는 것입니다.

public abstract class DataType { 
    public abstract <T> T accept(Operator<T> op); 
} 

public interface Operator<T> { 
    T operateAlpha(DataTypeAlpha data); 
    T operateBeta(DataTypeBeta data); 
    ... 
} 

public class DataTypeAlpha extends DataType { 
    public <T> T accept(Operator<T> op) { 
    return op.operateAlpha(this); 
    } 
} 
.... 

GUI에 당신이 그래서 짧고 간단한 대답은

public class TreeNodeFactory implements Operator<MyAppTreeNode> { 
    public MyAppTreeNode operateAlpha(DataTypeAlpha data) { 
     return new AlphaTreeNode(data); 
    } 
    ... 
} 

public class MyAppTreeNode { 
    static TreeNodeFactory factory = ...; 
    static MyAppTreeNode createTreeNodeForDataType(DataType dataType) { 
    return dataType.accept(factory); 
    }  
} 
+0

나는 이것을 좋아한다. 우아하고 타입 안전하며 짧습니다. 데이터 유형에 대해 여러 가지 작업을 할 수 있습니다. 나는 여전히 대체 솔루션에 대해 궁금합니다. –

+0

감사합니다. 호기심이 만족되면 좋아하는 것을 받아들이십시오.) – Tobber

0

이있을 것이다

그래서 코드는 데이터 모델에서 이런 일을 할 것 생성자 수 만 반환 자체 유형. 하위 유형이나 다른 클래스가없고 재사용 된 인스턴스가없고 null - 해당 유형의 새 인스턴스 만. 따라서 여기 생성자의 범위 밖에서 작동하는 솔루션을 찾고 있습니다. 가장 간단하고 가장 보편적 인 해결 방법은 포함 된 클래스의 새 인스턴스 나 기존 인스턴스를 반환하고 아무런 문제없이 서브 클래스 또는 null을 반환 할 수있는 정적 팩토리 메서드 (일반적으로 newInstance 또는 getInstance)를 작성하는 것입니다.

해결책 1과 2에 대한 귀하의 포인트가 유효합니다. 데이터 유형이 UI를 인식하지 못하게하는 것이 좋을 것입니다. 상황에 따라 (네 가지 유형 만 있으면) 아마도 솔루션 2를 선택하게 될 것입니다. 유형의 혼합을 나무 -Bittenus의 솔루션에 넣는 GUI의 꽤 일반적인 요구 사항은 아마도 그만한 가치가 있습니다. (이런 종류의 일을 한 번만 수행하면 많은 코드를 처리 할 수 ​​있습니다.)

당신은 어떻게 든 성장 당신의 유형의 수를 예상하지만 성장 결코 당신의 작업은 하나의 대안은 다음과 같이 나타납니다 별도의 공장으로 다형성 생성을 추출하는 경우 : 다음

class MyAppTreeNode { 
    interface Factory { 
    MyAppTreeNode create(DataType type); 
    } 
} 

class AlphaTreeNode extends MyAppTreeNode { 
    static class Factory implements MyAppTreeNode.Factory { 
    @Override public AlphaTreeNode create(DataType type) { 
     // Remember, in an override your return types can be more-specific 
     // but your parameter types can only be less-specific 
     return new AlphaTreeNode((DataTypeAlpha) type); 
    } 
    } 
} 

을 수행 할 수 있습니다 보다 가치

private static Map<Class<?>, MyAppTreeNode.Factory> factoryMap = new HashMap<>(); 
static { 
    factoryMap.put(DataTypeAlpha.class, new AlphaTreeNode.Factory()); 
    // ... 
} 

public static createTreeNode(DataType type) { 
    return factoryMap.get(type.getClass()).create(type); 
} 

더 문제 : 단지지도 (하지만 더 나은 의미에 대한 구아바의 ImmutableMap을 고려) 할?아마도 대부분의 경우.하지만 Guice가 당신을 도울 수 있다는 점을 명심하십시오. Guice는 Factory 구현을 자동으로 생성 할 수있는 능력을 가지고 있지만 여전히 DataTypeMyAppTreeNode.Factory에 매핑해야합니다.지도, 조건부 또는 이중 간접적 인 권한이 있어야합니다. 방문자 패턴.

이미 도움이 될만한 답변이 있다면 도움이 되었기를 바랍니다.

관련 문제