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/>