2013-10-08 35 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