我们有如下代码:
Service<E,F> pipeline = new MyServiceDecorator2(new MyServiceDecorator1(new MyService()));
然后以F f = pipeline.apply(new E("E"))
我们希望这样阅读:
Service<A,B> myService = new MyService();
// Service<C,D>
MyServiceDecorator1 myServiceDecorator1 = new MyServiceDecorator1();
// Service<E,F>
MyServiceDecorator2 myServiceDecorator2 = new MyServiceDecorator2();
Service<E,F> pipeline = myServiceDecorator2.andThen(myServiceDecorator1).andThen(myService);
// This should still be doable i.e., the end goal
F f = pipeline.apply(new E("E"));
我们尝试了各种技巧,但无法使返回类型正确排列。上面的方法会引发错误-我们只是手动将andThen
添加到每个Decorator类中以了解流程,就像这样:
public <J,K> Service andThen(Service<J,K> next) {
this.service = next;
return next;
}
这将返回链中“下一个项目”的类型。我尝试了一些使用next/prev
引用/指针的技巧,以提高其效率,但似乎无济于事。这有可能吗?
这是REPL,其中显示代码,并带有打印语句,显示通过装饰器的进度。
上下文:我们有大量的代码可以简化为“装饰器”,以实现“管道和过滤器”模式,以便我们提供基本的“框架”,使开发人员能够运用相同的图案/思路解决相同的问题,而不是复制/粘贴或重新发明轮子。以上是我们要实现的目标的“示例”。我们计划将其转换为泛型,但目前有重复的代码。
答案 0 :(得分:1)
编辑:正在尝试另一种方法(我认为它具有相同的问题...)
嗯,您无法真正获得想要的东西,需要权衡一些东西。
在这种情况下,它是使用apply
方法的,它必须接受Domain
。
之所以会发生这种情况,是因为在构建时未设置包装 Service
,因此不能100%输入。
interface Service<A extends Domain, B extends Domain> {
B apply(final Domain a);
Service<A, B> andThen(final Service<? extends Domain, ? extends Domain> service);
}
class MyService implements Service<A, B> {
private Service<? extends Domain, ? extends Domain> wrapped;
@Override
public B apply(final Domain a) {
return new B(a.name + "->B");
}
@Override
public Service<A, B> andThen(final Service<? extends Domain, ? extends Domain> wrapped) {
this.wrapped = wrapped;
return this;
}
}
class MyServiceDecorator1 implements Service<C, D> {
private Service<? extends Domain, ? extends Domain> wrapped;
@Override
public D apply(final Domain input) {
// C->A
Domain a = new A(input.name + "->A");
// get B
Domain b = this.wrapped.apply(a);
// B->D
return new D(b.name + "->D");
}
public Service<C, D> andThen(final Service<? extends Domain, ? extends Domain> wrapped) {
this.wrapped = wrapped;
return this;
}
}
class MyServiceDecorator2 implements Service<E, F> {
private Service<? extends Domain, ? extends Domain> wrapped;
@Override
public F apply(final Domain input) {
// E->C
Domain c = new C(input.name + "->C");
// get D
Domain d = this.wrapped.apply(c);
// D->F
return new F(d.name + "->F");
}
@Override
public Service<E, F> andThen(final Service<? extends Domain, ? extends Domain> wrapped) {
this.wrapped = wrapped;
return this;
}
}
public static void main(String[] args) {
final Service<A, B> myService = new MyService();
MyServiceDecorator1 myServiceDecorator1 = new MyServiceDecorator1();
MyServiceDecorator2 myServiceDecorator2 = new MyServiceDecorator2();
final Service<E, F> efService =
myServiceDecorator2.andThen(myServiceDecorator1)
.andThen(myService);
// This should still be doable i.e., the end goal
F f = efService.apply(new E("E"));
System.out.println(f.name);
}
我再也做不到,因为Java的泛型功能受到限制。
结束语:字节码生成是您的朋友。