a new design pattern for Python Library?

T

The Eternal Squire

Hi,

I tend to use this design pattern a lot in order to aid in
compartmentalizing interchangeable features in a central class that
depend on the central class's data. I know that explicit class
friendship designs syntactic sugar, but I am thinking this should be a
standard design pattern to make friendship dependencies a little more
self documenting.

Opinions?

The Eternal Squire


class Friend (object):
def __init__ (self, friend):
object.__init__ (self)
self.friend = friend


Example use:

class Bar (Friend):
TITLE = None
DEFAULT = 1
def __init__ (self, top):
Friend.__init__ (self, top)
self.data = self.default * self.default

def __str__ (self):
print "%s mode %d default = %d" % (self.__class__.__name__,

self.friend.mode,
self.data)


class ABar (Bar):
DEFAULT = 2


class Foo:
BAR = ABar

def __init__ (self):
self.bar = self.BAR (self)
self.mode = 1

def __str__ (self):
return str (self.bar)
 
B

Ben Sizer

The said:
I tend to use this design pattern a lot in order to aid in
compartmentalizing interchangeable features in a central class that
depend on the central class's data.

I'm afraid I've read this paragraph and the code 3 times and I still
have no idea what you're trying to convey. Perhaps it's just because
your example is too abstract to me. It does look like it obscures the
role of the classes involved however, which doesn't seem like a good
thing to me. What do you consider a 'friendship dependency'? Is this
just the Strategy pattern?
 
T

The Eternal Squire

Let me try again:

Suppose I have a central class with complex behavior that I want to
simply write as a bare skeleton upon which to hang the auxillary
classes that help provide the complex behavior.

The naive approach would be to write:

class Skeleton:
def __init__ (self):
self.core_data = 1

class Auxillary:
def __init__ (self):
pass

def string (self, skeleton):
return "%s %d" % (self.__class__.__name__, skeleton.core_data)


skeleton = Skeleton ()
auxillary = Auxillary ()
auxillary.behavior ()


What I will typically do is create the auxillary class as a friend so
that I can have tighter integration between the Skeleton instance and
an Auxillary member instance, where the Auxillary instance isolates
behavior that I might want to modify later through inheritance.

class Auxillary (Friend):
def __str__ (self):
return "%s %d" % (self.__class__.__name__, self.friend.core_data)

class Skeleton:
def __init__ (self):
self.auxillary = Auxillary (self)

skeleton = Skeleton ()

print skeleton.auxillary


See the difference? I know this is a bit contrived, but I wanted to
keep the effect simple. Effectively I now have a self-documenting
friend relationship between classes.

The Eternal Squire
 
B

Ben Sizer

The said:
Suppose I have a central class with complex behavior that I want to
simply write as a bare skeleton upon which to hang the auxillary
classes that help provide the complex behavior.

So, it's akin to the GoF's Template Method or Strategy patterns, then.
What I will typically do is create the auxillary class as a friend so
that I can have tighter integration between the Skeleton instance and
an Auxillary member instance, where the Auxillary instance isolates
behavior that I might want to modify later through inheritance.

class Auxillary (Friend):
def __str__ (self):
return "%s %d" % (self.__class__.__name__, self.friend.core_data)

class Skeleton:
def __init__ (self):
self.auxillary = Auxillary (self)

skeleton = Skeleton ()

print skeleton.auxillary

This looks just like the Strategy pattern except that instead of
storing the skeleton as a value within Auxiliary, you use a 'Friend'
base class. I would argue that this obscures the code rather than makes
it clearer. I would do this sort of thing in C++ where you need that
base class to enforce the interface, but not in Python. I don't care
what type I assign to self.auxillary as long as it supports the
methods/properties I require, and it shouldn't care whether it's being
assigned to a Skeleton or something else, as long as that object
provides the data it requires.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,173
Latest member
GeraldReund
Top