Eine Workchain mit Templatemethod-Muster implementieren?
-
09-12-2019 - |
Frage
Ich habe eine Hierarchie von worker
klassen, die alle eine Art Bearbeitung an einem Werkstück vornehmen.Die Idee ist, dass jeder Arbeiter eine Vorbearbeitung durchführt, das Werkstück in die Unterklasse schiebt und dann eine Nachbearbeitung durchführt:
public void process(Workpiece wp) {
doPreprocessing(wp);
sub.process(wp); // this obviously doesn't work
doPostProcessing(wp);
}
Im Moment löse ich das, indem ich neue abstrakte Methoden deklariere:
public final void process(Workpiece wp) {
doPreprocessing(wp);
subProcess(wp); // this obviously doesn't work
doPostProcessing(wp);
}
protected abstract void subProcess(Workpiece wp);
was den offensichtlichen Nachteil hat, dass es für jede Hierarchieebene eine zusätzliche, neue Methode gibt.
Ich möchte garantieren, dass alle Vor- und Nachbearbeitungsmethoden auch mit neuen, vom Benutzer implementierten Mitarbeitern ausgeführt werden, die nicht unter meiner Kontrolle stehen.
Wie würdest du das machen?
Lösung
Nach dem Muster der Template-Methode würden Sie dies tun, indem Sie Ihre Klasse so entwerfen, dass die doPreProcessing
und doPostProcessing
methoden werden in Unterklassen überschrieben.Ich vermute, Sie möchten dies nicht tun, weil Sie nicht sicher sein können, ob die Unterklassen super aufrufen, und daher nicht "garantieren können, dass alle Vor- und Nachbearbeitungsmethoden auch mit ausgeführt werden neue, vom Benutzer implementierte Worker."
Anstatt Vererbung zu verwenden, könnten Sie ein Design ausprobieren, das Worker-Objekte wie folgt miteinander verkettet:
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);
}
Ihre Klassen und vom Benutzer implementierten Klassen erstellen, anstatt den "nächsten" Worker zu erweitern, den "nächsten" Worker in ihren Konstruktoren:
public class MyWorker extends Worker {
public MyWorker() {
super(new MyOtherWorker());
}
public abstract void preProcess(Workpiece wp) {
// code
}
public abstract void postProcess(Workpiece wp) {
// code
}
}