Design Patterns and Python OOP - Objects By Design.notes
Saturday, March 26, 2005
TITLE OF PAPER: Design Patterns and Python OOP - Objects By Design
URL OF PRESENTATION: _URL_of_powerpoint_presentation_
PRESENTED BY: Alex Martelli
REPRESENTING: Himself
CONFERENCE: PyCon 2005
DATE: Wednesday, March 23, 2005
LOCATION: GWU Cafritz Conference Center, Marvin Theatre
--------------------------------------------------------------------------
REAL-TIME NOTES / ANNOTATIONS OF THE PAPER:
{If you've contributed, add your name, e-mail & URL at the bottom}
OOP as delegation
intrinsic/implicit
instance delegates to its class
class delegates to descriptors or to base classes
overt/explicit
containment
delegation to self (but not in real life, haha)
inheritance: more rigid, "is-a" relationship
hold/wrap: more flexible, "uses-a" relationship (aka "has-a" ?)
Pydioms: Hold vs Wrap
Hold: Object O has subobject S as an attribute or property
use self.S.method or O.S.method
yields coupling in the wrong axis, i.e. every call to a method has to
know exactly how to reach that method
Wrap: hold (often via private name) plus delegation (so you use O.method)
explicit (def method(self...): ... self.S.method(...)
automatic (delegation in __getattr__)
gets coupling right (Law of Demeter), i.e. every call doesn't need to
know how to find every method
as a guideline, if you have more than one dot ('.') in an expression,
rethink it
Wrapping to restrict
Allow access to only some of the features of an object.
You can't do that with just inheritance (nicely).
Standard __getattr__ method doesn't work with special methods, which are
looked up in the class.
Self-delegation--keep your implementationy assumptions localized, and call abstract, conceptual methods on yourself when possible
Template Method Design Pattern (TMDP)
"template" word is way overloaded
Classic version
Abstract base has organizing methods
Subclasses have hook methods that implement functionality
Client code calls the organizing methods on the subclasses
Mixin version
mixin base's OM, concrete classes' hooks
Same general idea as the classic version
Example: Standard library's Queue class (Classic version)
Queue.put delegates to _put
Queue is not abstract
it is used as-is
must implement the hook methods as a result
Subclasses can customize the queueing discipline
Override methods or data
Example: DictMixin (Mixin version)
Abstract, meant for multiple inheritance
You must supply the hook methods: the elementary dict methods
at least __getitem__, keys
Sample subclass: Chainmap, which looks things up in a chain of
dictionaries
State and Strategy Design Patterns
Not unlike a "Factored-out" TMDP
OM in one class, hooks in others
OM calls self.somedelegate.dosomehook()
Classic vision
Strategy: One abstract class per decision
Factors out object behavior
State: Fully encapsulated, strongly coupled to context, self-modifying
Example
Imaging having a class with an "organizing method" (a method which calls a bunch of hook methods on a delegate), putting the delegate in an instance var, and then assigning to the top-level object's __class__ to change its behavior on the fly, without changing the hooks!
Object Oriented Programming for Polymorphism
Intrinsic/implicit/classic
single or multiple inheritance
Pythonic (based on Duck Typing)
Restricting attributes
Using __setattr__ so that only attributes that exist can be rebound
Avoids all the issues of __slots__
Not sure why we'd ever want this... :)
Null Object Design pattern
Instead of None, an object that is "innocuously polymorphic"
It can act like any object, kind of.
This can hide bugs!
Example: A NoLog logging object
Allows one to implement non-verbose logging semantics without spreading
special cases whereever you log.
OOP for instantiation
Singleton (there can be only one)
If one already exists, you get that one.
Problem, what happens when you have a subclass? Do you get the
superclass version or not?
Monostate (Borg)
Many instances share a single state
No new instance ever has a "problem"
Q: Why would you ever subclas
--------------------------------------------------------------------------
REFERENCES: {as documents / sites are referenced add them below}
aleaxit@gmail.com
--------------------------------------------------------------------------
QUOTES:
"How a duck learned to type I don't know..." Alex
--------------------------------------------------------------------------
CONTRIBUTORS: {add your name, e-mail address and URL below}
Nick Bastin (nick.bastin@gmail.com) <http://www.nickbastin.com>
Linden Wright (lwright@mac.com)
Abhay Saxena <ark3@email.com>
Nate Silva <nate@northwe.st>
Erik Rose <corp@grinchcentral.com>
--------------------------------------------------------------------------
E-MAIL BOUNCEBACK: {add your e-mail address separated by commas }
--------------------------------------------------------------------------
NOTES ON / KEY TO THIS TEMPLATE:
A headline (like a field in a database) will be CAPITALISED
This differentiates from the text that follows
A variable that you can change will be surrounded by _underscores_
Spaces in variables are also replaced with under_scores
This allows people to select the whole variable with a simple double-click
A tool-tip is lower case and surrounded by {curly brackets / parentheses}
These supply helpful contextual information.
--------------------------------------------------------------------------
Copyright shared between all the participants unless otherwise stated...