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