SW DP Books

Ybur Brain on Design Patterns

Head First

Design Patterns

Design Patterns Explained tic««« laimn

Design Patterns

Elements of Reusable Objecl-Orienled Software

Dating Design Patterns


CHvîi1 e Jriened Prc^ranming

Encto» CkKdon Rickje Hanson Rhonda Jackson Jonoa Dr»vtesea

Design Patterns

Smalltalk Companion

Pattern Hatching llb^ji follow Aft&d

Modern C++ Design

AndrH Atexandmcu

NwMPilvtaMliiyvi MWN hr M» ^»w

Fric h Gd m ma Richard Helm Ralph Johnson lohn VlisskJes


? p innurui TO rA I TERNS

J<AHâf KffMtVMCt


0 many "classic" DP (for C++ or Java) are "workarounds against static typing" (cfr: Alpert, Brown, Woolf, "The DPs Smalltalk Companion", Addison-Wesley DP Series)

in Python: classic DP, minus WaFST, plus (optionally...:-) specific exploits of Python's dynamic and introspection strengths

0 no silver bullet, but, quite helpful IRL

® NAMES matter more than you'd think d "the guy with the hair, you know, the Italian" vs "Alex"...


# concern the ways and means of object instantiation

Structural a deal with the mutual composition of classes or objects


0 analyze the ways in which classes or objects interact and distribute responsibilities among them

« "program to an interface, not to an implementation"

a usually done "informally" in Python

0 "favor object composition over class inheritance"

0 in Python: hold, or wrap

0 inherit only when it's really convenient a very direct way to expose all methods in the base class (reuse + usually override + maybe extend)

0 but, it's a rather strong coupling!

& "Hold": object O has subobject S as an attribute (maybe property) -- that's all use self.S.method or O.S.method simple, direct, immediate, but... pretty strong coupling, often on the wrong axis d "Wrap": hold (often via private name) plus delegation (so you directly use O.method)

# automatic (delegation in_getattr_)

gets coupling right (Law of Demeter)

class RestrictingWrapper(object):

self._w = w self._block = block def __getattr__(self, n):

if n in self._block: raise AttributeError, n return getattr(self._w, n) • • •

Inheritance cannot restrict!

not very common in Python... ...because "factory" is essentially built-in!


Wf 3


"we want just one instance to exist" d use a module instead of a class

# no subclassing, no special methods, ... 0 make just 1 instance (no enforcement)

# need to commit to "when" to make it d singleton ("highlander")

# subclassing not really smooth d monostate ("borg")

0 Guido dislikes it class Singleton(object):

if not hasattr(cls, '_inst'): cls._inst = super(Singleton, cls

return cls._inst subclassing is a problem, though: class Foo(Singleton): pass class Bar(Foo): pass f = Foo(); b = Bar(); # ...???...

problem is intrinsic to Singleton class Borg(object): _shared_state = {}

obj = super(Borg, cls

obj___dict__ = cls._shared_state return obj subclassing is no problem, just:

class Foo(Borg): pass class Bar(Foo): pass class Baz(Foo): _shared_state data overriding to the rescue!

"we don't want to commit to instantiating a specific concrete class"

0 dependency injection

0 no creation except "outside"

0 what if multiple creations are needed?

0 "Factory" subcategory of VPs

0 may create w/ever or reuse existing

0 factory functions (& other callables)

0 factory methods (overridable)

0 abstract factory classes each type/class is intrinsically a factory

# internally, may have_new_

& externally, it's just a callable, interchangeable with any other

& may be injected directly (no need for boilerplate factory functions)

modules can be kinda "abstract" factories w/o inheritance ('os' can be 'posix' or 'nt')

if isinstance(nu, cls):

return nu

(An instance of "two-phase construction")

m = —import—(pkg,{},{},[obj]) return getattr(m, obj)

# example use:

Structural Patterns

The "Masquerading/Adaptation" subcategory:

a Adapter: tweak an interface (both class and object variants exist)

0 Facade: simplify a subsystem's interface a Bridge: let many implementations of an abstraction use many implementations of a functionality (without repetitive coding)

d Decorator: reuse+tweak w/o inheritance d Proxy: decouple from access/location f ÂCI

client code y requires a protocol C supplier code " provides different protocol S (with a superset of C's functionality) 0 adapter code a "sneaks in the middle":

0 to Y/ & is a supplier (produces protocol C)

to a is a client (consumes protocol S) 0 "inside", a implements C (by means of appropriate calls to S on ")

Was this article helpful?

0 0

Post a comment