It help to understand exactly what Decorator Pattern allows you to do.
Let's just focus on a Decorator that wraps around a single function. (For all other method calls, the decorator would forward it right toward the underlying object.)
This is what the Decorator's method could possibly do:
- Possibly do some of its own stuff before calling the underlying object
- Possibly call the method of the same name on the underlying object
- Or, possibly not. The call was eaten by my dog.
- Or, still call it, but with a different set of parameters.
- After returning from the method on the underlying object, possibly do some other stuff of its own.
- Say, replace the returned value.
- Or, throw a pizza.
By pizza I mean exception.
What Decorator could not possibly do, is:
A decorator method cannot dictate the internal control flow of the method in the underlying object, in ways that the underlying object doesn't expose.
What I mean by that is:
If the underlying object exposes toggles and switches which influence the internal control flow of its method, fine. Your decorator method can use these toggles and switches, and possibly restore them after returning from the underlying method.
If the underlying object doesn't allow you to influence some aspects of its internal control flow, you're stuck.
In this case, if you need to implement your own alternative control flow to completely replace the underlying method, there's a name for it. The Copy-and-paste Pattern.
However, you cannot do this:
Execute the next 253 bytes of machine code after entering the underlying method. Skip the next 47 bytes of machine code. Oh, by the way, inject some garbage into the underlying method's stack, and prepare to take over the machine's hypervisor with a zero-day exploit.
Actually you could possibly do that, but that's called a Trojan, not a Decorator.
So, going back to the main question. Should I use a Decorator, or a Derived Class?
I guess I'll leave that question to people who are infinitely more familiar with your code base.