Question

Let's say I have an interface for the Command pattern with undo functionality:

interface ICommand
{
    void Execute();
    void Undo();
}

This comes with a contract. Basically the command can be in one of two states - either it has been executed or not, and that determines the only method that can be called.

To add a check for this, I could create an abstract class called SafeCommand or simply CommandBase with this protection:

abstract class CommandBase : ICommand
{
    private bool executed = false;

    public void Execute()
    {
        if (executed)
            throw new InvalidOperationException();

        ExecuteImpl();
        executed = true;
    }

    public void Undo()
    {
        if (!executed)
            throw new InvalidOperationException();

        UndoImpl();
        executed = false;
    }

    protected abstract void ExecuteImpl();
    protected abstract void UndoImpl();
}

When I want to implement the actual command functionality, I now have to override the ExecuteImpl and UndoImpl methods instead.

Another way to solve this could be to make the methods virtual, but I prefer this way because I can't forget to implement the methods and also can't omit the base call. Also, in other cases where I need to have some code before and after the call, this will be the only solution.

I first encountered this pattern in WPF, where it's actually used twice in the same inheritance hierarchy with UIElement Measure, virtual MeasureCore and FrameworkElement override MeasureCore and virtual MeasureOverride methods.

My question is, is there a name for this pattern? It seems to me like some sort of a (forced) Adapter using inheritance instead of composition.

Was it helpful?

Solution

The only real GOF pattern here I can see in this construct is the "template method pattern".

The public interface of any CommandBase derivation - as seen from any code outside the class hierarchy - does not change, so I don't see this as

"providing a different interface to the subclasses",

as your question title imposes. My interpretation of this is more "providing an easier way to implement the interface with error checking".

The more interesting question here is: is there a LSP violation? I think not, if the contract is written down exactly as stated in the question, with the additional remark that Execute and Undo will throw exceptions when called in wrong order. Then the template method pattern will actually help to ensure the contract.

Licensed under: CC-BY-SA with attribution
scroll top