103
Satya Puvvada Design Patterns Satya Puvvada

Satya Puvvada Design Patterns Satya Puvvada. Objectives Gain an understanding of using design patterns to improve design and implementation Learn

Embed Size (px)

Citation preview

Satya Puvvada

Design Patterns

Satya Puvvada

Satya Puvvada

Objectives

Gain an understanding of using design patterns to improve design and implementation

Learn to develop robust, efficient and reusable C++ programs using design patterns

Satya Puvvada

Contents – Day 1 Introduction to design patterns Introduction to UML notation Patterns

– Singleton– Factory method– Abstract Factory– Observer– Strategy– Adapter– Visitor

Satya Puvvada

Contents – Day 2

Patterns– Builder

– Bridge

– Facade

– Proxy

– Composite

– Chain of responsibility

– Command

Satya Puvvada

Contents – Day 3

Patterns– Flyweight

– Memento

– State

– Decorator

– Prototype

– Mediator

Case Study References and conclusions

Satya Puvvada

Why design patterns

Developing software is hard Designing reusable software is more

challenging– finding good objects and abstractions– flexibility, modularity, elegance reuse– takes time for them to emerge, trial and

error Successful designs do exist

– exhibit recurring class and object structures

Satya Puvvada

Why OO Design Patterns

Effective for teaching OOD OOP is a new Art form

– People have only had ~20 years experience with OOP

– Architecture and painting have been around for thousands of years.

Effective method of transferring skill and experience– new OO programmers can be overwhelmed by the

options

Satya Puvvada

History of Design Patterns

Christopher Alexander - an architect – “The Timeless Way of Building”, 1979– “A Pattern Language”, 1977– Pattern - “ A solution to a problem in a context”– Purposes

• effective reuse

• dissemination of solutions

Satya Puvvada

History in OOP

1987 workshop at OOPSLA Beck and Ward 1993 The Hillside Group - Beck, Ward,

Coplien, Booch, Kerth, Johnson 1994 Pattern Languages of Programming

(PLoP) Conference 1995 Design Patterns : Elements of

Reusable OO software - Gamma, Helm, Johnson, Vlissides (Gang of Four)

Satya Puvvada

Definitions / Terminology

Pattern Language - a term from Christopher Alexander, not a software language but a group of patterns used to construct a whole

Pattern - many definitions see FAQ, lets try this one: “Patterns represent distilled experience which, through their assimilation, convey expert insight and knowledge to inexpert developers. “ - Brad Appleton

Satya Puvvada

What is a design pattern a standard solution to a common programming

problem a technique for making code more flexible by making it

meet certain criteria a design or implementation structure that achieves a

particular purpose a high-level programming idiom shorthand for describing certain aspects of program

organization connections among program components the shape of a heap snapshot or object model

Satya Puvvada

What is a design pattern

Describes recurring design structure– names, abstracts from concrete designs– identifies classes, collaborations,

responsibilities applicability, trade-offs, consequences

Satya Puvvada

What is a design pattern Design patterns represent solutions to problems

that arise when developing software within a particular context

“Patterns == problem/solution pairs in a context”

Patterns capture the static and dynamic structure and collaboration among key participants in software designs

Especially good for describing how and why to resolve nonfunctional issues

Patterns facilitate reuse of successful software architectures and designs.

Satya Puvvada

Applications

Wide variety of application domains: drawing editors, banking, CAD, CAE, cellular network management, telecomm switches, program visualization

Wide variety of technical areas: user interface, communications, persistent objects, O/S kernels, distributed systems

Satya Puvvada

Definition

“Each pattern describes a problem which occurs over and over again in our environment and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it in the same way twice”

Christopher Alexander, A Pattern Language, 1977

Satya Puvvada

Design Patterns

A pattern has 4 essential elements:– Pattern name– Problem– Solution– Consequences

Satya Puvvada

How a Pattern is Defined(GoF form) Name - good name Intent- what does it do Also Known As Motivation - a

scenario Applicability - when

to use Structure- UML

Participants - classes Collaborations - how

they work together Consequences - trade

offs Implementation- hints

on implementation Sample Code Known Uses Related Patterns

Satya Puvvada

Classes of Design Patterns Creational patterns:

– Deal with initializing and configuring classes and objects

Structural patterns:– Deal with decoupling interface and

implementation of classes and objects– Composition of classes or objects

Behavioral patterns:– Deal with dynamic interactions among

societies of classes and objects– How they distribute responsibility

Satya Puvvada

UML Notation

Satya Puvvada

Class symbol

1. Name compartment

2. Attribute compartment

3. Operation compartment

4. Class name

5. Properties

6. Stereotype

Satya Puvvada

Class diagram - associations

Used to associate classes Symbol used is a line with some

adornments Each association is given a name that

matches the association

Satya Puvvada

Class diagram - multiplicity

A number of objects of each class may be associated Customer may open many accounts, order may

contain many items

Asterisk (*) when used alone means zero or more, no lower or upper limitAsterisk (*) when used in a range (1..*) means no upper limitValues separated by two periods (..) means a range.Values separated by commas means an enumerated list of values .

Satya Puvvada

Class diagram - multiplicity

Satya Puvvada

Class diagram – Roles and constraints

When an association cannot be give a name a role can be assigned to either ends of the association

Satya Puvvada

Class diagram – Roles and constraints

1. Role: Must have a name or roles or both

2. Association name: Must have a name or roles or both

3. Role: Must have a name or roles or both

4. Class

5. Constraint: Optional

6. Multiplicity: Required

7. Association

8. Multiplicity: Required

9. Class

Satya Puvvada

Class diagram – Reflexive associations

1. Objects in the same class is associated

Satya Puvvada

Class diagram – Qualified associations

1. Used to reduce multiplicity

2. Used like a database index

3. Can be used when both sides of an association has 0..*

Satya Puvvada

Class diagram – Association classes

1. A class that is used to give information about an association

Satya Puvvada

Class diagram – Aggregation and composition

1. Special type of association

2. Used to show that a class is made up of other classes

Satya Puvvada

Class diagram – composition

1. Similar to aggregation

2. It is used when the lifespan of the parts depend on the lifespan of the aggregate

Satya Puvvada

Class diagram – generalizationSame as inheritance

No multiplicity shown

Links classes together where each class consists a subset of the element that is to be finally defined

Satya Puvvada

Class diagram – delegationCan be used to reduce generalization

Makes one class a part of another class using aggregation

Satya Puvvada

Sequence diagrams

1. Object lifeline

2. Message/Stimulus

3. Iteration

4. Self-reference

5. Return

6. Anonymous object

7. Object name

8. Sequence number

9. Condition

10. Basic comment

Satya Puvvada

Sequence diagrams

1. Activation: The start of the vertical rectangle, the activation bar

2. Deactivation: The end of the vertical rectangle, the activation bar

3. Timeout event: Typically signified by a full arrowhead with a small clock face or circle on the line

4. Asynchronous event: Typically signified by stick arrowhead

5. Object termination symbolized by an X

6. Synchronous message: Typically signified with a solid line and filled arrowhead

7. Return: Typically signified with a dashed line and line stick arrowhead

Satya Puvvada

Collaboration diagrams –

Satya Puvvada

Collaboration diagram - observer

Satya Puvvada

Patterns

Satya Puvvada

Singleton Pattern - Creational

The Singleton pattern ensures that a class has only one instance and provides a global point of access to it.

Examples: – There can be many printers in a system but

there should only be one printer spooler.– There should be only one instance of a

WindowManager (GrainWindowingSystem).– There should be only one instance of a

filesystem.

Satya Puvvada

Singleton Pattern How do we ensure that a class has only one

instance and that the instance is easily accessible?

A global variable makes an object accessible, but does not keep you from instantiating multiple objects.

A better solution is to make the class itself responsible for keeping track of its sole instance. The class ensures that no other instance can be created (by intercepting requests to create new objects) and it provides a way to access the instance.

Satya Puvvada

Singleton Pattern

Use the Singleton pattern when There must be exactly one instance of a

class, and it must be accessible to clients from a well-known access point.

When the sole instance should be extensible by subclassing, and clients should be able to use an extended instance without modifying their code.

Satya Puvvada

Singleton Structure

Singleton

static Instance()SingletonOperation()GetSingletonData()

static uniqueinstancesingletonData

return uniqueinstance

Satya Puvvada

Singleton Particpants

Singleton– Defines an Instance operation that lets clients

access its unique instance. Instance is a class operation (static member function in C++)

– May be responsible for creating its own unique instance

Client– Acesses a Singleton instance solely through

Singleton’s Instance operation.

Satya Puvvada

Singleton Consequences

Controlled access to sole instanceBecause the Singleton class encapsulates its sole

instance, it can have strict control over how and when clients access it.

Reduced name spaceThe Singleton pattern is an improvement over

global variables. It avoids polluting the name space with global variables that store sole instances.

Satya Puvvada

Singleton Consequences Permits refinement of operations and

representationsThe Singleton class may be subclassed and it is easy

to configure an application with an instance of this extended class at run-time.

Satya Puvvada

Singleton Implementation Ensuring a unique instance

The Singleton pattern makes the sole instance a normal instance of a class, but that class is written so that only one instance can ever be created. A common way to do this is to hide the operation that creates the instance behind a static class operation that guarantees that only one instance is created.

Satya Puvvada

Singleton Sample Codeclass Singleton {

public:static Singleton* Instance();

// clients access the Singleton exclusively through // the Instance() member function protected: Singleton() {} // the constructor is protected, such that a client // which tries to instantiate a Singleton object gets // a compiler error private: static Singleton* instance_;};

Satya Puvvada

Singleton Sample Code

Singleton* Singleton::instance_ = 0;// initialize static member data of class Singleton

Singleton* Singleton::Instance(){ if (instance_ == 0) // if not created yet instance_ = new Singleton; // create once return instance_;}

Satya Puvvada

Pattern Factory Method

Synopsis: Define an interface for creating an object, but let subclasses decide which class to instantiate.

Factory Method lets a class defer instantiation to subclasses

• Context: Example is that of a GUI framework. The generic Application class will have a method createDocument to create a generic document. A specific use of the framework for, say, word-processing GUI would subclass the generic Application class and override the createDocument method to generate word-processing documents.

Satya Puvvada

Pattern Factory Method

• Forces: Use the Factory Method pattern when:

– a class can’t anticipate the class of objects it must create

– a class wants its subclasses to specify the objects it creates

– the set of classes to be generated may be dynamic

Satya Puvvada

Pattern Factory Method Solution: Use a factory method to create the instances: – Product (e.g. Document) – defines the interface of

objects the factory method creates – ConcreteProduct (e.g. MyDocument) – implements

the Product interface – Creator (e.g. Application) – declares the factory

method which returns an object of type Product (possibly with a default implementation); may call the factory method to create a Produce object

– ConcreteCreator (e.g. MyApplication) – overrides the factory method to return an instance of ConcreteProduct

Satya Puvvada

Pattern Factory Method

Satya Puvvada

Pattern Factory Method

Factory method – class creational • Consequences: – It eliminates the need to bind application-

specific classes into your code. The code only deals with the Product interface and therefore can work with any user-defined ConcreteProduct classes.

– A client will have to subclass the Creator class just to create a particular ConcreteProduct instance.

Satya Puvvada

Pattern Factory Method

– Provides hooks for subclasses to provide extended versions of objects

– Connects parallel class hierarchies, e.g. Application – Document vs MyApplication – MyDocument

– The set of product classes that can be instantiated may change dynamically

Satya Puvvada

Factory Method

Applicability : Use when– a class cannot anticipate the class of objects it

must create– a class wants its subclasses to specify the

objects it creates– classes delegate responsibility to one of several

helper subclasses, and you want to localize the knowledge of which helper subclass to delegate.

Satya Puvvada

Factory method

Source code

Satya Puvvada

AbstractFactoryAbstract factory – object creational

• Synopsis: Provides a way to create instances of abstract

matched set of concrete subclasses

• Context: Consider building a GUI framework which should work with multiple windowing systems (e.g. Windows, Motif, MacOS) and should provide consistent look-and-feel.

• Forces: Use the Abstract Factory pattern when:

– a system should be independent of how its products are

created, composed and represented

– a system should be configured with one of multiple families of products

Satya Puvvada

AbstractFactory

– a family of related products is designed to be used together, and you need to enforce this constraint

– you want to provide a class library of products, and only reveal their interfaces, not their implementations

Satya Puvvada

AbstractFactory– Solution: Define an abstract factory class which has

methods to generate the different kinds of products. (For a windowing system this could generate matched buttons, scroll bars, fields).

The abstract factory is subclassed for a particular concrete set of products

– AbstractFactory – declares an interface for operations that create abstract product objects

– ConcreteFactory – implements the operations to create

concrete product objects

– AbstractProduct – declares an interface for a type of product object

– ConcreteProduct – implement the AbstractProduct interface –

Satya Puvvada

AbstractFactory

– Client – uses only the interfaces declared by AbstractFactory

and AbstractProduct classes

Satya Puvvada

AbstractFactory

Satya Puvvada

AbstractFactory

Abstract factory – object creational • Consequences: – It isolates concrete classes • clients are isolated from implementation classes • clients manipulate instances through their

abstract interfaces – It makes exchanging product families easy – It promotes consistency among products

Satya Puvvada

AbstractFactory

– Supporting new kinds of product is difficult

• the AbstractFactory interface fixes the set of products that can be created

• extending the AbstractFactory interface will involve changing all of the subclasses

– The hierarchy of products is independent of the client

Satya Puvvada

AbstractFactory

– Supporting new kinds of product is difficult

• the AbstractFactory interface fixes the set of products that can be created

• extending the AbstractFactory interface will involve changing all of the subclasses

– The hierarchy of products is independent of the client

Satya Puvvada

AbstractFactory

Source code

Satya Puvvada

Observer - Behavioral

One-to-many dependency between objects: change of one object will automatically notify observers

Satya Puvvada

Observer: Applicability

A change to one object requires changing an unknown set of others

Object should be able to notify others that may not be known at the beginning

Satya Puvvada

Observer: Structure

Satya Puvvada

Observer: Consequences

Abstract coupling between subject and observer

Support for broadcast communication Hard to maintain

Satya Puvvada

Observer: Consequences

Loose coupling in communication– Observers decide what happens

Dynamic change of communication Anonymous communication Multi-cast and broadcast communication

Satya Puvvada

Observer

Source code

Satya Puvvada

Strategy - Behavioural Consider a system that needs to break a stream of text

into lines. There are many algorithms for doing this – hardwiring a particular algorithm may be undesirable:

– clients will be more complex if they include the algorithm – different algorithms will be appropriate at different times or in different contexts

– it is difficult to add new algorithms • The solution is to define classes which encapsulate

different line-breaking algorithms – the so-called Strategy pattern

Satya Puvvada

Strategy Synopsis: Define a family of algorithms, encapsulate

each one,and make them interchangeable. Strategy lets the algorithm

vary independently from clients that use it • Context: In a document editor you may want to

vary the choice of line-breaking strategies, possibly on-the-fly

• Forces: Use the Strategy pattern when: – many related classes differ only in their behavior,

in which case the Strategy provides a way of configuring a class with one of many behaviors

Satya Puvvada

Strategy – you need different variants of an

algorithm – an algorithm uses data that clients

shouldn’t know about – Strategy avoids exposing complex,

algorithm-specific data structures – a class defines multiple alternative

behaviors

Satya Puvvada

Strategy Solution: Encapsulate the algorithm in an object:– Strategy (e.g. Compositor) – declares an interface

common to all supported algorithms. – Context uses this interface to call the algorithms

defined by a ConcreteStrategy– ConcreteStrategy (e.g. SimpleCompositor) –

implements the algorithm using the Strategy interface

– Context (e.g. Composition) – is configured with a ConcreteStrategy object, and may define an interface that lets Strategy access its data.

Satya Puvvada

Strategy

Satya Puvvada

Strategy Consequences: The Strategy pattern has the following

benefits and drawbacks: – families of related algorithms can be defined using a

class hierarchy, thus allowing common functionality of the algorithms to be factored out

– an alternative to subclassing for providing a variety of algorithms or behaviours. Subclassing for modifying behaviour hard-wires the behaviour into Context. Further, subclassing does not support dynamic modification of the algorithm

– Strategies can eliminate conditional statements used to select the particular algorithm

Satya Puvvada

Strategy – Strategies provide a choice of

implementations, depending for example, on different time and space tradeoffs

Satya Puvvada

Adapter Pattern - Structural

Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.

Satya Puvvada

The Adapter (Wrapper) Pattern Context: you are building an inheritance hierarchy

and want to incorporate it into an existing class The reused class is also often already part of its

own inheritance hierarchy Problem: how to obtain the power of

polymorphism when reusing a class whose methods have the same function, but NOT the same signature as the other methods in the hierarchy?

Forces: you do not have access to multiple inheritance or you do not want to use it

Satya Puvvada

More on Adapter

In fact, there are two variants of the adapter pattern:

Class adapter, which uses multiple inheritance to adapt one interface to another

Object adapter, which uses single inheritance and delegation

Satya Puvvada

Adapter pattern

Delegation used to bind an Adapter and an Adaptee

Interface inheritance used to specify the interface of the Adapter class

ClientTarget

Request()

Adaptee

ExistingRequest()

Adapter

Request()

adaptee

Satya Puvvada

Adapter Example

Satya Puvvada

Adapter Structure

Satya Puvvada

Code sample - Inheritance

class OldSquarePeg {

public:

void squarePegOperation()

{ do something }

}

class RoundPeg {

public:

void virtual roundPegOperation = 0;

}

Satya Puvvada

Code sample

class PegAdapter: private OldSquarePeg,

public RoundPeg {

public:

void virtual roundPegOperation() {

add some corners;

squarePegOperation();

}

}

Satya Puvvada

Code sample

void clientMethod() {

RoundPeg* aPeg = new PegAdapter();

aPeg->roundPegOperation();

}

Satya Puvvada

Code sample - Composition

class OldSquarePeg {

public:

void squarePegOperation() { do something }

}

class RoundPeg {

public:

void virtual roundPegOperation = 0;

}

Satya Puvvada

Code sample - Composition

class PegAdapter: public RoundPeg {

private:

OldSquarePeg* square;

public:

PegAdapter() { square = new OldSquarePeg; }

void virtual roundPegOperation() {

add some corners;

square->squarePegOperation();

}

}

Satya Puvvada

Visitor Pattern

Parse Trees

• If an expression has a correct syntax according to a grammar then we can make a parse tree for it.

Satya Puvvada

Visitor Pattern

Visitor pattern works for a tree data structure with many different types of nodes.

Compilers and other programs (ex: pretty printers) do lots of operations by traversing the parse tree – visiting every node.

Satya Puvvada

Visitor Pattern - Behavioural

Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.

Satya Puvvada

Visitor example

Satya Puvvada

Visitor example

Satya Puvvada

Visitor applicability

many distinct and unrelated operations need to be performed on objects in an object structure, and you want to avoid "polluting" their classes with these operations

Satya Puvvada

Visitor Structure

Satya Puvvada

Visitor Structure

Satya Puvvada

Pros and Cons

Pros• Visitor makes adding new operations easy• Visitor gathers related operations and separates

unrelated ones• Ability to visit across hierarchies• Ability to accumulate states

Cons• Adding concrete element classes is hard• slots encapsulation

Satya Puvvada

Visitor Consequences

1. Visitor makes adding new operations easy

2. A visitor gathers related operations and separates unrelated ones

3. Adding new Concrete Element classes is hard

4. Visiting across class hierarchies

5. Accumulating state.

6. sloting encapsulation

Satya Puvvada

Code sample

struct Transform; // forward declaration

struct Geometry; // forward declaration

struct Visitor {

virtual void visit_transform( Transform* ) = 0;

virtual void visit_geometry ( Geometry* ) = 0;

virtual ~Visitor() {}

};

Satya Puvvada

Code samplestruct Render : public Visitor {

virtual void visit_transform( Transform* ); // render Transform

virtual void visit_geometry ( Geometry* ); // render Geometry };

struct Optimize : public Visitor{

virtual void visit_transform( Transform* ); // optimize Transform

virtual void visit_geometry ( Geometry* ); // optimize Geometry

};

Satya Puvvada

Code sample

struct Node {

virtual void accept( Visitor* ) = 0;

virtual ~Node() {}

};

struct Transform : public Node {

virtual void accept( Visitor* v) { v->visit_transform( this); }

};

Satya Puvvada

Code sample

struct Geometry : public Node {

virtual void accept( Visitor* v) { v->visit_geometry( this); }

};

Main() {

Struct geometry *mygeom; // create geometry node

Struct Render *myrender;

Mygeom->accept(myrender);

}

Satya Puvvada