是的,仿制药是一个经常性的主题,在这里又一次......
目前,我有这段代码。 Processor
是一个“简单”的通用界面。
public final class ProcessorChain<IN extends MessageProvider, OUT extends MessageProvider>
implements Processor<IN, OUT>
{
/**
* The resulting processor
*/
private final Processor<IN, OUT> p;
/**
* Start a processing chain with a single processor
*
* @param p the processor
* @param <X> the input type
* @param <Y> the output type
* @return a single element processing chain
*/
public static <X extends MessageProvider, Y extends MessageProvider>
ProcessorChain<X, Y> startWith(final Processor<X, Y> p)
{
return new ProcessorChain<X, Y>(p);
}
/**
* Private constructor
*
* @param p the processor
*/
private ProcessorChain(final Processor<IN, OUT> p)
{
this.p = p;
}
/**
* Add an existing processor to that chain
*
* <p>Note that this returns a <b>new</b> chain.</p>
*
* @param p2 the processor to add
* @param <NEWOUT> the return type for that new processor
* @return a new chain consisting of the previous chain with the new
* processor appended
*/
public <NEWOUT extends MessageProvider> ProcessorChain<IN, NEWOUT>
chainWith(final Processor<OUT, NEWOUT> p2)
{
return new ProcessorChain<IN, NEWOUT>(merge(p, p2));
}
public Processor<IN, OUT> end()
{
return this;
}
@Override
public OUT process(final ProcessingReport report, final IN input)
throws ProcessingException
{
return p.process(report, input);
}
/**
* Merge two processors
*
* @param p1 the first processor
* @param p2 the second processor
* @param <X> the input type of {@code p1}
* @param <Y> the output type of {@code p1} and input type of {@code p2}
* @param <Z> the output type of {@code p2}
* @return a processor resulting of applying {@code p2} to the output of
* {@code p1}
*/
private static <X extends MessageProvider, Y extends MessageProvider, Z extends MessageProvider>
Processor<X, Z> merge(final Processor<X, Y> p1, final Processor<Y, Z> p2)
{
return new Processor<X, Z>()
{
@Override
public Z process(final ProcessingReport report, final X input)
throws ProcessingException
{
return p2.process(report, p1.process(report, input));
}
};
}
}
所以,目前,我可以写:
// p1 does <X, Y>, p2 does <Y, Z>, p3 does <Z, T>
Processor<X, T> p = ProcessingChain.startWith(p1).chainWith(p2).chainWith(p3).end();
它有效。事实上,我从未在仿制药方面走得那么远。
我想写的是:
Processor<X, T> p = ProcessingChain.start().add(p1).add(p2).add(p3).end();
我一直在努力做到这一点,但失败了。
我希望能够做到这一点的一个原因是,将来也可以写:
Processor<X, T> p = ProcessingChain.start().add(p1).stopOnError().etc().etc()
我觉得如果我知道如何.start()
,那么“实用程序”处理器将不会成为问题。
那么,怎么做?
答案 0 :(得分:2)
无法使用裸启动方法推断生成的ProcessorChain必须具有的类型。此外,正如@PaulBellora指出的那样,你勾勒出的start()方法本身不能是处理器,因为它没有足够的信息。
您可以使用单独的类作为start()方法的结果,尽管它不能是无参数的。 e.g:
public class ProcessorChainFactory<M extends MessageProvider> {
public static <X extends MessageProvider> ProcessorChainFactory<X> start() {
return null;
}
public static <X extends MessageProvider> ProcessorChainFactory<X> start(Class<X> clazz) {
return null;
}
public <X extends MessageProvider> ProcessorChain<M, X> add(Processor<M, X> processor) {
// TODO Auto-generated method stub
return null;
}
}
然后可以通过几种方式调用:
Processor<MessageProvider1, Final> processor = ...;
ProcessorChain<MessageProvider1, Final> processor1 = ProcessorChainFactory.<MessageProvider1> start().add(processor);
ProcessorChain<MessageProvider1, Final> processor2 = ProcessorChainFactory.start(MessageProvider1.class).add(processor);
我的感觉是,除了你当前的ProcessingChain.startWith(p1)
之外,你没有得到更多,但也许它有用。
答案 1 :(得分:1)
无参数start
方法应该返回什么?这是问题的症结所在,尽管你在问题中只提到了它。
请注意,您已将ProcessorChain
声明为实施Processor
- 因此ProcessorChain
的任何实例都必须像一个实例一样。出于这个原因,创建一个没有ProcessorChain
的{{1}}实例来包装是没有意义的。
一般来说,我会说构建器不应该实现它构建的接口,但是编写了我认为我至少有兴趣看到反驳的参数。
答案 2 :(得分:1)
嗯,好吧,有一种方法,虽然它有点hackish:
public static <X extends MessageProvider> ProcessorChain<X, X> start()
{
final Processor<X, X> p = new Processor<X, X>()
{
@Override
public X process(final ProcessingReport report, final X input)
throws ProcessingException
{
return input;
}
};
return new ProcessorChain<X, X>(p);
}
然而,它不会完全奏效。对于S
,ValidationData
和P
,p1
执行<S, ValidationData>
和p2
执行<ValidationData, P>
,写作:
ProcessorChain.start().chainWith(p1).chainWith(p2).end()
导致此编译错误:
<NEWOUT>chainWith(Processor<MessageProvider,NEWOUT>)
in ProcessorChain<MessageProvider,MessageProvider>
cannot be applied to
(Processor<S,ValidationData>)
上面的代码是我的第一次尝试......
但如果我写:
ProcessorChain.<S>start().chainWith(p1).chainWith(p2).end()
然后它有效!