Python Patterns

Alex Martelli aleaxit at yahoo.com
Wed Oct 6 05:14:44 EDT 2004


Jacek Generowicz <jacek.generowicz at cern.ch> wrote:
   ...
> > Right, good point.  In C++ you can do something closer with the Strategy
> > pattern -- still one level of indirectness, but a consistent set of
> > methods (embodied in the one strategy object) commuted as a whole.
> > Assigning __class__ IS of course more direct, yes;-).
> 
> Isn't Strategy more like rebinding the methods of a class, rather than
> rebinding the .__class__ of an instance ?

<http://c2.com/cgi/wiki?StrategyPattern> has lots of discussion of State
vs Strategy (and no clear conclusion -- discussants disagree deeply on
philosophical grounds).  My viewpoint is that each is about objectifying
behavior -- as is delegating some or all behavior to another object.

Lookups of attributes (including methods) on an instance implicitly
delegate to the __class__ unless the attribute is found directly on the
instance [[lookups of special methods to implement operators &c don't
even look at the instance except in classic classes, but we can simply
focus on ordinary lookups here]].  Switching classes is thus switching a
bundle of attributes (particularly methods) as a whole, and affects only
the specific instance whose class changes, while switching a single
method on a class obviously has finer granularity on one plane (affects
a specific facet only) but HUGE on the other (affects any number of
instances at once).

I don't see anything in Strategy that suggests a desire to change the
behavior of an arbitrarily high number of instances at one stroke,
rather than the behavior of one single, specific instance.  So, I can't
really see the parallel you suggest.  Setting a bound method on an
instance, without altering that instance's class object at all, might be
closer, and as long as we're ignoring [[that part]] the parallel between
the techniques is there -- it's a matter of granularity (do you want to
affect each facet of behavior, or instance behavior as a whole).   The
commonality is in using implicit delegation, rather than explicit
(either via __getattr__ or method-by-method).

Basically, Python gives you more viable strategies than C++, so any
one-to-one mapping between usage in the two languages is doomed from the
start -- there will often be more than one strategy in Python that maps
down to the same strategy in C++.  Personally, I find that (for the
categories of programs I generally write) the meaningful unit of
behavior is rarely a single method (it happens, but it's not typical) --
there are generally _bundles_ (of methods representing subfacets of a
single "behavior") that must stay coupled and cohesive; so, switching
methods individually is not as attractive as switching a set of them
through a single object... and changing __class__ does exactly this for
the largest bundle (thus, ideal for a single-responsibility class... and
shouldn't those be the ones we should _strive_ to design?-).


Alex



More information about the Python-list mailing list