“Patterns are discovered, not invented”Richard Helm
What’s a pattern?
A pattern is a named abstraction from a concrete form that represents a recurring solution to a particular problem.
Categories of Patterns
Design patterns vary in granularity and level of abstraction.By categorizing patterns, it becomes easier to recognize and learn thempatterns can be categorized bypurposeorscopepurposereflects what the pattern doesscopespecifies if the pattern applies to classes or objects
reflects what the pattern doesCreational-- facilitate object creationStructural-- deal with the composition of classes or objectsBehavioral-- deal with the way objects interact and distribute responsibility
whether the pattern applies toclassesorobjectsclass patterns:deal with relationships between classes or subclasses established through inheritancethese relationships are fixed at compile timeobjects patterns: deal with object relationships that can be changed at runtime
other ways to organize patterns
some patterns are frequently used with other patterns, for example composite is often used with visitor and/or iteratorsome patterns are alternatives: Prototype is usually an alternative for Abstract FactorySome patterns are very similar in structure, such as Composite and Decorator
How do Design Patterns Solve Design Problems?
The meaning of OO is well-knownThe hard part is decomposing the system into objects to exploit:encapsulationflexibility, extensibilityease of modificationperformanceevolutionreusability
Many objects in the design come from the analysis modelBut OO designs often end up with classes that have no counterpart in the real worldDesign Patterns help the modeler to identify less obvious abstractions and the objects that can capture them.
Inheritance is a mechanism for reuseyou can define a new kind of object in terms of the old oneyou get new implementations almost for free, inheriting most of what you need from an existing classThis is only half the story!
Program to an interface,not an implementation
Inheritance permits defining afamily of objectswithidentical interfacespolymorphismdepends on this!all derived classes share the base class interfaceSubclasses add or override 0perations, rather than hiding operationsAll subclasses then respond to requests in the interface of the abstract class
Inheritance properly used
clients are unaware of types of objects:heuristic 5.12 - “explicit case analysis on the type of an object is usually an error. The designer should use polymorphism”.Rielclients only know about the abstract classes defining the interface.heuristic 5.7: “All base classes should be abstract”.RielThis reduces implementation dependenciesprogram to an interface, not an implementationcreational patterns help ensure this rule!
Two techniques for reuse
inheritance:white boxobjectcomposition:black box
advantage of inheritance for reuse
defined staticallysupported directly by the language: straightforward to useeasier to modify implementation being reused
disadvantage of inheritance
can’t change inherited implementation at run-timeparent classes often define part of their subclass’s physical representationbecause inheritance exposes the parent implementation it’s said to “break encapsulation” (GOF p.19, Sny86)change in parent => change in subclassWhat if inherited attribute is inappropriate?
object composition:black boxreuse
objects are accessedsolelythrough their interfaces: no break of encapsulationany object can be replaced by another at runtime: as long as they are the same typefavor object composition over class inheritance. GOF p. 20but inheritance & composition work together!
“a way of making composition as powerful for reuse as inheritance”:GOF, p. 20[JZ91] Ralph Johnson and Jonathan Zweig,Delegation in C++,JOOP, f(11):22-35, Nov. 91[Lie86] Henry Lieberman.Using prototypical objects to implement shared behavior in OO systems. OOPSLA, pp 214-223, Nov. ‘86
In delegation, 2 objects handle a requestanalogous to subclass deferring request to parentin delegation, the receiver passes itself to the delegate to let the delegated operation refer to the receiver!
delegating area() to rectangle
advantages of delegation
can change behaviors at run-timewindow can become square at run-time by replacing Rectangle with Square,(assuming Rectangle & Square are same type!)There are run-time costs.delegation in patterns: State, Strategy, Visitor, Mediator, Bridge
delegating area() to square
Patterns make design resistant to re-designRobustness to Change
Algorithmic dependencies: Template Method, Visitor, Iterator, Builder, Strategy.Creating an object by specifying a class explicitly: Abstract Factory, Factory Method, PrototypeDependence on specific operations: Command, Chain of ResponsibilityDependence on object representation or implementation: Abstract Factory, Bridge, ProxyTight coupling: Abstract Factory, Command, Facade, Mediator, Observer, Bridge
Patterns make design resistant to re-design
Extending functionality by subclassing: Command, Bridge, Composite, Decorator, Observer, StrategyInability to alter classes conveniently: Visitor, Adapter, Decorator
Design Inexperience: “Is my design ok?”Patterns engender confidenceused twice & blame the GOFstill room for creativity
Large portion of design can be covered by patternsSeductively simple to implementmost explained in a few pagesadd no “extra-value” to end-userYou still have to write functionality: patterns don’t solve the problem
Most people know the patternsIf you’re looking at someone’s design & you identify a pattern, you immediately understand much of the designCommon design vocabulary“Let’s use a Builder here”Design language beyond language syntaxProblem-oriented languageprogram inrather thanintothe language
Getting the “right” patternTaming over-enthusiasmyou “win” if you use the most patternseverything solved by the last pattern you learned
How to select a pattern
know a basic catalogscan intent sectionstudy patterns of like purposeconsider a cause of redesign