260 likes | 476 Views
Design Patterns. Introduction What is a pattern? Design Patterns -- definitions Examples. Introduction. Developers never solve every problem from first principles We re-use old solutions which have worked, adapting them to the new situation.
E N D
Design Patterns Introduction What is a pattern? Design Patterns -- definitions Examples
Introduction • Developers never solve every problem from first principles • We re-use old solutions which have worked, adapting them to the new situation. • We re-use successful designs by basing any new design on prior experience. • A bit of history • The idea originated with a building architect, Christopher Alexander in the 1970s who applied it to architecture and urban planning in 1970s • In 1987, Ward Cunningham and Kent Beck devised five patterns for the guidance of Smalltalk (an early OO language) programmers • A programming problem could be solved by finding which of the patterns best matches the problem, and using this pattern to “cut” a solution • Around 1990, Jim Coplien began collecting C++ idioms for use as patterns to guide programmers • Design Patterns grew in 1990-94 from these beginings Introduction to Design Patterns
Introduction • What do we mean by a pattern? • “an abstraction from a concrete form which keeps recurring in vrious specific contexts” • It captures the essence of many approaches to a design problem: what is the “right” approach • Design Patterns • Simple, elegant, flexible solutions to specific problems. • Solutions have evolved over time • Not always obvious -- result from hard work + sharing and evaluating of ideas • An insight into flexible, modular, re-usable design • The “bible” is Design Patterns, by Erich Gamma, Richard Helm, Ralph Johnson & John Vlissides et al, Addison-Wesley, 1995, ISBN 0201633612 • op Read Bennett, McRobb & Farmer, Object Oriented Systems Analysis & Design using UML, chapter 14. Introduction to Design Patterns
What is a Pattern? • So what exactly is a software design pattern? There are 4 essential elements of a design pattern: • the Pattern Name • the Problem • This describes when the pattern can be applied: to what kind of problem, and what pre-conditions need to be met to apply it • the Solution • A template or abstract description of the problem solution in terms of a set of classes (objects) with particular functionalities and interrelationships • Consequences • presenting the results and tradeoffs of using the pattern, helping you decide the best choice from among several promising alternatives. Introduction to Design Patterns
Design Patterns • Additional information might include concrete, detailed examples of use • There are many design patterns, catalogued for easy navigation and comparison: • Some Design Patterns - • Structural Patterns • Composition of classes/objects • Example: the Adapter pattern converts the interface of a class into another interface clients expect. • Example: the Composite pattern composes objects into tree-structures to represent part/whole relationships and lets clients treat individuals and groups uniformly. • Example: the Decorator pattern attaches additional responsibility to an object dynamically -- more flexibly than subclassing. Introduction to Design Patterns
Design Patterns • Creational patterns • The process of object construction • Example: the Singleton pattern is for a class that has only one instance • Example: the Abstract Factory pattern provides an interface for creating families of related or dependent objects without specifying their concrete class. • Example: the Factory Method pattern defines an interface for creating an object of some class but defers instantiation to subclasses • Behavioural Patterns • The way classes and objects interact • Example: the Iterator pattern provides an interface for accessing elements of an aggregate, such as a vector or a list, without exposing the aggregates interface or internal structure. Introduction to Design Patterns
Design Patterns • Behavioural Patterns ctd • Example: the Observer pattern defines a 1 to many dependency between objects so that when one changes state, all dependents are notified and updated. • Example: the Strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable: the functinality of an object can be varied by plugging in a different one. • Example: the Template Method pattern defines the skeleton of an algorithm in an operation (function), deferring some steps to a subclass; multiple subclasses redefine certain steps of the algorithm without changing the algorithm’s structure. • Example: the State pattern allows an object to alter its behaviour when its internal state changes. The object will appear to change its class. • Example: the Command pattern encapsulates a request as an object, so we can parameterize clients with different requests, queue/log requests, support undoable operations. Introduction to Design Patterns
<<abstract>>Component op1(); Leaf op1( ); Example: Composite Design Pattern • A group of objects where • An object can be an individual or a group of objects • Individuals and groups are to be treated the same way. aggregation possibly an interface 1..* several ops 0..1 ... Composite op1( ); addChild( ) removeChild( ) for each child g, g.op1(); possibly other methods for managing children Introduction to Design Patterns
Example: Composite Design Pattern • Component interface • Specifies the interface common to all objects in the composition • Leaf classes (several different, in general) • Each implements Component and and defines behaviours for primitive objects in the composition. These objects have no children. • Composite class • Implements Component and defines behaviours for components with children. Normally this will consists of iterating through the children, performing the behaviour with each child. Introduction to Design Patterns
aggregation 1..* Shape 0..1 Rectangle Circle Oval Line Drawing Example: Composite Design Pattern • Example of using this • A Drawing is group -- an aggregate of Shape objects • A Shape is a Rectangle or an Oval or a Circle or a Line or group of shapes • Derive Rectangle, Oval, Line, Circle, from abstract base class Shape • We want a group of shape elements to be handled (positioning, resizing, ...) in the same way as individual shape elements • A Drawing is just such a group -- so derive it from Shape too: Introduction to Design Patterns
Composite Design Pattern applied to Shapes • A Shape is associated with 0 or 1 Drawing • A Drawing contains one or more Shapes • ...which may recursively be individual Rectangles, Ovals etc, or Drawings, ie groups • At the moment, we have four “leaf” subclasses. • Common Shape operations (“op1()”) will be declared abstract in Shape and implemented in the subclasses. • Drawing subclass additionally needs addChild, removeChild() children management methods • The Java implementation • MyShape.java is the abstract base class • listing attached to these notes • MyOval.java, MyCircle are a typical “leaf” classes • listings attached to these notes • MyRectangle.java, MyLine.java • More “leaf” classes: you are asked to write these in the practical exercise Introduction to Design Patterns
Composite Design Pattern applied to Shapes • The Java implementation of the “composite” class, MyDrawing.java. • It is derived from MyShape: public class MyDrawing extends MyShape { • It needs a way of storing its children: Vector children = new Vector(); • Constructor is similar to the others’ -- but width and height are 0: public MyDrawing(int x, int y) { super(x, y, 0, 0); } • It has methods for adding and removing a shape: public void add(MyShape s) { children.addElement(s); } public void remove(MyShape s) { children.removeElement(s); } Introduction to Design Patterns
Composite Design Pattern applied to Shapes • The Java implementation of the “composite” class • Re-sizing is not allowed for Drawings: public void size(int wdth, int hgt) { throw new UnsupportedOperationException(); } • You move a Drawing by moving all the shapes it contains: public void move(int x, int y) { int dx = x - getX(); int dy = y - getY(); Iterator it = children.iterator(); while(it.hasNext()) { MyShape s = (MyShape)it.next(); int newX = s.getX() + dx; int newY = s.getY() + dy; s.move(newX, newY); } } • NB Vectors and Iterators live in java.util.* • Likewise, draw a Drawing by delegating: Introduction to Design Patterns
Composite Design Pattern applied to Shapes • The Java implementation of the “composite” class • Likewise, draw a Drawing by delegating: public void draw(Graphics g) { Iterator it = children.iterator(); while(it.hasNext()) { MyShape s = (MyShape)it.next(); s.draw(g); } } • Using the composite Pattern Introduction to Design Patterns
Using Composite Pattern • We start with a drawing: private MyDrawing shapes =new MyDrawing(0,0); • That we populate with shapes shapes.add(new MyRectangle(13,25,100,200)); shapes.add(new MyCircle(110,150,100)); shapes.add(new MyRectangle(10,50,200,200)); • That can be drawings private MyDrawing blob = new MyDrawing(30,20); shapes.add(blob); blob.add(new MyRectangle(13,25,100,200)); blob.add(new MyCircle(110,150,100)); • We can then move parts blob.move(30,15); • Or the whole shapes.move(10,15); • And draw it all to a graphics object shapes.draw(g); Introduction to Design Patterns
Using Composite Pattern • An Advantage of Polymorphism: • Adding a new shape requires no modification of existing code • 1. Derive the new shape from MyShape overriding the draw method • 2. That’s it. • All code that uses MyShape will work with the new shape. • Alternative designs can use type information explicitly • e.g. instanceof() • These are likely to require additional modifications • You have to take care with the use of run time type information • Avoid “switch on type” constructs. Introduction to Design Patterns
Example: Adapter Pattern <<interface>> Target Client AdapterClass AdapteeClass <<interface>> Target Client AdapteeClass AdapterClass • Converts the interface of a class into another interface clients expect. • Note the two versions: object version and class version • Target interface specifies the interface that Client expects • Adaptee is a class that provides desired functionality but an interface need to be adapted to Target • Adapter provides adapted interface either by subclassing or by “owning” an Adaptee object. Introduction to Design Patterns
Shape TextShape Line boundingBox() createManipularor() boundingBox() createManipularor() boundingBox() createManipularor() TextView getExtent() Example: Adapter Pattern Drawing Editor return text.getExtent() return new TextManipulator Ref: Gamma et al p 139 fff Introduction to Design Patterns
<<abstract>> Creator product createProduct( ): op(); ConcreteCreator createProductl( ) : ConcreteProduct op() Example: Factory Method Pattern <<interface>> Product ConcreteProduct ... return new ConcreteProduct(); • Defines an interface for creating an object of some class but defers instantiation to subclasses • Abstract Creator class specifies factory method • ConcreteCreator class -- several of these -- each extends Creator and implements its factory method createProduct • Product interface -- the interface of objects created by the factory method • ConcreteProduct classes -- several -- implement the interface. Objects created by the factory method are instances of these classes. Introduction to Design Patterns
Document open() close() save() revert() MyApplication createDocumentl( ) : MyDocument Example: Factory Method Pattern Application docs createDocument( ): newDocment(); openDocument …. Document doc = createDocument() docs.add(doc); doc.open(); MyDocument ... return new MyDocument(); • Ref: Gamma et al p 107 Introduction to Design Patterns
<<interface>> Iterator <<interface>>Aggregate next():Object; hasNext(): boolean getIterator(); ConcreteAggregate ConcreteIterator getIterator(): Iterator next():Object; hasNext(): boolean Example: Iterator Pattern • Iterator interface specifies operations for accessing a given category of collections • ConcreteIterator class implements Iterator interface. Each object keeps track of its current position in the traversal of the underlying aggregate. • Aggregate interface specifies operations for aggregates, which must include an operation for returning an Iterator. • ConcreteAggregate class implements this -- could be Vector or Collection or user defined, based on these or an array • Client interacts with a ConcreteAggregate through the Iterator interface. • We have already made soome use of this pattern! Client 1 * Introduction to Design Patterns
Java.util. Iterator Java.util. Collection iterator(); next():Object; hasNext(): boolean Vector (anon class) iterator(): Iterator next():Object; hasNext(): boolean Example: Iterator Pattern • See Java util package documentation. Iterator is intended as a replacement for Enumeration (which has simlar abstract methods hasMoreElements(), nextElement(); a Vector also has a method elements() which returns an object of anonymous class implementing Enumeration ) Introduction to Design Patterns
<<abstract>> AbstractClass templateMethod( ) op1( ) op2( ) ConcreteClass ConcreteClass2 op1( ) op2( ) op1( ) op2( ) Example: Template Method Pattern • Defines the skeleton of an algorithm in an operation (function), deferring some steps to a subclass; multiple subclasses redefine certain steps of the algorithm without changing the algorithm’s structure. • AbstractClass specifies one or more template methods that implement a partially complete algorithm and specify abstract hook methods that the template mwthod(s) will use. • ConcreteClass extends AbstractClass, implementing the hook methods in various specific ways ... op1(); ... op2(); ... Introduction to Design Patterns
<<abstract>> Subject <<interface>>Observer add(Observer) remove(Observer) notifyAll( ) update(Event) ConcreteObserver update(Event) Example: Observer Pattern * • Defines a 1 to many dependency between objects so that when one changes state, all dependents are notified and updated. • Subject class maintains list list of Observer objects; has methods for adding and removing Observers and notifying them of changes of state in the Concrete Subject. • ConcreteSubject – particular class of interest • Observer interface specifies the interface by which ConcreteObservers are notified • ConcreteObserver implements Observer interface and provides particular behaviours for responding to changes in ConcreteSubject’s state. ConcreteSubject For each observer o o.update( ) …. Introduction to Design Patterns
Example: Strategy Pattern 1 <<interface>> Strategy Context • Defines a family of algorithms, encapsulates each one, and makes them interchangeable: the functinality of an object can be varied by plugging in a different one. • Strategy interface specifies the interface implemented by all ConcreteStrategy classes (which implement various particular Strategies) • Context class maintains a reference to some ConcreteStrategy objectand invikes it through the Strategy interface to execute a strategy. ConcreteStrategy2 … ConcreteStrategy2 1 <<interface>> LayoutManager Container GridLayout FlowLayout Introduction to Design Patterns