Some questions to think about Design Patterns Are design patterns… Template? Reusable code? Rule of thumb? Guuidelines? What IS a design pattern? • A pattern is a named abstraction from a concrete form that represents a recurring solution to a particular problem. • Patterns = problem/solution pairs in context • Patterns facilitate reuse of successful software architectures and design • Not code reuse – Instead, solution/strategy reuse – Sometimes, interface reuse • Best practices • “Patterns are discovered, not invented” - Richard Helm Are design patterns language specific? Most design patterns focus on OO Assume inheritance, polymorphism, encapsulation, etc. In procedural languages, might add OO features as “patterns” Some languages provide or make it easier to implement some patterns Categories of Patterns Design patterns vary in granularity and level of abstraction. By categorizing patterns, it becomes easier to recognize and learn them 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 Design Patterns Organization Design Patterns Purpose Creational Structural Behavioral Scope Objects Classes Other ways of organizing 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 Knowing your 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. Interface vs 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 operations, rather than hiding operations All subclasses then respond to requests in the interface of the abstract class Reuse: Two techniques • Inheritance: White box • Object Composition: Black box Why inheritance for reuse? Defined statically Supported directly by the language: straightforward to use Easier to modify implementation being reused Disadvantages of inheritance for reuse Can’t change inherited implementation at run-time Parent classes often define part of their subclasses physical representation Because inheritance exposes the parent implementation it’s said to “break encapsulation” Change in parent => Change in subclass If inherited attribute is inappropriate? Example A duck not only quacks, swims and…is displayed Ducks can…Fly!! How to give duck flying ability? Inheritance? Flying duck through inheritance How about Rubber Ducks? Don’t quack(); already overidden to squeak Don’t fly at all; overide to do nothing? What about DecoyDucks – They don’t quack or fly Slightly better solution Alternate solution: Interface for Ducks Compostion > Inheritance? Objects are accessed solely through their interfaces: no break of encapsulation Any object can be replaced by another a runtime: as long as they are the same type Favor object composition over class inheritance. But inheritance & composition work together Delegation “a way of making composition as powerful for reuse as inheritance”: 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 Triangle Delegation advantages Can change behaviors at run-time • Window can become circular at runtime by replacing Rectangle with Circle, (assuming Rectangle & Circle are same type!) There are run-time costs. Delegation in patterns: State, Strategy, Visitor, Mediator, Bridge Redesigned Duck Encapsulated Quack Behavior Encapsulated Fly behavior 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 rep or implementation: Abstract Factory, Bridge, Proxy Tight coupling: Abstract Factory, Command, Facade, Mediator, Observer, Bridge 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 Guidelines to prevent UnderEngineering Time constraints often force production of poorly designed code Leads to unmaintainable code 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 related to design patterns Getting the “right” pattern Taming over-enthusiasm you “win” if you use the most patterns everything solved by the last pattern you learned Over-Engineering More sophisticated or flexible than necessary Weaknesses of design patterns Targets wrong problem Missing language features Lacks formal foundations Does not provide reuse (like components) Leads to inefficient solutions Does not differ significantly from other abstractions Model-View-Controller predates GoF patterns How to choose a design pattern Know a basic catalog Scan intent section Study patterns of like purpose Consider a cause of redesign Refactor toward or away from patterns to avoid over/under design Much thanks to R.Stehwein!