2013-10-08 38 views
4

有兩類X,Y,它實現一個Base接口 有這需要處理每個類型通用接口VS接口,用於每種類型的

interface Base { 
} 
class X implements Base { 
} 
class Y implements Base { 
} 

interface XProcessor { 
    void process(X object); 
} 
interface YProcessor { 
    void process(Y object); 
} 

的對象,但這樣的方法的缺點的護理的接口是我必須爲每種類型的對象(X,Y ..)公開一個接口,並且如果有很多這樣的對象,我最終會暴露過多的接口。我以爲我會被暴露只是一個接口,它需要一個類型庫的處理對象的謹慎處理這個

interface Processor<E extends Base> { 
    void process(E object); 
} 

實施者寫自己實現加工型X的對象作爲

class XProcessor implements Processor<X> { 
    void process(X object) { 
     //do something 
    } 
} 

的問題這種方法是當我不得不調用方法進程時,我不知道應該將哪種類型的對象傳遞給處理器,因爲在運行時我無法確定該處理器的類型

void process(Processor p) { 
    p.process(??); 
} 

是否有更好的方法來處理這個問題?

+1

這裏的問題是:爲什麼你真的需要在運行時知道類?如果你不能概括這個過程,那麼就和每個課程一起工作。 –

+1

這可以通過一個'Factory'來處理不同的'Processor's嗎? – tredontho

+0

訪客模式。 – Riga

回答

2

由於@tredontho建議可以使用下面的工廠「ProcessorFactory」來獲取相關實例和然後調用進程方法

public class ProcessTest { 

    <T extends Base> void processBase(T base) { 
     ProcessorFactory.getProcessor(base).process(base); 
    } 

} 


interface Base{ 
} 
class X implements Base{ 
} 
class Y implements Base{ 
} 

interface Processor<E extends Base>{ 
    void process(E object); 
} 

interface XProcessor extends Processor<X> { 

} 
interface YProcessor extends Processor<Y> { 

} 

class ProcessorFactory { 

    @SuppressWarnings("unchecked") 
    static <T extends Base> Processor<T> getProcessor(T base) { 
     if (base instanceof X) { 
      return (Processor<T>) new XProcessorImpl(); 
     } 
     return null; 
    } 

} 

class XProcessorImpl implements XProcessor { 

    @Override 
    public void process(X object) { 
     // TODO Auto-generated method stub 

    } 

} 
+1

這看起來很乾淨。但在我的情況下,界面'處理器'將暴露給用戶,他會執行它。在運行時,我們將獲得實現「Processor」接口的所有類並調用它們的「process」方法。因此,除非我們爲類型爲'X'的對象的'XProcessor'類型的每種類型的對象提供接口,否則無法確定在運行時傳遞給流程方法的對象類型。所以在我的情況下,我認爲一個單一的通用接口是不夠的,我應該爲每種類型的對象公開一個接口。 – themanwhosoldtheworld

+1

@Kalyan你可以介紹'類 getSupportedClass();'到處理器接口並強制接口的實現者公開所支持的類。通過使用這你可以找出哪個處理器的實現可以用於給定的Base實例 –

+0

.hmm,雖然它看起來不太優雅,但它不錯。 – themanwhosoldtheworld

1

這與運行時無關。您已刪除在類型的編譯時間如果你喜歡寫東西

void process(Processor p){ 
    p.process(??); 
} 

如果您Processor接口是通用的,你不應該使用原始類型了:

<E extends Base> void process(Processor<E> p){ 
    p.process(…instance of E…); 
} 

例如:

<E extends Base> void processAll(Processor<E> p, Collection<? extends E> c){ 
    for(E item: c) p.process(c); 
} 
1

是否process()方法有一個參數?

你可能會採用以下方式嗎?

每個單獨的類實現通用接口processor包括存根void process()方法,從而建立自己的自定義操作。然後你可以upcast你的對象的接口(把它們以某種集合如有此要求的)。

你可以有這樣的事情:

List<Processor> p = new ArrayList<>(); 
p.add(new Xprocessor); 
p.add(new Yprocessor); 

for each(Processor pr: p) { 
    pr.Processor(); 
} 

和多態性會採取其他的事情。

在這種情況下,你甚至不需要泛型。

+0

這是訪客模式。 – Riga