Removing inheritance (decorator pattern ?)
Gerard flanagan
grflanagan at gmail.com
Mon Jun 16 13:49:52 EDT 2008
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/annotate/head:/src/template.py
)
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()
More information about the Python-list
mailing list