Saya sedang berupaya mempertimbangkan ulang aspek-aspek tertentu dari layanan web yang ada. Cara API layanan diimplementasikan adalah dengan memiliki semacam "pipeline pemrosesan", di mana ada tugas yang dilakukan secara berurutan. Tidak mengherankan, tugas-tugas selanjutnya mungkin memerlukan informasi yang dihitung oleh tugas-tugas sebelumnya, dan saat ini cara ini dilakukan adalah dengan menambahkan bidang ke kelas "keadaan pipa".
Saya telah berpikir (dan berharap?) Bahwa ada cara yang lebih baik untuk berbagi informasi antara langkah-langkah pipa daripada memiliki objek data dengan miliaran bidang, beberapa di antaranya masuk akal untuk beberapa langkah pemrosesan dan tidak kepada yang lain. Akan sangat menyusahkan untuk membuat kelas ini aman dari thread (saya tidak tahu apakah itu mungkin), tidak ada cara untuk alasan tentang invariannya (dan kemungkinan tidak ada).
Saya mencari-cari buku pola desain Gang of Four untuk menemukan beberapa inspirasi, tetapi saya tidak merasa ada solusi di sana (Memento agak bersemangat, tetapi tidak sepenuhnya). Saya juga mencari online, tetapi saat Anda mencari "pipeline" atau "workflow" Anda kebanjiran informasi pipa Unix, atau mesin alur kerja dan kerangka kerja.
Pertanyaan saya adalah - bagaimana Anda akan mendekati masalah pencatatan status eksekusi dari pipeline pemrosesan perangkat lunak, sehingga tugas-tugas selanjutnya dapat menggunakan informasi yang dihitung oleh yang sebelumnya? Saya kira perbedaan utama dengan pipa Unix adalah bahwa Anda tidak hanya peduli dengan hasil dari tugas yang sebelumnya segera.
Seperti yang diminta, beberapa pseudocode untuk menggambarkan kasus penggunaan saya:
Objek "konteks pipa" memiliki banyak bidang yang dapat diisi / dibaca oleh langkah-langkah pipa yang berbeda:
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
}
Setiap langkah pipa juga merupakan objek:
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;
}
}
Demikian pula untuk hipotetis FooStep
, yang mungkin perlu Bar dihitung oleh BarStep sebelum itu, bersama dengan data lainnya. Dan kemudian kita memiliki panggilan API yang sebenarnya:
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);
}
}