2013-11-09 77 views
0

這是一個我正在嘗試的示例程序。如何避免爲通用類型創建特定實現

我處理的物品 - 可以產生SingleItems或MultiItems

public interface IProducer<T> { 
    T produce(); 
} 

public class SingleItemProducer implements IProducer<SingleItem> { 

    @Override 
    public SingleItem produce() { 
     return new SingleItem(...); 
    } 
} 

public class MultiItemProducer implements IProducer<MultiItem> { 
    . . . . . 
    . . . . . 
} 

消費者能夠消費SingleItems或MultiItems

public interface IConsumer<T> { 
    void consume(T item); 
} 

public class SingleItemConsumer implements IConsumer<SingleItem> { 

    @Override 
    public void consume(SingleItem item) { 
     System.out.println(item.getContents()); 
    } 
} 

public class MultiItemConsumer implements IConsumer<MultiItem> { 
    . . . . . 
    . . . . .  
} 

處理器單邊或多邊

public interface IItem<T> { 
    T getContents();  
} 

/** An item that holds a Map and uses it for something */ 
public class SingleItem implements IItem<Map<String,String>> { 
    . . . . . 
} 

/** An item that holds a List of maps and uses it for something */ 
public class MultiItem implements IItem<List<Map<String,String>>> { 
    . . . . . 
} 

生產者是將使用生產者&消費者ge完成的工作。

public interface IProcessor<T> { 
    void process(); 
    void process(T item); 
} 

/** A generic processor that should be able to work with any type of consumer or producer */ 
public class GenericItemProcessor implements IProcessor<IItem<? extends Object>> { 

    IProducer<IItem<? extends Object>> producer; 
    IConsumer<IItem<? extends Object>> consumer; 

    public GenericItemProcessor (IProducer<IItem<? extends Object>> p, IConsumer<IItem<? extends Object>> c) { 
     this.producer = p; 
     this.consumer = c; 
    } 

    @Override 
    public void process() { 
     IItem<? extends Object> item = null; 
     // As long the producer produces items, keep processing them 
     while ((item = producer.produce()) != null) { 
      this.process(item); 
     } 
    } 

    @Override 
    public void process(IItem<? extends Object> item) { 
     consumer.consume(item); 
    } 
} 

而且,在主程序中,當我嘗試這一點,

IProducer<SingleItem> producer = new SingleItemProducer(); 
IConsumer<SingleItem> consumer= new SingleItemConsumer(); 
IProcessor<IItem<? extends Object>> processor = new GenericItemProcessor(producer, consumer); 

它說我不能做最後的分配。

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
    The constructor GenericItemProcessor(IProducer<SingleItem>, IConsumer<SingleItem>) is undefined 

。當然,這會工作,

IProcessor<SingleItem> processor = new GenericItemProcessor(producer, consumer); 

如果我取代IItem<? extends Object>所有出現與SingleItemGenericItemProcessor

但問題是我必須創建一個處理器來處理每個項目類型,看起來它會打敗擁有通用「類型」處理器的目的。

可能在這裏丟失了一些明顯的東西,但是,這怎麼能正確完成呢?希望得到一些建議。

+0

在Scala中,這將與逆變完成以及Consumer和Producer的協變類型參數 - 但是很抱歉,我不知道如何將其轉換爲Java。 –

+0

[方法簽名中的Java泛型類型不匹配的可能的重複](http://stackoverflow.com/questions/19749005/java-generics-type-mismatch-in-method-signature) –

回答

1

我認爲您在GenericItemProcessor中對泛型的使用過於複雜。在處理器中的代碼不走的事實,使用情況,該處理器產生IItem對象,所以它不是必需的通用類型IItem<? extends Object>綁定:

/** A generic processor that should be able to work with any type of consumer or producer */ 
public class GenericProcessor<T> implements IProcessor<T> { 

    IProducer<? extends T> producer; 
    IConsumer<? super T> consumer; 

    public GenericProcessor(IProducer<? extends T> p, IConsumer<? super T> c) { 
     this.producer = p; 
     this.consumer = c; 
    } 

    @Override 
    public void process() { 
     T item = null; 
     // As long the producer produces items, keep processing them 
     while ((item = producer.produce()) != null) { 
      this.process(item); 
     } 
    } 

    @Override 
    public void process(T item) { 
     consumer.consume(item); 
    } 
} 

所以這段代碼是現在沒有問題:

IProducer<SingleItem> producer = new SingleItemProducer(); 
IConsumer<SingleItem> consumer = new SingleItemConsumer(); 
IProcessor<SingleItem> processor = new GenericProcessor<SingleItem>(
    producer, consumer); 

除此之外,這將使您的處理器更通用,因爲它現在可以處理任何生產者/消費者,即使他們不生產/消耗IItem對象。請注意生產商使用? extends T和消費者使用? super T。由於這一點,你可以「連接」每個生產者,產生某種類型的子類的實例,以消費者接受一個超類相同類型的實例:

IProducer<Integer> producer = new IntegerProducer(); 
IConsumer<Object> consumer = new ObjectConsumer(); 
IProcessor<Number> processor = new GenericProcessor<Number>(
    producer, consumer); 
相關問題