Varolan bir web hizmetinin belirli yönlerini yeniden faktoring üzerinde çalışıyorum. Hizmet API'lerinin uygulanma şekli, sırayla gerçekleştirilen görevlerin olduğu bir tür "işleme hattı" na sahip olmaktır. Şaşırtıcı olmayan bir şekilde, daha sonraki görevlerin önceki görevler tarafından hesaplanan bilgilere ihtiyacı olabilir ve şu anda bunun gerçekleştirilme şekli bir "ardışık düzen durumu" sınıfına alan eklemektir.
Boru hattı adımları arasında bilgi paylaşmanın, bazıları için bazı işlem adımlarına ve başkalarına değil, bazı işleme adımlarına mantıklı olan bir veri nesnesine sahip olmaktan daha iyi bir yol olduğunu düşündüm (ve umuyorum?). Bu sınıfı iplik güvenli hale getirmek için büyük bir acı olurdu (hatta mümkün olup olmadığını bilmiyorum), onun değişmezleri hakkında bir neden yoktur (ve muhtemelen herhangi bir yok).
Biraz ilham bulmak için Gang of Four tasarım desenleri kitabında dolaşıyordum, ama orada bir çözüm varmış gibi hissetmedim (Memento biraz aynı ruhtaydı, ama tam olarak değil). Ayrıca çevrimiçi baktım, ancak "boru hattı" veya "iş akışı" için arama yaptığınızda, Unix boru bilgileri veya tescilli iş akışı motorları ve çerçeveleri ile sular altında kalabilirsiniz.
Benim sorum - bir yazılım işleme boru hattının yürütme durumunu kaydetme konusuna nasıl yaklaşırsınız, böylece daha sonraki görevler daha önceki görevler tarafından hesaplanan bilgileri kullanabilir? Unix borulardaki en büyük fark, sadece hemen önceki görevin çıktısını umursamamanızdır.
İstendiği gibi, kullanım durumumu göstermek için bazı sözde kod:
"Pipeline bağlamı" nesnesi, farklı pipeline adımlarının doldurabileceği / okuyabileceği bir grup alana sahiptir:
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
}
Boru hattı adımlarının her biri de bir nesnedir:
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;
}
}
Benzer şekilde FooStep
, diğer verilerle birlikte BarStep tarafından hesaplanan Çubuğa ihtiyaç duyabilecek bir varsayım için . Ve sonra gerçek API çağrısı var:
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);
}
}