我正在努力重构现有Web服务的某些方面。实现服务API的方式是通过具有一种“处理管道”,其中有按顺序执行的任务。毫不奇怪,以后的任务可能需要由以前的任务计算的信息,当前完成此操作的方法是将字段添加到“管道状态”类中。
我一直在思考(并希望?),比在管道步骤之间共享信息的更好方法要好于拥有一个具有成千上万个字段的数据对象,其中某些字段对某些处理步骤有意义,而对另一些处理步骤却没有意义。使该类成为线程安全类将是一个巨大的痛苦(我不知道它是否可能实现),无法推断其不变性(很可能没有任何原因)。
我翻阅了《四人帮》设计模式书以找到一些灵感,但我觉得那儿没有解决的办法(Memento的想法有些相同,但不完全相同)。我也在网上看过,但是第二次搜索“管道”或“工作流”时,您就会被Unix管道信息或专有工作流引擎和框架所淹没。
我的问题是-您将如何处理记录软件处理管道执行状态的问题,以便以后的任务可以使用以前的任务计算的信息?我猜想与Unix管道的主要区别在于,您不仅在乎前一项任务的输出。
根据要求,使用一些伪代码来说明我的用例:
“管道上下文”对象具有许多字段,不同的管道步骤可以填充/读取这些字段:
public class PipelineCtx {
... // fields
public Foo getFoo() { return this.foo; }
public void setFoo(Foo aFoo) { this.foo = aFoo; }
public Bar getBar() { return this.bar; }
public void setBar(Bar aBar) { this.bar = aBar; }
... // more methods
}
每个管道步骤也是一个对象:
public abstract class PipelineStep {
public abstract PipelineCtx doWork(PipelineCtx ctx);
}
public class BarStep extends PipelineStep {
@Override
public PipelineCtx doWork(PipelieCtx ctx) {
// do work based on the stuff in ctx
Bar theBar = ...; // compute it
ctx.setBar(theBar);
return ctx;
}
}
对于假设类似FooStep
,它可能需要由BarStep计算的Bar以及其他数据。然后,我们进行了真正的API调用:
public class BlahOperation extends ProprietaryWebServiceApiBase {
public BlahResponse handle(BlahRequest request) {
PipelineCtx ctx = PipelineCtx.from(request);
// some steps happen here
// ...
BarStep barStep = new BarStep();
barStep.doWork(crx);
// some more steps maybe
// ...
FooStep fooStep = new FooStep();
fooStep.doWork(ctx);
// final steps ...
return BlahResponse.from(ctx);
}
}