2016-11-17 1 views
1

를 사용하지 않고 같은 게터와 타사 클래스를 일반화하는 것은 샘플 코드이다). 그래서 이러한 인스턴스를 받으면 일반적인 유형으로 처리하고 싶습니다. 그래서 모델 클래스를 만들었습니다. 리플렉션을 사용하지 않고 G 인스턴스에 속성을 할당하는 방법이 있습니까? A, B 및와 밀접하게 연결되어 있지 않습니까? 정말 느리기 때문에 옵션이 아닙니다. 자바 8 솔루션은 괜찮습니다.여기에 반사

+0

우연히 알 수 있습니다. 그들은 공통의 수퍼 클래스를 가지지 않거나 동일한 인터페이스를 구현하지 않기 때문에 이미 수행 중이거나 반영을 사용하는 것처럼''instanceof''로 나열해야합니다. – f1sh

+0

난 단지 당신이 get 메소드의 오버라이드 (override)과 클래스를 만들어 제공 할 수 있습니다 : 클래스 G는 { 데이터 수 (A가) {반환 a.getData();} 데이터 (B 나) {반환 B를 얻을.getData(); 데이터 가져 오기 (C c) {return c.getData();} } –

+0

리플렉션은 "실제로 느린가"? 일부 라이브러리는 문제없이 항상이 라이브러리를 사용합니다. – eis

답변

3

단일 책임 원칙 : G는 메시지가 아닌 메시지 공장 :

class G { 
    private Class messageType; 
    private Header header; 
    private Data data; 

    public G(Class<?> klass, Header header, Data data) { 
     this.messageType = klass; 
     this.header = header; 
     this.data = data; 
    } 
} 

class GFactory { 
    private Map<Class<?>, Function<Object, G>> mappings; 

    public <T> void register(
      Class<T> klass, 
      Function<T, Header> headerExtractor, 
      Function<T, Data> dataExtractor) { 
     Function<Object, T> cast = klass::cast; 
     mappings.put(klass, cast.andThen(t -> 
      new G(klass, headerExtractor.apply(t), dataExtractor.apply(t)))); 
    } 

    public G createG(Object message) { 
     return mappings.get(message.getClass()).apply(message); 
    } 

    private GFactory() { 
     register(A.class, A::getHeader, A::getData); 
    } 
} 

나는 또한 자체 내에서 GFactory를 초기화하지만, 외부 그렇게하지 말 것.

+0

니스! 드디어 if-else 조건을 제거 할 수 있습니다. 스프링 컨텍스트 파일에 GFactory의 초기화를 넣을 수 있는지 봅시다. –

+0

멋진 솔루션처럼 보입니다. – GhostCat

+2

@GhostCat : 해결책은 이해할 수 없지만 좋은 해결책을 제시하지는 못합니다. 그러나 당신이'register (A.class, A :: getHeader, A :: getData)'줄을 솔루션의 열쇠로 삼는다면, 이해하기가 그렇게 어렵지 않다. 물론'B'와'C'에 줄을 추가해야합니다. – Holger

1

아니요.

당신이 할 수있는 유일한 일은 두 개의 장치를 여기에서으로 분리합니다. 의미 :

을 대신 전환이 "instanceof를"을하고 속성 를 검색 할 책임이 하나 클래스를 필요없이 ... 두 다른 클래스로 그것을 밀어 수 있습니다.

의미 : 먼저 당신이 "instanceof를"같은 방법을 가지고 공장의 일종으로 전환하는 것을 이동 그리고

class Foo { 
    Foo(String header, ...) { ... 
    String getHeader() { ... 
    ... 

같은 것을 G의 요구 G를 제공합니다 일부 "데이터 전송 클래스를"정의 :

class FooFactory { 
    Foo makeFooFrom(Object message) { ... 

그리고 나서 G는 해당 FooFactory를 사용하여 들어오는 메시지에 대한 Foo 객체를 획득합니다.

하지만 것입니다 : 반사, 당신 의미 같은 해결 할 수있는 일이 독립 클래스에서 다른 필드를 가지고있는 "암시"복잡성을 사용하지 않고.

내 솔루션에있는 유일한 "이점": G는 A, B, C에 대해 아무 것도 알 필요가 없습니다. 단지 Foo 클래스에 대해 알고 있습니다.

물론 FooFactory는 이러한 모든 것을 알아야합니다. 대부분의 경우 복잡성은 물과 같습니다. 다른 방식으로 만들 수는 있지만 압축하거나 "사라지게"할 수는 없습니다.

+0

이 통찰력에 감사드립니다! –