기존 웹 서비스의 특정 측면을 리팩토링하려고 노력하고 있습니다. 서비스 API가 구현되는 방식은 일종의 "프로세싱 파이프 라인"을 갖는 것입니다. 여기서는 작업이 순서대로 수행됩니다. 당연히, 나중의 작업에는 이전 작업에 의해 계산 된 정보가 필요할 수 있으며 현재이 방법은 "파이프 라인 상태"클래스에 필드를 추가하는 것입니다.
나는 zillion 필드가있는 데이터 객체를 갖는 것보다 파이프 라인 단계간에 정보를 공유하는 더 좋은 방법이 있다고 생각했습니다 (그리고 희망합니까?). 일부는 처리 단계에 적합하지만 다른 처리 단계에는 의미가 없습니다. 이 클래스를 스레드로부터 안전하게 만드는 것은 큰 고통이 될 것입니다 (가능한지 모르겠습니다). 불변에 대해 추론 할 방법이 없습니다 (아마도 없을 것입니다).
영감을 찾기 위해 Gang of Four 디자인 패턴 서적을 통해 페이징했지만 솔루션이있는 것처럼 느껴지지 않았습니다 (Memento는 다소 같은 정신에 있었지만 그다지 좋지는 않았습니다). 또한 온라인을 보았지만 두 번째로 "파이프 라인"또는 "워크 플로우"를 검색하면 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);
}
}