Design Patterns Introduction “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 them patterns can be categorized by purpose or scope purpose reflects what the pattern does scope specifies if the pattern applies to classes or objects purpose reflects what the pattern does Creational -- facilitate object creation Structural -- deal with the composition of classes or objects Behavioral -- deal with the way objects interact and distribute responsibility scope whether the pattern applies to classes or objects class patterns: deal with relationships between classes or subclasses established through inheritance these relationships are fixed at compile time objects 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 iterator some patterns are alternatives: Prototype is usually an alternative for Abstract Factory Some patterns are very similar in structure, such as Composite and Decorator How do Design Patterns Solve Design Problems? The meaning of OO is well-known The hard part is decomposing the system into objects to exploit: encapsulation flexibility, extensibility ease of modification performance evolution reusability Finding objects Many objects in the design come from the analysis model But OO designs often end up with classes that have no counterpart in the real world Design Patterns help the modeler to identify less obvious abstractions and the objects that can capture them. Inheritance Inheritance is a mechanism for reuse you can define a new kind of object in terms of the old one you get new implementations almost for free, inheriting most of what you need from an existing class This is only half the story! Program to an interface, not an implementation Inheritance permits defining a family of objects with identical interfaces polymorphism depends on this! all derived classes share the base class interface Subclasses add or override 0perations, rather than hiding operations All 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”. Riel clients only know about the abstract classes defining the interface. heuristic 5.7: “All base classes should be abstract”. Riel This reduces implementation dependencies program to an interface, not an implementation creational patterns help ensure this rule! Two techniques for reuse inheritance: white box object composition: black box advantage of inheritance for reuse defined statically supported directly by the language: straightforward to use easier to modify implementation being reused disadvantage of inheritance can’t change inherited implementation at runtime parent classes often define part of their subclass’s physical representation because inheritance exposes the parent implementation it’s said to “break encapsulation” (GOF p.19, Sny86) change in parent => change in subclass What if inherited attribute is inappropriate? object composition: black box reuse objects are accessed solely through their interfaces: no break of encapsulation any object can be replaced by another at runtime: as long as they are the same type favor object composition over class inheritance. GOF p. 20 but inheritance & composition work together! Delegation “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 214223, Nov. ‘86 delegation: reuse In delegation, 2 objects handle a request analogous to subclass deferring request to parent in delegation, the receiver passes itself to the delegate to let the delegated operation refer to the receiver! delegating area() to rectangle Rectangle Window area() return rectangle->area() Has-a area() width height return width*height advantages of delegation can change behaviors at run-time window can become square at runtime 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 Square Window area() return square->area() Has-a area() side return side*side Patterns make design resistant to re-design Robustness to Change Algorithmic dependencies: Template Method, Visitor, Iterator, Builder, Strategy. Creating an object by specifying a class explicitly: Abstract Factory, Factory Method, Prototype Dependence on specific operations: Command, Chain of Responsibility Dependence on object representation or implementation: Abstract Factory, Bridge, Proxy Tight coupling: Abstract Factory, Command, Facade, Mediator, Observer, Bridge Patterns make design resistant to redesign Extending functionality by subclassing: Command, Bridge, Composite, Decorator, Observer, Strategy Inability to alter classes conveniently: Visitor, Adapter, Decorator Design Confidence Design Inexperience: “Is my design ok?” Patterns engender confidence used twice & blame the GOF still room for creativity Design Coverage Large portion of design can be covered by patterns Seductively simple to implement most explained in a few pages add no “extra-value” to end-user You still have to write functionality: patterns don’t solve the problem Design Understanding Most people know the patterns If you’re looking at someone’s design & you identify a pattern, you immediately understand much of the design Common design vocabulary “Let’s use a Builder here” Design language beyond language syntax Problem-oriented language program in rather than into the language Common Problems Getting the “right” pattern Taming over-enthusiasm you “win” if you use the most patterns everything solved by the last pattern you learned How to select a pattern know a basic catalog scan intent section study patterns of like purpose consider a cause of redesign