Implementare un workckain con templatemethod pattern?
-
09-12-2019 - |
Domanda
Ho una gerarchia di classi worker
, tutte le quali fanno qualche tipo di lavorazione a un pezzo.L'idea è che ogni lavoratore fa parte della pre-elaborazione, spinge il pezzo in lavorazione alla sottoclasse e poi fa alcuni postProcessing:
public void process(Workpiece wp) {
doPreprocessing(wp);
sub.process(wp); // this obviously doesn't work
doPostProcessing(wp);
}
.
Proprio ora sto risolvendo questo dichiarando nuovi metodi astratti:
public final void process(Workpiece wp) {
doPreprocessing(wp);
subProcess(wp); // this obviously doesn't work
doPostProcessing(wp);
}
protected abstract void subProcess(Workpiece wp);
.
Che ha l'ovvio svantaggio che per ciascun livello di gerarchia, c'è un metodo aggiuntivo e nuovo.
Vorrei garantire che tutti i metodi pre- e post processo vengono eseguiti anche con nuovi lavoratori implementati dall'utente, che non sono sotto il mio controllo.
Come lo faresti?
Soluzione
Seguendo il modello del metodo del modello, lo farebbe progettando la classe in modo tale che i metodi generacodictagCode e doPreProcessing
siano sovrascritti nelle sottoclassi.Immagino che tu non voglia farlo, perché non puoi essere sicuro che le sottoclassi chiamerà Super, e quindi non puoi "garantire che tutti i metodi di pre-e post processo siano eseguiti anche con il nuovo utente, utente-Prementato i lavoratori. "
Invece di usare l'ereditarietà, potresti provare un design che gli oggetti degli impianti di catene sono insieme, come questo:
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);
}
.
Le tue classi e lezioni implementate dall'utente, invece di estendere il lavoratore "Avanti", creare il lavoratore "Avanti" nei loro costruttori:
public class MyWorker extends Worker {
public MyWorker() {
super(new MyOtherWorker());
}
public abstract void preProcess(Workpiece wp) {
// code
}
public abstract void postProcess(Workpiece wp) {
// code
}
}
.