Реализовать рабочую цепочку с шаблоном templatemethod? - PullRequest
0 голосов
/ 08 марта 2012

У меня есть иерархия 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);

, который имеет очевидный недостаток, заключающийся в том, что для каждого уровня иерархии существует дополнительный новый метод.

Я хотел бы гарантировать, что все методы до и после обработки выполняются даже с новыми, реализованными пользователем рабочими, которые не находятся под моим контролем.

Как бы вы это сделали?

1 Ответ

2 голосов
/ 08 марта 2012

Следуя шаблону метода шаблона, вы сделаете это, спроектировав свой класс таким образом, чтобы методы 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
    }
}
...