perlmeditation
jdporter
<p>
You know that strategy classes are easy to make and use.
For example, you want to encapsulate your output formats in such a way
that you can select the appropriate wrapper without affecting
client code.
<code>
package Output_Strategy::HTML;
package Output_Strategy::CSV;
. . .
my $output_strategy = $opt{'html'}
? 'Output_Strategy::HTML'
: 'Output_Strategy::CSV';
$output_strategy->preamble;
$output_strategy->render(@data);
$output_strategy->postamble;
# whatever
</code>
One of the nice aspects of this technique is that it is run-time dynamic:
you can reassign (or re-bless, if the strategy classes don't differ by data) the strategy object (<c>$output_strategy</c>)
at any time, to select a different strategy.
</p><p>
Now, this technique makes the following assumption (or, more accurately,
imposes the following constraint): the entity to be strategized
(output format, in the example above) is a stand-alone class or object.
It could even be a delegate within another object.
</p><p>
But, suppose you are extending the capabilities of a class via inheritance
rather than delegation/composition. How can you apply a strategy pattern
in the inheritance?
</p><p>
My answer is quite simple, and, again, it exploits Perl's highly dynamic
nature. It involves modifying the inheritance tree at run time.
And to make it more flexible, I insert a level of indirection in the
inheritance chain, so that the "end user" classes don't need to be
affected.
</p><p>
Suppose we have a set of classes (e.g. Foo) that want to "mix in" the methods of
our output interface. Let Foo and Bar inherit from Output_Strategy; and let
Output_Strategy inherit — based on a run-time setting — from one of
the actual strategy classes.
<code>
package Foo;
use base 'Output_Strategy'; # this is a 'strategy handle class'
. . .
# set the inheritance path at run time:
@Output_Strategy::ISA = ( $opt{'html'}
? 'Output_Strategy::HTML'
: 'Output_Strategy::CSV' );
</code>
And any time you need to change the strategy, you don't have to change the inheritance list (<c>@ISA</c>) of the "end user" classes (e.g. Foo).
</p>
<p>
<b>Note:</b> I'm not saying this is better than delegation. I just think it's a
potentially interesting alternative technique.
</p>
<h4>Glossary:</h4>
<ul>
<li>[jargon://Handle] (sense 3): an indirect, or two-level, reference</li>
<li>[c2://Strategy pattern]</li>
<li>[c2://Composition Instead Of Inheritance|Composition]</li>
<li>[c2://What Is Delegation|Delegation]</li>
<li>[c2://Adapter Pattern|Facade pattern] <i>aka</i> Wrapper</li>
<li>[c2://MixIn|Mix-ins]</li>
</ul>
<p>
<b>Update:</b> I have referred to this "double-indirection" of classes as <i>"handles"</i> because the technique reminded me of the double-indirection of memory management, used in some operating systems. In Windows, these are called handles, and it makes sense; it's the same idea as file handles, and in fact (IIUC), Windows handles are an abstraction over all of the system resources a process can access. Wikipedia has [wp://Handle (computing)|an article on Handles], and it says a handle is "an abstract reference to a resource". But that doesn't really describe what I'm doing here, which is more accurately called a <b>[wp://Bridge pattern|bridge]</b>. Wikipedia's article on [wp://Opaque pointer]s helpfully/confusingly refers to both handles and the Bridge pattern. :-)
</p>
<img src="https://www.cio.com/wp-content/uploads/2023/06/software_development_team_coding_programming_strategy_thinkstock_853580100-100749662-orig.jpg" width=200 ></img>
<hr/>
<div class="pmsig"><div class="pmsig-170442">
We're building the house of the future together.
</div></div>