Реализовать рабочую цепочку с шаблоном шаблонного метода?

StackOverflow https://stackoverflow.com//questions/9616942

  •  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
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top