¿Implementar una cadena de trabajo con patrón de método de plantilla?
-
09-12-2019 - |
Pregunta
tengo una jerarquia de worker
clases, todas las cuales realizan algún tipo de procesamiento en una pieza de trabajo.La idea es que cada trabajador realice un procesamiento previo, empuje la pieza de trabajo a la subclase y luego realice un procesamiento posterior:
public void process(Workpiece wp) {
doPreprocessing(wp);
sub.process(wp); // this obviously doesn't work
doPostProcessing(wp);
}
Ahora mismo estoy resolviendo esto declarando nuevos métodos abstractos:
public final void process(Workpiece wp) {
doPreprocessing(wp);
subProcess(wp); // this obviously doesn't work
doPostProcessing(wp);
}
protected abstract void subProcess(Workpiece wp);
lo que tiene la desventaja obvia de que para cada nivel jerárquico, existe un método nuevo y adicional.
Me gustaría garantizar que todos los métodos previos y posteriores al proceso se ejecuten incluso con trabajadores nuevos implementados por el usuario, que no están bajo mi control.
¿Cómo lo harías tú?
Solución
Siguiendo el patrón del método de plantilla, haría esto diseñando su clase de modo que el doPreProcessing
y doPostProcessing
Los métodos se anulan en las subclases.Supongo que no desea hacer esto, porque no puede estar seguro de que las subclases llamarán a super y, por lo tanto, no puede "garantizar que todos los métodos previos y posteriores al proceso se ejecuten incluso con usuarios nuevos". -Trabajadores implementados."
En lugar de utilizar la herencia, podría probar un diseño que encadene objetos de trabajo, como este:
public abstract class Worker {
private Worker next;
protected Worker(Worker next) {
this.next = next;
}
public void process(Workpiece wp) {
preProcess(wp);
if (next != null)
next.process(wp);
postProcess(wp);
}
public abstract void preProcess(Workpiece wp);
public abstract void postProcess(Workpiece wp);
}
Sus clases y las clases implementadas por el usuario, en lugar de extender el "siguiente" trabajador, crean el "siguiente" trabajador en sus constructores:
public class MyWorker extends Worker {
public MyWorker() {
super(new MyOtherWorker());
}
public abstract void preProcess(Workpiece wp) {
// code
}
public abstract void postProcess(Workpiece wp) {
// code
}
}