Re: Removing inheritance (decorator pattern ?)
- From: George Sakkis <george.sakkis@xxxxxxxxx>
- Date: Mon, 16 Jun 2008 11:35:22 -0700 (PDT)
On Jun 16, 1:49 pm, Gerard flanagan <grflana...@xxxxxxxxx> wrote:
George Sakkis wrote:
I have a situation where one class can be customized with several
orthogonal options. Currently this is implemented with (multiple)
inheritance but this leads to combinatorial explosion of subclasses as
more orthogonal features are added. Naturally, the decorator pattern
[1] comes to mind (not to be confused with the the Python meaning of
the term "decorator").
However, there is a twist. In the standard decorator pattern, the
decorator accepts the object to be decorated and adds extra
functionality or modifies the object's behavior by overriding one or
more methods. It does not affect how the object is created, it takes
it as is. My multiple inheritance classes though play a double role:
not only they override one or more regular methods, but they may
override __init__ as well. Here's a toy example:
I don't know if it will map to your actual problem, but here's a
variation of your toy code. I was thinking the Strategy pattern,
different classes have different initialisation strategies? But then you
could end up with as many Strategy classes as subclasses, I don't know.
(Also in vaguely similar territory -http://bazaar.launchpad.net/~grflanagan/python-rattlebag/trunk/annota...
)
class MetaBase(type):
def __init__(cls, name, bases, data):
cls.strategies = []
cls.prefixes = []
for base in bases:
print base
if hasattr(base, 'strategy'):
cls.strategies.append(base.strategy)
if hasattr(base, 'prefix'):
cls.prefixes.append(base.prefix)
super(MetaBase, cls).__init__(name, bases, data)
class Joinable(object):
__metaclass__ = MetaBase
strategy = list
prefix = ''
def __init__(self, words):
self._words = words
for strategy in self.strategies:
self._words = strategy(self._words)
def join(self, delim=','):
return '%s %s' % (' '.join(self.prefixes), delim.join(self._words))
class Sorted(Joinable):
strategy = sorted
prefix = '[sorted]'
class Reversed(Joinable):
strategy = reversed
prefix = '[reversed]'
class SortedReversed(Sorted, Reversed):
pass
class ReversedSorted(Reversed, Sorted):
pass
if __name__ == '__main__':
words = 'this is a test'.split()
print SortedReversed(words).join()
print ReversedSorted(words).join()
This doesn't solve the original problem, the combinatorial explosion
of empty subclasses. At the end of the day, I'd like a solution that
uses a (mostly) flat, single-inheritance, hierarchy, allowing the
client say:
j = Joinable(words)
if sort:
j = Sorted(j)
if reverse:
j = Reversed(j)
...
print j.join()
George
.
- Follow-Ups:
- Re: Removing inheritance (decorator pattern ?)
- From: Maric Michaud
- Re: Removing inheritance (decorator pattern ?)
- References:
- Removing inheritance (decorator pattern ?)
- From: George Sakkis
- Re: Removing inheritance (decorator pattern ?)
- From: Gerard flanagan
- Removing inheritance (decorator pattern ?)
- Prev by Date: Re: sqlite3 and Python 2.5.1
- Next by Date: Re: PEP 372 -- Adding an ordered directory to collections
- Previous by thread: Re: Removing inheritance (decorator pattern ?)
- Next by thread: Re: Removing inheritance (decorator pattern ?)
- Index(es):
Relevant Pages
|