Re: Ensuring a method is overridden
markspace wrote:
Daniel Pitts wrote:
I would only use Decorators in to extend behavior (performing the same
behavior, but modifying the input and/or output of the extended
behavior).
Yes, that's primarily the use-case I was thinking of. Of course there
could be more complex interactions where decorators are not suitable.
> I don't see how decorators are any more insulated than strategies.
Primarily because they only do modify "input and output" and often only
deal with one public method at a time, I think they're more encapsulated
than certain other types of composition.
That's like saying Oranges taste better than Apples because you have to
peel them :-)
Strategies can be very tightly encapsulated, and Decorators are subject
to Object hierarchy dependencies which can increase complexity.
For example, recently I added a GZIP filter to one of my webapps. It
worked well, except when another filter was triggered in the wrong
order, and it tried to modify the GZIP data, rather than the underlying
data. If there had been a "Content-Encoding Strategy" that I could have
set to a GZIPContentEncoder, it would have been a non-issue.
Well, in either case, both patterns are valuable, and I think Strategy
tends to be under-used. I suggest playing around with it to see how it
works out.
If you find you have a tree like this:
[A]
/ \
[B] [C]
where A, B, C are classes, and B methods overrides are a disjoint set of
from C methods overrides, try instead to make it a strategy (or several
strategies even).
Yes, you end up with more "classes":
[A] +[S] +[S']
/ \ / \
[A'] [B] [A''] [C]
where A is composed of S and S' objects, S/S' are abstract or interfaces
and the default impl in the old system for A is now in A' and A''. The
overridden methods in B/C remain the same.
Just try it, and see where it leads you.
--
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>