Реализовать рабочую цепочку с шаблоном шаблонного метода?
-
09-12-2019 - |
Вопрос
У меня есть иерархия worker
классы, каждый из которых выполняет некоторую обработку заготовки.Идея состоит в том, что каждый рабочий выполняет некоторую предварительную обработку, отправляет заготовку в подкласс, а затем выполняет некоторую постобработку:
public void process(Workpiece wp) {
doPreprocessing(wp);
sub.process(wp); // this obviously doesn't work
doPostProcessing(wp);
}
Прямо сейчас я решаю эту проблему, объявляя новые абстрактные методы:
public final void process(Workpiece wp) {
doPreprocessing(wp);
subProcess(wp); // this obviously doesn't work
doPostProcessing(wp);
}
protected abstract void subProcess(Workpiece wp);
у которого есть очевидный недостаток: для каждого уровня иерархии существует дополнительный новый метод.
Я хотел бы гарантировать, что все методы предварительной и постобработки выполняются даже с новыми, реализованными пользователем рабочими процессами, которые не находятся под моим контролем.
Как бы Вы это сделали?
Решение
Следуя шаблону шаблонного метода, вы можете сделать это, разработав класс таким образом, чтобы doPreProcessing
и doPostProcessing
методы переопределяются в подклассах.Я предполагаю, что вы не хотите этого делать, потому что вы не можете быть уверены, что подклассы вызовут super, и, следовательно, вы не можете «гарантировать, что все методы предварительной и последующей обработки будут выполнены даже с новыми пользовательскими -реализованные рабочие».
Вместо использования наследования вы можете попробовать дизайн, объединяющий рабочие объекты, например:
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);
}
Ваши классы и классы, реализованные пользователем, вместо расширения «следующего» работника создают «следующего» работника в своих конструкторах:
public class MyWorker extends Worker {
public MyWorker() {
super(new MyOtherWorker());
}
public abstract void preProcess(Workpiece wp) {
// code
}
public abstract void postProcess(Workpiece wp) {
// code
}
}