-1

Let's say I have a Strategy interface :

public interface Strategy {

    void perform();

}

And a template method to implement it :

public abstract class AbstractStrategy implements Strategy {

    @Override
    public void perform() {
        String firstInfo = doStuff();
        String secondInfo = firstDelegationToImplementor(firstInfo);
        String thirdInfo = processSecondInfo(secondInfo);
        String fourthInfo = secondDelegationToImplementor(thirdInfo);
        finalProcessing(fourthInfo);
    }

    private void finalProcessing(String fourthInfo) {
        //TODO automatically generated method body, provide implementation.

    }

    protected abstract String secondDelegationToImplementor(String thirdInfo);

    protected abstract String firstDelegationToImplementor(String firstInfo);

    private String processSecondInfo(String secondInfo) {
        return "thirdResult";
    }

    private String doStuff() {
        return "firstResult";
    }
}

And I have a concrete subclass of that :

public class ConcreteStrategy extends AbstractStrategy {

    private String firstInfo;

    @Override
    protected String secondDelegationToImplementor(String thirdInfo) {
        return someMoreProcessing(firstInfo, thirdInfo);
    }

    private String someMoreProcessing(String firstInfo, String thirdInfo) {
        return null;
    }

    private String someProcessing(String firstInfo) {
        return null;
    }

    @Override
    protected String firstDelegationToImplementor(String firstInfo) {
        this.firstInfo = firstInfo;
        return someProcessing(firstInfo);
    }
}

But due to the fact that it needs to remember some intermediate result in between the method calls it is not stateless. Stateless classes have several advantages, they are automatically thread safe for instance.

So the question is : how can I make ConcreteStrategy stateless, while taking advantage of the template method?

(edit) Clarification : the published methods of both the interface and the template method class cannot change.

(note, I have solved this question already and will answer it myself, but I'll give others a chance to solve it)

bowmore
  • 10,842
  • 1
  • 35
  • 43
  • Your template class private methods either do nothing or return constant strings. It's hard to take seriously your requirement that this class not be changed. A more realistic bit of code might help. – Don Roby Jul 18 '14 at 13:21
  • @DonRoby The class can be changed, its published methods cannot. I've kept the code fairly abstract to keep the focus on the technical problem, without semantical distraction and also for brevity. You could imagine the first delegated method to result in a key that in the second delegated method needs to be used to get a value from a Map for instance. – bowmore Jul 18 '14 at 13:48

1 Answers1

1

Ok here's the answer I have come up with when I faced this :

public class StatelessConcreteStrategy implements Strategy {

    @Override
    public void perform() {
        new ConcreteStrategy().perform();
    }
}

StatelessConcreteStrategy is stateless. It has all the benefits any other stateless class has, and by delegating the perform() to a new ConcreteStrategy instance, it gets to use the template method pattern, and is able to 'remember' any data it wants to in between method calls.

In fact you'll most likely want to inline ConcreteStrategy to an inner or even anonymous inner class.

bowmore
  • 10,842
  • 1
  • 35
  • 43