Question

I have a hierarchy of worker classes, all of which do some kind of processing to a workpiece. The idea is, that each worker does some pre processing, pushes the workpiece to the subclass and then does some postprocessing:

public void process(Workpiece wp) {
   doPreprocessing(wp);
   sub.process(wp); // this obviously doesn't work
   doPostProcessing(wp);
}

Right now I'm solving this by declaring new abstract methods:

public final void process(Workpiece wp) {
   doPreprocessing(wp);
   subProcess(wp); // this obviously doesn't work
   doPostProcessing(wp);
}

protected abstract void subProcess(Workpiece wp);

which has the obvious disadvantage that for each hierarchy-level, there is an additional, new method.

I would like to guarantee, that all pre- and post-process methods are executed even with new, user-implemented workers, which are not under my control.

How would you do that?

Was it helpful?

Solution

Following the template method pattern, you would do this by designing you class such that the doPreProcessing and doPostProcessing methods are overridden in subclasses. I'm guessing you don't want to do this, because you can't be sure the subclasses will call super, and thus you can't "guarantee that all pre- and post-process methods are executed even with new, user-implemented workers."

Instead of using inheritance, you could try a design that chains worker objects together, like this:

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);
}

Your classes, and user-implemented classes, instead of extending the "next" worker, create the "next" worker in their constructors:

public class MyWorker extends Worker {

    public MyWorker() {
        super(new MyOtherWorker());
    }

    public abstract void preProcess(Workpiece wp) {
        // code
    }

    public abstract void postProcess(Workpiece wp) {
        // code
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top