oo design and design patterns in c++

206
OOP Design Patterns in C++ Ganesh Samarthyam [email protected]

Upload: ganesh-samarthyam

Post on 25-Jan-2017

89 views

Category:

Software


0 download

TRANSCRIPT

Page 1: OO Design and Design Patterns in C++

OOP Design Patterns in C++

Ganesh [email protected]

Page 2: OO Design and Design Patterns in C++

“Applying design principles is the key to creating high-quality software!”

Architectural principles: Axis, symmetry, rhythm, datum, hierarchy, transformation

Page 3: OO Design and Design Patterns in C++

Why care about design quality and design principles?

Page 4: OO Design and Design Patterns in C++

Poor software quality costs more than $150 billion per year

in U.S. and greater than $500 billion per year worldwide

- Capers Jones

Page 5: OO Design and Design Patterns in C++

The city metaphor

Source: http://indiatransportportal.com/wp-content/uploads/2012/04/Traffic-congestion1.jpg

Page 6: OO Design and Design Patterns in C++

The city metaphor

“Cities grow, cities evolve, cities have parts that simply die while other

parts flourish; each city has to be renewed in order to meet the needs of its populace… Software-intensive systems

are like that. They grow, they evolve, sometimes they wither away, and

sometimes they flourish…”

Grady Booch in the foreword for “Refactoring for Software Design Smells: Managing Technical Debt”, Girish Suryanarayana, Ganesh Samarthyam, Tushar Sharma, Morgan Kaufmann/Elsevier, 2014.

Page 7: OO Design and Design Patterns in C++
Page 8: OO Design and Design Patterns in C++

Modularisation in Java 9

Modularize JDK & JRE

Hide platform internal details such as sun.misc

Provide a module system for Java developers

Reference: http://paulbakker.io/java/java-9-modularity/

Page 9: OO Design and Design Patterns in C++

Example of beautiful design

int arr[] = {1, 4, 9, 16, 25}; // some values // find the first occurrence of 9 in the array int * arr_pos = find(arr, arr + 4, 9); std::cout<< “array pos = “<< arr_pos - arr << endl;

vector<int> int_vec; for(int i = 1; i <= 5; i++) int_vec.push_back(i*i); vector<int>::iterator vec_pos = find (int_vec.begin(), int_vec.end(), 9); std::cout<< “vector pos = “<< (vec_pos - int_vec.begin());

Page 10: OO Design and Design Patterns in C++

For architects: design is the key!

Page 11: OO Design and Design Patterns in C++

What do we mean by “principles”?

“Design principles are key notions considered fundamental to many different software design

approaches and concepts.” - SWEBOK v3 (2014)

Page 12: OO Design and Design Patterns in C++

"The critical design tool for software development is a mind well educated in design principles"

- Craig Larman

Page 13: OO Design and Design Patterns in C++

Fundamental Design Principles

Page 14: OO Design and Design Patterns in C++

Robert C. Martin

Formulated many principles and described many other important principles

Page 15: OO Design and Design Patterns in C++

Michael Feathers

Michael Feathers coined the acronym SOLID in 2000s to remember first five of the numerous principles by Robert C. Martin

Page 16: OO Design and Design Patterns in C++

SOLID principles

S Single Responsibility Principle

Every object should have a single responsibility and that should be encapsulated by the class

O Open Closed Principle Software should be open for extension, but closed for modification

L Liskov’s Substitution Principle

Any subclass should always be usable instead of its parent class

I Interface Segregation Principle

Many client specific interfaces are better than one general purpose interface

D Dependency Inversion Principle

Abstractions should not depend upon details. Details should depend upon abstractions

Page 17: OO Design and Design Patterns in C++

3 principles behind patterns

Design'principles'behind'pa0erns'

Program'to'an'interface,'not'to'an'implementa7on''

Favor'object'composi7on''

over'inheritance'

Encapsulate'what'varies'

Page 18: OO Design and Design Patterns in C++

Booch’s fundamental principles

Principles*

Abstrac/on*

Encapsula/on*

Modulariza/on*

Hierarchy*

Page 19: OO Design and Design Patterns in C++

How to apply principles in practice?

Design principles

Code

How to bridge the gap?

Page 20: OO Design and Design Patterns in C++

Why care about refactoring?

As an evolving program is continually changed, its complexity, reflecting

deteriorating structure, increases unless work is done

to maintain or reduce it - Lehman's law of Increasing Complexity

Page 21: OO Design and Design Patterns in C++

What is refactoring?Refactoring (noun): a change

made to the internal structure of software to make it easier to understand and cheaper to modify without changing its

observable behavior

Refactor (verb): to restructure software by applying a series

of refactorings without changing its observable

behavior

Page 22: OO Design and Design Patterns in C++

What are smells?“Smells'are'certain'structures'

in'the'code'that'suggest'(some4mes'they'scream'for)'the'possibility'of'refactoring.”''

Page 23: OO Design and Design Patterns in C++

Granularity of smellsArchitectural+

+Cyclic&dependencies&between&modules&Monolithic&modules&&Layering&viola9ons&(back&layer&call,&skip&layer&call,&ver9cal&layering,&etc)&

Design++God&class&Refused&bequest&&Cyclic&dependencies&between&classes&

Code+(implementa6on)+++Internal&duplica9on&(clones&within&a&class)&&Large&method&&Temporary&field&&

Page 24: OO Design and Design Patterns in C++

What are design patterns?

recurrent solutions to common design problems

Pattern Name Problem Solution Consequences

Page 25: OO Design and Design Patterns in C++

Why care about patterns?❖ Patterns capture expert

knowledge in the form of proven reusable solutions ❖ Better to reuse proven

solutions than to “re-invent” the wheel

❖ When used correctly, patterns positively influence software quality

❖ Creates maintainable, extensible, and reusable code

Page 26: OO Design and Design Patterns in C++

Design pattern catalog

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 27: OO Design and Design Patterns in C++

Design pattern catalog

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Creational Deals with controlled object creation

Factory method, for example

StructuralDeals with

composition of classes or objects

Composite, for example

Behavioral

Deals with interaction between objects/

classes and distribution of responsibility

Strategy, for example

Page 28: OO Design and Design Patterns in C++

5 minutes intro to notation

Page 29: OO Design and Design Patterns in C++

An example

Source: “Refactoring for Software Design Smells: Managing Technical Debt”, Girish Suryanarayana, Ganesh Samarthyam, Tushar Sharma, Morgan Kaufmann/Elsevier, 2014

Page 30: OO Design and Design Patterns in C++

Object Oriented Design - Best Practices

Page 31: OO Design and Design Patterns in C++

Design Practices: Even in C!

ConsiderthefollowingmethodsfromtheClibrary:

void bcopy(const void *src, void *dst, size_t n);void *memcpy(void *dst, const void *src, size_t n);

Whatistheproblemintheinterfacesofthesemethods?DoesitfollowtheprinciplesofgoodAPIdesign?

Page 32: OO Design and Design Patterns in C++

Design Practices: Even in C!

realloc-“doestoomanythings!”

Page 33: OO Design and Design Patterns in C++

Design Practices: Even in C!

strtok-“statefulmethods!”(notreentrant)

Page 34: OO Design and Design Patterns in C++

Intuitive class design?

classMyContainer {private:

int m_size;public:

voidsetLength(int size){m_size=size;}voidsetSize(int size){m_size=size;}int getLength() {returnm_size;}int getSize(){returnm_size;}//othermembers

}

Page 35: OO Design and Design Patterns in C++

Intuitive class design?

MyContainer * container = new Container; container.setSize(0); container.setLength(20); cout << “Container's size is ” << container.getSize() <<endl; cout << “Its length is “ container.getLength() <<endl;

// output: // Container's size is 20 // Its length is 20

Page 36: OO Design and Design Patterns in C++

Calling virtual methods from actorstruct base { base() { vfun(); } virtual void vfun() { cout << “Inside base::vfun\n”; } };

struct deri : base { virtual void vfun() { cout << “Inside deri::vfun\n”; } };

int main(){ deri d; }

// prints: // Inside base::vfun

Page 37: OO Design and Design Patterns in C++

Calling virtual methods from actorstruct base {

base() { base * bptr = this; bptr->bar();

// even simpler ... ((base*)(this))->bar(); } virtual void bar() =0; };

struct deri: base { void bar(){ } };

int main() { deri d;

}

// g++ output: // pure virtual method called // ABORT instruction (core dumped)

Page 38: OO Design and Design Patterns in C++

Temporary objects & NRVclass String { public: String(const char *str) : cstr(str) {} String(const String& arg) { std::cout<< “String cctor \n”; this->cstr = arg.cstr; } private: const char * cstr; }

String function(){ return String("Hello"); }

int main(){ String s = function(); }

// without NRV optimization on, this prints:

// String cctor

// with NRV optimization on, this prints:

// String cctor

// String cctor

Page 39: OO Design and Design Patterns in C++

Intuitive overloading?

Colour (int red, int green, int blue); Colour (float hue, float saturation, float brightness);

Page 40: OO Design and Design Patterns in C++

Intuitive overloading?

static Colour* createRGBColour(int red, int blue, int green); static Colour* createHSBColour(float hue, float saturation, float brightness);

Page 41: OO Design and Design Patterns in C++

Intuitive overloading?

void log(double val) { // prints the natural logarithm value of val

}

void log(String str) { // logs the string str into the log file

}

Page 42: OO Design and Design Patterns in C++

Intuitive overloading?void log(double val) {

// prints the natural logarithm value of val }

void log(String str) { // logs the string str into the log file

}

void logarithm(double val); void logger(String str); // or void log(double val); void logger(String str);

Page 43: OO Design and Design Patterns in C++

Preventing inheritance

// C++ Example class NoInherit { private: NoInherit() { // code for constructor } public: static NoInherit* createInstance() { return new NoInherit(); } };

// Creation of the object NoInherit* nip = NoInherit::createInstance();

Page 44: OO Design and Design Patterns in C++

Beware of versioning problems

class Base { // provided by a third party tool public: virtual void vfoo(){ // introduced in version 2.0 cout<< ”vfoo in Base – introduced in a new version”; } // other members

};

class Derived : public Base { // some client code public: void vfoo(){ // was available in version 1.0 cout<< ”vfoo in Deri – now becomes overridden”; } // other members

};

Page 45: OO Design and Design Patterns in C++

Follow “safe” overriding

class Base { public: virtual void call(int val = 10) { cout << “The default value is :”<< endl; } };

class Derived : public Base { public: virtual void call(int val = 20) { cout << “The default value is :”<< endl; } }; // user code: Base *b = new Derived; b->call();

// prints // The default value is: 10

Page 46: OO Design and Design Patterns in C++

Selectively introduce types// in mymath.h namespace math { class scalar { /* … */ } class vector { /* … */ } // other members } // in use.cpp // for using std::vector: #include <vector> using namespace std;

// for using the scalar class in your math namespace: #include “mymath.h” using namespace math;

int main() { vector<scalar *> v; // compiler error: vector is ambiguous // does vector refer to std::vector or math::vector? }

Page 47: OO Design and Design Patterns in C++

Selectively expose types to clients

namespace { int someMem; void somefunction(); }; // is a better way to limit names to file scope // than the following: static int someMem; static void somefunction();

Page 48: OO Design and Design Patterns in C++

Hiding?

int x, y; // global variables x and y

class Point { public: int x, y; // class members x and y Point(int x, int y); // function arguments x and y };

// Point constructor for setting values of x and y data members

// C++ Point::Point(int x, int y) { x = x; y = y; }

Page 49: OO Design and Design Patterns in C++

Beware of hiding

void foo { // outer block int x, y; { // inner block int x = 10, y = 20; // hides the outer x and y } }

Page 50: OO Design and Design Patterns in C++

Design Principles

Page 51: OO Design and Design Patterns in C++

What’s that smell?

“Large class” smell

Page 52: OO Design and Design Patterns in C++

Refactoring with “extract class”

Page 53: OO Design and Design Patterns in C++

Single Responsibility PrincipleThere should be only one

reason for a class to change

Page 54: OO Design and Design Patterns in C++

Feature envy smell

Methods(that(are(more(interested(in(the(data(of(other(classes(than(that(of(their(own(class(

Page 55: OO Design and Design Patterns in C++

Duplicated Code

Page 56: OO Design and Design Patterns in C++

CTRL-C and CTRL-V

Page 57: OO Design and Design Patterns in C++

Types of clones

• exactly(iden,cal(except'for'varia.ons'in'whitespace,'layout,'and'comments'

Type'1'

• syntac,cally(iden,cal(except'for'varia.on'in'symbol'names,'whitespace,'layout,'and'comments'

Type'2'

•  iden.cal'except'some'statements(changed,(added,(or(removed(

Type'3'

• when'the'fragments'are'seman,cally(iden,cal(but'implemented'by'syntac.c'variants'

Type'4'

Page 58: OO Design and Design Patterns in C++

How to deal with duplication?

Page 59: OO Design and Design Patterns in C++

Tools for clone detection

Simian CPD PMD

Page 60: OO Design and Design Patterns in C++

What’s that smell?

Page 61: OO Design and Design Patterns in C++

What’s that smell?

Page 62: OO Design and Design Patterns in C++

Refactoring “incomplete library classes” smell

min/max' open/close' create/destroy' get/set'

read/write' print/scan' first/last' begin/end'

start/stop' lock/unlock' show/hide' up/down'

source/target' insert/delete' first/last' push/pull'

enable/disable' acquire/release' le:/right' on/off'

Page 63: OO Design and Design Patterns in C++

Abstract factory pattern

Page 64: OO Design and Design Patterns in C++

Separating concerns in MVC

Page 65: OO Design and Design Patterns in C++

Open Closed Principle (OCP)

Bertrand Meyer

Software entities should be open for extension, but closed for modification

Page 66: OO Design and Design Patterns in C++

Variation Encapsulation Principle (VEP)

Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides

Encapsulate the concept that varies

Page 67: OO Design and Design Patterns in C++

Fundamental principle: Encapsulation

The principle of encapsulation advocates separation of concerns andinformation hiding through techniques such as hiding implementation

details of abstractions and hiding variations

Page 68: OO Design and Design Patterns in C++

Enabling techniques for encapsulation

Page 69: OO Design and Design Patterns in C++

Design principles and enabling techniques

Page 70: OO Design and Design Patterns in C++

Liskov’s Substitution Principle (LSP)

It#should#be#possible#to#replace#objects#of#supertype#with#objects#of#subtypes#without#

altering#the#desired#behavior#of#the#program#

Barbara#Liskov#

Page 71: OO Design and Design Patterns in C++

LSP violationclass Shape { public: // can throw any exceptions virtual void rotate(int angle) = 0; // other methods };

class Circle : public Shape { public: virtual void rotate(int angle) throw (CannotRotateException) { throw CannotRotateException(); } // other methods };

// client code Shape *shapePtr = new Circle(); shapePtr->rotate(10); // program aborts!

Page 72: OO Design and Design Patterns in C++

Private inheritance and LSP

class Base {};

class Derived : private Base {};

// user code

Base *b = new Derived();

// compiler error: conversion to inaccessible base class “Base”

Page 73: OO Design and Design Patterns in C++

Refused bequest smell

A"class"that"overrides"a"method"of"a"base"class"in"such"a"way"that"the"contract"of"the"base"class"is"not"

honored"by"the"derived"class"

Page 74: OO Design and Design Patterns in C++

What’s that smell?

Page 75: OO Design and Design Patterns in C++

How about this refactoring?

Page 76: OO Design and Design Patterns in C++

How about this refactoring?

Page 77: OO Design and Design Patterns in C++

Suggested refactoring

Page 78: OO Design and Design Patterns in C++

Practical considerations

Page 79: OO Design and Design Patterns in C++

What’s that smell?

Page 80: OO Design and Design Patterns in C++

Refactoring

Page 81: OO Design and Design Patterns in C++

What’s that smell?

Page 82: OO Design and Design Patterns in C++

Refactoring

Replace inheritance with delegation

Page 83: OO Design and Design Patterns in C++

Hands-on exercise

❖ Find out LSP violations in any code base

❖ Discuss how can it be fixed.

Page 84: OO Design and Design Patterns in C++

Interface Segregation Principle (ISP)

Clients should not be forced to depend upon interfaces they do not use

Page 85: OO Design and Design Patterns in C++

Dependency Inversion Principle (DIP)

A. High level modules should not depend upon low level modules. Both should depend upon abstractions.

B. Abstractions should not depend upon details. Details should depend upon abstractions.

Page 86: OO Design and Design Patterns in C++
Page 87: OO Design and Design Patterns in C++
Page 88: OO Design and Design Patterns in C++

Suggested refactoring for this smell

Page 89: OO Design and Design Patterns in C++

Suggested refactoring for this smell

Page 90: OO Design and Design Patterns in C++

Suggested refactoring for this smell

Page 91: OO Design and Design Patterns in C++

Suggested refactoring for this smell

Page 92: OO Design and Design Patterns in C++

Suggested refactoring for this smell

Page 93: OO Design and Design Patterns in C++

Suggested refactoring for this smell

Page 94: OO Design and Design Patterns in C++

Applying DIP in OO Design

Use references to interfaces/abstract classes as fields members, as argument types and return types

Do not derive from concrete classes

Use creational patterns such as factory method and abstract factory for instantiation

Do not have any references from base classes to its derived classes

Page 95: OO Design and Design Patterns in C++

3 principles behind patterns

Program to an interface, not to an implementation

Favor object composition over inheritance

Encapsulate what varies

Page 96: OO Design and Design Patterns in C++

Cover key patterns through examples

It is not about the number of patterns you know, but how well you understand “why, when, where, and how” to

apply them effectively

Page 97: OO Design and Design Patterns in C++

Singleton pattern

Page 98: OO Design and Design Patterns in C++

Scenario

enum ColorScheme { RGB, HSB, HLS, CMYK } class Color {

private float red, green, blue; // for supporting RGB scheme private float hue1, saturation1, brightness1; // for supporting HSB scheme private float hue2, lightness2, saturation2; // for supporting HLS schemepublic Color(float arg1, float arg2, float arg3, ColorScheme cs) {

switch (cs) {// initialize arg1, arg2, and arg3 based on ColorScheme value

}}

}

• Assume that you need to support different Color schemes in your software• RGB (Red, Green, Blue), HSB (Hue, Saturation, Brightness), and HLS (Hue,

Lightness, and Saturation) schemes• Overloading constructors and differentiating them using enums can become

confusing • What could be a better design?

Page 99: OO Design and Design Patterns in C++

A solution using Factory Method pattern

Color

+ GetRGBColor()+ GetHSBColor()+ GetHLSColor()

RGBColor

- red : float- green : float - blue : float

HSBColor

- hue : float- saturation : float - brightness : float

HLSColor

- hue : float- lightness : float - saturation : float

Page 100: OO Design and Design Patterns in C++

A solution using Factory Method pattern

Color

+ GetColor(ColorType)+ …

RGBColor

- red : float- green : float - blue : float

HSBColor

- hue : float- saturation : float - brightness : float

HLSColor

- hue : float- lightness : float - saturation : float

Page 101: OO Design and Design Patterns in C++

Factory method pattern: Structure

Page 102: OO Design and Design Patterns in C++

Factory method pattern: Discussion

❖ A class cannot anticipate the class of objects it must create

❖ A class wants its subclasses to specify the objects it creates

Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory method lets a class defer instantiation to subclasses.

❖ Delegate the responsibility to one of the several helper subclasses

❖ Also, localize the knowledge of which subclass is the delegate

Page 103: OO Design and Design Patterns in C++

Abstract factory pattern

Page 104: OO Design and Design Patterns in C++

Scenario

public:MyLocale (std::string language, // e.g. “en" for English

std::string script, // e.g., “Arab” for Arabic std::string country, // e.g., “us” for United States std::string variant, // e.g., “TH” for Thai std::string extensions) // e.g., “ca-buddhist” for Thai Buddhist Calendar

• Assume that you have a Locale class constructor that takes many “optional arguments”

• Constraint: Only certain variants are allowed - you need to “disallow” inappropriate combinations(e.g., invalid combination of country and variant) by throwing IllformedLocaleException.

• Overloading constructors will result in “too many constructors” • How will you design a solution for this?

Page 105: OO Design and Design Patterns in C++

Recommended solution

MyLocale aLocale = new MyLocale.Builder.setLanguage(“sr").setScript(“Latn").setRegion("RS").build();

• Create a Locale Builder that “builds” and returns an object step-by-step• Validation will be performed by the individual set methods • The build() method will return the “built” object

Page 106: OO Design and Design Patterns in C++

Builder pattern: structure

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 107: OO Design and Design Patterns in C++

Builder pattern: Discussion

❖ Creating or assembling a complex object can be tedious

Separate the construction of a complex object from its representation so that the same construction process can create different representations.

❖ Make the algorithm for creating a complex object independent of parts that make up the object and how they are assembled

❖ The construction process allows different representations for the object that is constructed

Page 108: OO Design and Design Patterns in C++

Real scenario #1Initial design

Page 109: OO Design and Design Patterns in C++

Real scenario #1

❖ How will you refactor such that:❖ A specific DES, AES, TDES,

… can be “plugged” at runtime?

❖ Reuse these algorithms in new contexts?

❖ Easily add support for new algorithms in Encryption?

Next change: smelly design

Page 110: OO Design and Design Patterns in C++

Time to refactor!Three strikes and you

refactor

Martin Fowler

Page 111: OO Design and Design Patterns in C++

Potential solution #1?Broken

hierarchy!

Page 112: OO Design and Design Patterns in C++

Potential solution #2?Algorithms not

reusable!

Page 113: OO Design and Design Patterns in C++

Potential solution #3?

Page 114: OO Design and Design Patterns in C++

Can you identify the pattern?

Page 115: OO Design and Design Patterns in C++

You’re right: Its Strategy pattern!

Page 116: OO Design and Design Patterns in C++

Strategy pattern: Discussion

❖ Useful when there is a set of related algorithms and a client object needs to be able to dynamically pick and choose an algorithm that suits its current need

Defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary

independently from clients that use it

❖ The implementation of each of the algorithms is kept in a separate class referred to as a strategy.

❖ An object that uses a Strategy object is referred to as a context object.

❖ Changing the behavior of a Context object is a matter of changing its Strategy object to the one that implements the required algorithm

Page 117: OO Design and Design Patterns in C++

Scenario

❖ Consider a Route class in an application like Google Maps

❖ For finding shortest path from source to destination, many algorithms can be used

❖ The problem is that these algorithms get embedded into Route class and cannot be reused easily (smell!)

Route

+ SetRoute(Location, Location)+ FindShortestPathJohnson(): Path + FindShortestDijkstra(): Path+ FindShortestBellmanFord(): Path

How will you refactor such thata) Support for shortest path algorithm can be added easily? b) Separate path finding logic from dealing with location information.

- Source: Location- Destination: Location

Page 118: OO Design and Design Patterns in C++

Hands-on exercise

❖ Try-out strategy pattern examples

❖ Discuss how overriding, functors (“function objects”), and lambdas can be used for implementing strategy

Page 119: OO Design and Design Patterns in C++

How about this solution?

ShortestPathAlgos

+ FindPath(): Path

JohnsonsAlgo DijkstrasAlgo

Route

+ SetRoute(Location, Location)+ ShortestPath(): Path

BellmanFordAlgo

- Source: Location- Destination: Location

Page 120: OO Design and Design Patterns in C++

Real scenario #2

Initial design

Page 121: OO Design and Design Patterns in C++

Real scenario #2How to add support for new

content types and/or algorithms?

Page 122: OO Design and Design Patterns in C++

How about this solution?

Page 123: OO Design and Design Patterns in C++

Can you identify the pattern structure?

Page 124: OO Design and Design Patterns in C++

You’re right: Its Bridge pattern structure!

Page 125: OO Design and Design Patterns in C++

More design patterns to explore

Crea%onal)

• Abstract)factory))• Builder))• Factory)method))• Prototype))• Singleton)

Structural)

• Adapter))• Bridge))• Composite))• Decorator))• Facade))• Flyweight))• Proxy)

Behavioral)

• Chain)of)responsibility))• Command))•  Interpreter))•  Iterator))• Mediator))• Memento))• Observer))• State))• Strategy))• Template)method))• Visitor)

deals with object creation

deals with composition of classes or objects

deals with interaction between objects/

classes and distribution of responsibility

Page 126: OO Design and Design Patterns in C++

Hands-on exercise

❖ Try-out bridge pattern sample source code

Page 127: OO Design and Design Patterns in C++

Scenario

Report

+ Open()+ Populate()+ Print()+ Save()

SummaryHTMLReport SummaryRichReport DetailedHTMLReport DetailedRichReport

Page 128: OO Design and Design Patterns in C++

How about this solution?

FileFormat

+ Save()

HTMLFormat RichTextFormat

Report

+ Open()+ Save(ReportType)+ …

SummaryReport DetailedReport

Page 129: OO Design and Design Patterns in C++

You’re right: Its Bridge pattern!

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 130: OO Design and Design Patterns in C++

An example of Bridge pattern

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 131: OO Design and Design Patterns in C++

Bridge pattern: Discussion

❖ An abstraction can be designed as an interface with one or more concrete implementers.

❖ When subclassing the hierarchy, it could lead to an exponential number of subclasses.

❖ And since both the interface and its implementation are closely tied together, they cannot be independently varied without affecting each other

Decouples an abstraction from its implementation so that the two can vary independently

❖ Put both the interfaces and the implementations into separate class hierarchies.

❖ The Abstraction maintains an object reference of the Implementer type.

❖ A client application can choose a desired abstraction type from the Abstraction class hierarchy.

❖ The abstraction object can then be configured with an instance of an appropriate implementer from the Implementer class hierarchy

Page 132: OO Design and Design Patterns in C++

ScenarioInitial design

TextView

+ Draw()

BorderedTextView

+ Draw()+ DrawBorder()

Page 133: OO Design and Design Patterns in C++

Scenario

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 134: OO Design and Design Patterns in C++

Supporting new requirementsRevised design with new requirements

TextView

+ Draw()

BorderedTextView

+ Draw()+ DrawBorder()

ScrollableTextView ScrollableBorderedTextView

- borderWidth

+ Draw()+ ScrollTo()

- ScrollPosition

+ Draw()+ ScrollTo()+ DrawBorder()

- ScrollPosition- borderWidth

Page 135: OO Design and Design Patterns in C++

Scenario

❖ How will you refactor such that:❖ You don't have to “multiply-

out” sub-types? (i.e., avoid “explosion of classes”)

❖ Add or remove responsibilities (e.g., scrolling) at runtime?

Next change: smelly design

Page 136: OO Design and Design Patterns in C++

How about this solution?VisualComponent

+ Draw()

TextView

+ Draw()

ScrollDecortor BorderDecorator

+ Draw()+ ScrollTo()

- ScrollPosition

+ Draw()+ DrawBorder()

- borderWidth

Decorator

+ Draw() component->Draw()

Decorator::Draw()DrawBorder()

Decorator::Draw()ScrollTo()

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 137: OO Design and Design Patterns in C++

At runtime (object diagram)

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 138: OO Design and Design Patterns in C++

Can you identify the pattern?VisualComponent

+ Draw()

TextView

+ Draw()

ScrollDecortor BorderDecorator

+ Draw()+ ScrollTo()

- ScrollPosition

+ Draw()+ DrawBorder()

- borderWidth

Decorator

+ Draw() component->Draw()

Decorator::Draw()DrawBorder()

Decorator::Draw()ScrollTo()

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 139: OO Design and Design Patterns in C++

You’re right: Its Decorator pattern!

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 140: OO Design and Design Patterns in C++

Decorator pattern: Discussion

❖ Want to add responsibilities to individual objects (not an entire class)

❖ One way is to use inheritance❖ Inflexible; static choice ❖ Hard to add and remove

responsibilities dynamically

Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality

❖ Add responsibilities through decoration

❖ in a way transparent to the clients

❖ Decorator forwards the requests to the contained component to perform additional actions ❖ Can nest recursively

❖ Can add an unlimited number of responsibilities dynamically

Page 141: OO Design and Design Patterns in C++

Hands-on exercise

❖ Try-out decorator pattern sample source code

Page 142: OO Design and Design Patterns in C++

Scenarioa) How do we treat files

and folders alike?b) How can we handle

shortcuts?

File

+ GetName()+ GetSize()+ …

- name: String- size: int- type: FileType- data: char[]- …

Folder

+ GetName()+ GetFiles()+ GetFolders()+ …

- name: String - files[]: File- folders[]: Folder

Page 143: OO Design and Design Patterns in C++

How about this solution?FileItem

+ GetName()+ GetSize()+ Add(FileItem)+ Remove(FileItem)

Folder

+ GetFiles()+ …

File

- files: FileItem

+ GetType()+ GetContents()+ …

- type: FileType- data: char[]

Shortcut

+ GetLinkedFileItem()+ …

- linkToFile: FileItem

Page 144: OO Design and Design Patterns in C++

Composite pattern

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 145: OO Design and Design Patterns in C++

Composite pattern: Discussion

❖ There are many situations where a group of components form larger components

❖ Simplistic approach: Make container component contain primitive ones ❖ Problem: Code has to treat

container and primitive components differently

Compose objects into tree structures to represent part-whole hierarchies. Composite lets client treat individual objects and compositions of objects uniformly.

❖ Perform recursive composition of components❖ Clients don’t have to

treat container and primitive components differently

Page 146: OO Design and Design Patterns in C++

Hands-on exercise

❖ Try-out bridge decorator sample source code

Page 147: OO Design and Design Patterns in C++

Decorator vs. CompositeDecorator and composite structure looks similar:

Decorator is a degenerate form of Composite!

Decorator Composite

At max. one component Can have many components

Adds responsibilities Aggregates objects

Does not make sense to have methods such as Add(),

Remove(), GetChid() etc.

Has methods such as Add(), Remove(), GetChild(), etc.

Page 148: OO Design and Design Patterns in C++

Scenario

How will you design to share the characters to save space?

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 149: OO Design and Design Patterns in C++

Flyweight as a solution

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 150: OO Design and Design Patterns in C++

Flyweight pattern: structure

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 151: OO Design and Design Patterns in C++

Flyweight pattern: Discussion

❖ When an application uses a large number of small objects, it can be expensive

❖ How to share objects at granular level without prohibitive cost?

Use sharing to support large numbers of fine-grained objects efficiently

❖ When it is possible to share objects (i.e., objects don't depend on identity)

❖ When object’s value remain the same irrespective of the contexts - they can be shared

❖ Share the commonly used objects in a pool

Page 152: OO Design and Design Patterns in C++

Scenario

Source: http://www.javaworld.com/article/2074068/learn-java/take-control-with-the-proxy-design-pattern.html

How to load objects like large images efficiently “on-

demand?”

Page 153: OO Design and Design Patterns in C++

Proxy pattern: example

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 154: OO Design and Design Patterns in C++

Proxy pattern: structure

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 155: OO Design and Design Patterns in C++

Proxy pattern: Discussion

❖ How to defect the cost of full creation and initialization until we really need it?

Provide a surrogate or placeholder for another object to control access to it.

❖ When it is possible to share objects❖ When object’s value

remain the same irrespective of the contexts - they can be shared

❖ Share the commonly used objects in a pool

Page 156: OO Design and Design Patterns in C++

Scenario

In an application similar to MS Paint, assume that a class (say ShapeArchiver) is responsible for archiving information about all the drawn shapes. Similarly, another class (say Canvas) is responsible for displaying all drawn shapes. Whenever any change in shapes takes place, you need to inform these two classes as to the changed information.

So, how you would like to implement this notification?

Page 157: OO Design and Design Patterns in C++

Observer pattern

Page 158: OO Design and Design Patterns in C++

ScenarioHow to exploit:a) common code segments? b) provide extensibility for

supporting other kinds of compressed files (e.g., rar)?

• You have code segments and steps for creating different kinds of compressed files, such as zip file and gzip files. How will you unify the common steps for compressing files and support new compression formats easily?

Page 159: OO Design and Design Patterns in C++

Refactoring to Template Method CompressTextFile

+ getFileName(String): String + writeFile(String): OutputStream + closeFile(OutputStream): void

ZipTextFile

+ getFileName(String): String + writeFile(String): OutputStream

GZIPTextFile

+ getFileName(String): String + writeFile(String): OutputStream

Page 160: OO Design and Design Patterns in C++

Template Method: Structure

Source: https://www.safaribooksonline.com/library/view/swift-2-design/9781785887611/graphics/4582_05_07.jpg

Page 161: OO Design and Design Patterns in C++

Template Method Pattern: Discussion

Define the skeleton of an algorithm in an operation, deferring somesteps to subclasses. Template Method lets subclasses redefine certain steps

of an algorithm without changing the algorithm's structure.

Page 162: OO Design and Design Patterns in C++

Template Method in CppUnit

https://github.com/hvoigt/cppunit/blob/master/src/cppunit/TestCase.cpp

Page 163: OO Design and Design Patterns in C++

ScenarioHow to separate:a) code generation logic

from node types?b) how to support different

target types?

class Plus extends Expr { private Expr left, right; public Plus(Expr arg1, Expr arg2) { left = arg1; right = arg2; } public void genCode() { left.genCode(); right.genCode(); if(t == Target.JVM) { System.out.println("iadd"); } else { // DOTNET System.out.println("add"); } }}

Page 164: OO Design and Design Patterns in C++

Group exercise - Understanding visitor pattern

Page 165: OO Design and Design Patterns in C++

A solution using Visitor patternclass Plus extends Expr { private Expr left, right; public Plus(Expr arg1, Expr arg2) { left = arg1; right = arg2; } public Expr getLeft() { return left; } public Expr getRight() { return right; } public void accept(Visitor v) { v.visit(this); }}

class DOTNETVisitor extends Visitor { public void visit(Constant arg) { System.out.println("ldarg " + arg.getVal()); } public void visit(Plus plus) { genCode(plus.getLeft()); genCode(plus.getRight()); System.out.println("add"); } public void visit(Sub sub) { genCode(sub.getLeft()); genCode(sub.getRight()); System.out.println("sub"); } public void genCode(Expr expr) { expr.accept(this); }}

Page 166: OO Design and Design Patterns in C++

Visitor pattern: structure

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 167: OO Design and Design Patterns in C++

Visitor pattern: call sequence

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 168: OO Design and Design Patterns in C++

Visitor pattern: Discussion

❖ 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

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 operations

❖ Create two class hierarchies: ❖ One for the elements

being operated on❖ One for the visitors that

define operations on the elements

Page 169: OO Design and Design Patterns in C++

Patterns discussed so far

✓ Builder pattern

✓ Factory method pattern

✓ Strategy pattern

✓ Bridge pattern

✓ Decorator pattern

✓ Observer pattern

✓ Composite pattern

✓ Flyweight pattern

✓ Proxy pattern

✓ Visitor pattern

✓ Template method pattern

✓ Interpreter pattern

Page 170: OO Design and Design Patterns in C++

Many other patterns other than GoF

template <typename T> class MyClass : public Counter<MyClass<T>> { };

Page 171: OO Design and Design Patterns in C++

Hands-on exercise

❖ Try-out CRTP sample source code

Page 172: OO Design and Design Patterns in C++

Design Patterns - A Case Study

Page 173: OO Design and Design Patterns in C++

Designing a document editor• How to maintain a document structure?

• How to support formatting?

• How to support embellishments (highlighting, marking, etc) with ease?

• Support multiple look-and-feel standards

• Support multiple windowing systems (mac, windows, motif, etc)

• How to support user operations and handle user events?

• How to support spellchecking and hyphenation?

• ….

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 174: OO Design and Design Patterns in C++

“Recursive composition”

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 175: OO Design and Design Patterns in C++

Solution using Composite pattern

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 176: OO Design and Design Patterns in C++

More “recursive composition”

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 177: OO Design and Design Patterns in C++

“Recursive composition” - class design

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 178: OO Design and Design Patterns in C++

Supporting bordering, scrolling, …

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 179: OO Design and Design Patterns in C++

Supporting multiple look-and-feel

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 180: OO Design and Design Patterns in C++

Abstract factory: Structure

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 181: OO Design and Design Patterns in C++

Supporting multiple look-and-feel

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 182: OO Design and Design Patterns in C++

Separating implementation dependencies

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 183: OO Design and Design Patterns in C++

Supporting user operations

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 184: OO Design and Design Patterns in C++

Supporting user operations

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 185: OO Design and Design Patterns in C++

Command pattern: Structure

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 186: OO Design and Design Patterns in C++

Supporting undo/redo: Command history

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 187: OO Design and Design Patterns in C++

Traversing document (e.g., spell check)

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 188: OO Design and Design Patterns in C++

Iterator pattern: Structure

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 189: OO Design and Design Patterns in C++

Iterator pattern: Another example

Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994

Page 190: OO Design and Design Patterns in C++

Patterns discussed in this case-study

✓ Composite pattern

✓ Decorator pattern

✓ Abstract factory pattern

✓ Bridge pattern

✓ Command pattern

✓ Iterator pattern

Page 191: OO Design and Design Patterns in C++

Wrap-up and key take-aways

Page 192: OO Design and Design Patterns in C++

Exercise: Create a suitable designNote:&Responsibility&of&

rendering&the&line&in&chosen&style&is&with&underlying&OS&/&

pla;orm&

Source: “Refactoring for Software Design Smells: Managing Technical Debt”, Girish Suryanarayana, Ganesh Samarthyam, Tushar Sharma, Morgan Kaufmann/Elsevier, 2014

Page 193: OO Design and Design Patterns in C++

How about this solution?

Source: “Refactoring for Software Design Smells: Managing Technical Debt”, Girish Suryanarayana, Ganesh Samarthyam, Tushar Sharma, Morgan Kaufmann/Elsevier, 2014

Page 194: OO Design and Design Patterns in C++

Suggested refactoring for this smell

Source: “Refactoring for Software Design Smells: Managing Technical Debt”, Girish Suryanarayana, Ganesh Samarthyam, Tushar Sharma, Morgan Kaufmann/Elsevier, 2014

Page 195: OO Design and Design Patterns in C++

Beware of “patterns mania”!

Page 196: OO Design and Design Patterns in C++

What are your takeaways?

Page 197: OO Design and Design Patterns in C++

Books to read

Page 198: OO Design and Design Patterns in C++
Page 199: OO Design and Design Patterns in C++
Page 200: OO Design and Design Patterns in C++
Page 201: OO Design and Design Patterns in C++
Page 202: OO Design and Design Patterns in C++
Page 203: OO Design and Design Patterns in C++

“Applying design principles is the key to creating high-quality software!”

Architectural principles: Axis, symmetry, rhythm, datum, hierarchy, transformation

Page 204: OO Design and Design Patterns in C++
Page 205: OO Design and Design Patterns in C++

Image/video credits❖ http://en.wikipedia.org/wiki/Fear_of_missing_out❖ http://lesliejanemoran.blogspot.in/2010_05_01_archive.html❖ http://javra.eu/wp-content/uploads/2013/07/angry_laptop2.jpg❖ https://www.youtube.com/watch?v=5R8XHrfJkeg❖ http://womenworld.org/image/052013/31/113745161.jpg❖ http://www.fantom-xp.com/wallpapers/33/I'm_not_sure.jpg❖ https://www.flickr.com/photos/31457017@N00/453784086 ❖ https://www.gradtouch.com/uploads/images/question3.jpg❖ http://gurujohn.files.wordpress.com/2008/06/bookcover0001.jpg ❖ http://upload.wikimedia.org/wikipedia/commons/d/d5/Martin_Fowler_-_Swipe_Conference_2012.jpg❖ http://www.codeproject.com/KB/architecture/csdespat_2/dpcs_br.gif ❖ http://upload.wikimedia.org/wikipedia/commons/thumb/2/28/Bertrand_Meyer_IMG_2481.jpg/440px-

Bertrand_Meyer_IMG_2481.jpg ❖ http://takeji-soft.up.n.seesaa.net/takeji-soft/image/GOF-OOPLSA-94-Color-75.jpg?d=a0 ❖ https://developer.apple.com/library/ios/documentation/cocoa/Conceptual/OOP_ObjC/Art/watchcalls_35.gif❖ http://www.pluspack.com/files/billeder/Newsletter/25/takeaway_bag.png ❖ http://cdn1.tnwcdn.com/wp-content/blogs.dir/1/files/2013/03/design.jpg ❖ http://img01.deviantart.net/d8ab/i/2016/092/c/2/may_the_force_be_with_you___yoda_flag_by_osflag-d9xe904.jpg