2016-09-02 2 views
2

제 코드에는 일반 컨테이너 인터페이스가 있습니다. 컨테이너에는 팩토리 객체가 있고 컨테이너 유형은 팩토리에 의해 결정됩니다.일반 컨테이너 팩터

과 같이 :

public class HardGenerics { 
    public static Container<String> stringContainer(Function<Supplier<String>,Container<String>> factory) { 
     return factory.apply(() -> ""); 
    } 

    public static Container<Integer> integerContainer(Function<Supplier<Integer>,Container<Integer>> factory) { 
     return factory.apply(() -> 0); 
    } 

    private interface Container<T> { } 

    public static class ListBackedContainer<T> implements Container<T>{ 
     private final Supplier<T> factory; 
     private List<T> list = new ArrayList<T>(); 
     public ListBackedContainer(Supplier<T> factory) { 
      this.factory = factory; 
     } 
    } 

    public static void main(String[] args) { 
     create(); 
    } 

    private static void create() { 
     stringContainer(ListBackedContainer::new);//extract single parameter 
     integerContainer(ListBackedContainer::new);//extract single parameter 
    } 
} 

질문 :

내가 용기 공장을 통과하고자하는 (즉, ListBackedContainer :: 새)의 주위에 내 코드베이스에,하지만 난 방법을 알아낼 수 없습니다 그것을 입력하려면?

업데이트 :

그래서 문제에 정교. 나는 그것이 확실하지 않다

+0

여기에있는 것이 잘못되었습니다. – shmosel

+0

아래의 두 가지 설명과 제안 된 해결 방법에서 알 수 있듯이 하나의 ContainerFactory를 전달하려고하지만 어떤 유형을 가져야합니까 – mathiasbn

+0

죄송합니다. 왜'containerFactory :: create'가'ListBackedContainer :: new'보다 좋은가? – shmosel

답변

2

public static void main(String[] args) { 
    create(ListBackedContainer::new); 
} 

private static void create(Function<Supplier</*what to do*/>, Container</*what to do*/>> factory) { 
    stringContainer(factory); 
    integerContainer(factory); 
} 

내가 추상 일반 컨테이너 공장 주위에 통과하고 싶은, 그리고 콘크리트 ListBackedContainer : 나는이 작업을 수행 할 수 없습니다 (또는 내가 방법을 알아낼 수 없습니다) 가능한, 그래서 합리적인 해결 방법은 지금과 같은 실제 추상 팩토리 인터페이스를 만들 수 : 발놀림의

public static void main(String[] args) { 
    create(ListBackedContainer::new); 
} 

private static void create(ContainerFactory containerFactory) { 
    stringContainer(containerFactory::create); 
    integerContainer(containerFactory::create); 
} 

interface ContainerFactory{ 
    <T> Container<T> create(Supplier<T> itemFactory); 
} 

아니 많이, 그리고 일반 유형 지옥보다 더 많은 표현입니다.

+0

에있는 구체적인 구현만을 선택해야한다. 이것은 정확한 해결책이 아니다. 'ListBackedContainer :: new'는 팩토리의'T' 매개 변수를 무시하고 원시 타입 경고를 생성합니다. – shmosel

+0

나는 왜 그 경고를 생성하는지 잘 모르겠다. 타입 추론은 정적 팩토리 메소드 ('ListBackedContainer :: create')로는 잘 동작하지만 생성자 참조에서는 실패합니다. – shmosel

+0

또한 메서드 참조를 사용하는 대신 팩토리를 익명 하위 클래스로 인스턴스화하여 원시 형식 경고를 피할 수 있습니다. 특별히 메소드 참조로 클래스를 생성하려는 경우,'ListBackedContainer :: new'를 반환하는 팩토리 팩토리를 생성 할 수 있습니다. 익명으로 인스턴스화됩니다. – shmosel