decorator design pattern (a gift wrapper)

23
Decorator Design Pattern A Gift Wrapper Sameer Singh Rathoud

Upload: sameer-rathoud

Post on 29-Nov-2014

1.972 views

Category:

Technology


1 download

DESCRIPTION

This presentation will help in understanding decorator design pattern, it’s structure and it’s implementation.

TRANSCRIPT

Page 1: Decorator design pattern (A Gift Wrapper)

Decorator Design PatternA Gift Wrapper

Sameer Singh Rathoud

Page 2: Decorator design pattern (A Gift Wrapper)

About presentation

This presentation will help in understanding decorator design pattern, it’s

structure and it’s implementation.

I have tried my best to explain the concept in very simple language.

The programming language used for implementation in this presentation is c#. But

any one from different programming background can easily understand the

implementation.

Page 3: Decorator design pattern (A Gift Wrapper)

Definition

A decorator pattern is a design pattern that allows behavior to be added to an

object dynamically. Decorators provide a flexible alternative to sub-classing for

extending functionality.

Decorator pattern is a structural design pattern.

Page 4: Decorator design pattern (A Gift Wrapper)

Problem

A car manufacturing company named “UselessCars” came newly in the market. Initially they came up

with a very basic cars with four wheels, a engine and few more basic things.

UselessCarBasic

getCost()

This is a class for our

“UselessCarBasic” with an operation

“getCost()” (will return the cost of

the car).

Page 5: Decorator design pattern (A Gift Wrapper)

Problem

As the company was not able to sell the cars. They came up with few more features in the car like

“doors” and “seats”.

UselessCarBasic

getCost()

So the “UselessCars” came up with three more classes

“UselessCarWithDoor”, “UselessCarWithseats” and

“UselessCarWithDoorAndSeats” deriving from “UselessCarBasic”.

Here each derive class has implemented operation “getCost()”Inheritance

UselessCarWithDoor

getCost()

UselessCarWithseats

getCost()

UselessCarWithDoorAndSeats

getCost()

Page 6: Decorator design pattern (A Gift Wrapper)

Problem

But later the company came up with lots of other features and “UselessCars” class structure met

with the class explosion.

UselessCarBasic

getCost()

Inheritance

UselessCarWithDoor

getCost()

UselessCarWithseats

getCost()

UselessCarWithABS

getCost()

UselessCarWith

AdjustableSeat

getCost()

UselessCarWith

FogLamp

getCost()

UselessCarWithAirBag

getCost()

UselessCarWithMusicSys

getCost()

UselessCarWithDoorAndSeats

getCost()

Page 7: Decorator design pattern (A Gift Wrapper)

Problem

To solve this class explosion problem the “UselessCar” has changed there structure to a single class

and added operations to add the cost of each features.

UselessCarBasic

AddDoors()

AddSeats()

AddABS()

AddLeatherSeatCovers()

AddLeatherDashBoard()

AddMusicSystem()

AddAirBags()

....

getCost()

Although this is a workable solution. But this class structure is

violating the OO design principle “open/close principle” (open

for extension and close for modification). In this class

structure, every time a new feature is getting launched

“UselessCarBasic” class will get changed (adding a function in

class for adding cost). So we need to look for a better solution

to this problem.

Page 8: Decorator design pattern (A Gift Wrapper)

Solution

Inheritance

<< interface >>

UselessCar

GetCost()

UselessCarBasic

Inheritance

UselessCar

GetCost()

<< interface >>

UselessCarDecorator

GetCost()

UselessCarWithDoors

GetCost()

UselessCarWithDoors

GetCost()

UselessCarWithABS

GetCost()

UselessCarWithFogLamps

GetCost()

....

GetCost()

In this approach we have created an

interface “UselessCar” which is having

an operation “GetCost()” and created a

class “UselessCarBasic” which is

implementing “UselessCar” and defining

operation “GetCost()”. Here we have

introduced one more interface

“UselessCarDecorator” which is holding a

reference of “UselessCar” and all the

features of “UselessCar” will be

implementing this interface and

providing the definition of operation

GetCost() by adding the cost of the

feature in the cost of “UselessCarBasic”.

Page 9: Decorator design pattern (A Gift Wrapper)

Motivation and Intent

• The intent of this pattern is to add additional responsibilities dynamically to an

object.

Add addition functionality or state to an individual objects at run-time. Inheritance

is not feasible because it is static and applies to an entire class.

Page 10: Decorator design pattern (A Gift Wrapper)

Structure

Client

Inheritance

<< interface >>

Component

Operation ()

Operation ()

Concrete Component

Operation ()

<< interface >>

Decorator

Concrete Decorator A

Operation ()

Concrete Decorator B

Operation ()

Inheritance

state AddedBehavior ()

Component

Page 11: Decorator design pattern (A Gift Wrapper)

Participants in structure

• Component (interface): is a interface for objects for which responsibilities can be added

dynamically.

• Concrete component: concrete implementation of component and will provide the object for

which responsibilities can be added at runtime.

• Decorator (interface): is a interface for additional functionality or state and maintains the

reference to component.

• Concrete decoratorA and Concrete decoratorB: are the classes defining the implementation to

decorator interface and provide the additional functionality.

• Client: The user of the decorator design pattern.

Page 12: Decorator design pattern (A Gift Wrapper)

Collaborations

• Created a Component and run the Operation() on that. Added a behavior/functionality/state with

concrete component and run the operation on the decorated object, now the behavior will get

changed.

Client Concrete Component Concrete Decorator

new Concrete Component ()

ComponentObject.Operation()

new Concrete Decorator (ComponentObject)

ConcreteDecoratorObject.Operation()

Page 13: Decorator design pattern (A Gift Wrapper)

Implementation (C#)

Component (Interface)

public abstract class UselessCar

{

public abstract int Cost { get; }

}

Here “UselessCar” is an abstract class with

an abstract property “Cost”. Now all the

concrete classes implementing this abstractclass will override “Cost” method.

<< interface >>

UselessCar

+ Cost ()

Page 14: Decorator design pattern (A Gift Wrapper)

Implementation (C#)Concrete Component

class UselessCarBasic: UselessCar

{

public override int Cost

{

get

{

return 1000; //Basic Car Cost

}

}

}

Here a concrete class “UselessCarBasic” is

implementing abstract class “UselessCar”

and these concrete classes is overridingproperty “Cost” (giving the cost of

“UselessCarBasic”) of “UselessCar”

class.

<< interface >>

UselessCar

+ Cost ()

UselessCarBasic

Cost()

Page 15: Decorator design pattern (A Gift Wrapper)

Implementation (C#)Decorator (interface)

public abstract class UselessCarDecorator : UselessCar

{

public UselessCar uselessCarObj;

public override int Cost

{

get

{

return this.uselessCarObj.Cost;

}

}

public UselessCarDecorator(UselessCar uselessCar)

{

this.uselessCarObj = uselessCar;

}

}

Here an abstract class “UselessCarDecorator”

is implementing abstract class “UselessCar” and

these concrete classes is overriding property“Cost” of “UselessCar” class and additionally

it is holding a reference of “UselessCar”.

<< interface >>

UselessCar

+ Cost ()

UselessCarBasic

+ Cost()

UselessCarDecorator

+ Cost()

+ UselessCar

Page 16: Decorator design pattern (A Gift Wrapper)

Implementation (C#)Concrete Decorator

class UselessCarWithDoors: UselessCarDecorator {

public UselessCarWithDoors(UselessCar uselessCar)

: base(uselessCar) {

}

public override int Cost {

get {

return uselessCarObj.Cost + 200; //Basic Car Cost + Doors cost

}

}

}

“UselessCarWithDoors”

is a concrete class

implementing abstract class“UselessCarDecorator”

and overriding property“Cost” of

“UselessCarDecorator”

and it is defining a constructor

expecting a parameter of type“UselessCar” this

parameter is further passed to

the constructor of base class(“UselesscarDecorator”).

Page 17: Decorator design pattern (A Gift Wrapper)

Implementation (C#)

class UselessCarWithSeats : UselessCarDecorator {

public UselessCarWithSeats(UselessCar uselessCar)

: base(uselessCar) {

}

public override int Cost {

get {

return uselessCarObj.Cost + 150; //Basic Car Cost + Seats cost

}

}

}

Here is an another class“UselessCarWithSeats”

implementing“UselessCarDecorator”

and overriding property“Cost” and it is also defining

a constructor expecting a

parameter of type“UselessCar” this

parameter is further passed to

the constructor of base class(“UselesscarDecorator”).

Concrete Decorator

Page 18: Decorator design pattern (A Gift Wrapper)

Implementation (C#)

class UselessCarWithABS : UselessCarDecorator {

public UselessCarWithABS(UselessCar uselessCar)

: base(uselessCar) {

}

public override int Cost {

get {

return uselessCarObj.Cost + 800; //Basic Car Cost + ABS cost

}

}

}

This is one more class“UselessCarWithABS”

implementing“UselessCarDecorator”

and overriding property “Cost”

and it is also defining a

constructor expecting a

parameter of type“UselessCar” this parameter

is further passed to the

constructor of base class(“UselesscarDecorator”).

Concrete Decorator

Page 19: Decorator design pattern (A Gift Wrapper)

Implementation (C#)Client

class Client {

static void Main(string[] args) {

UselessCar uselessCar = new UselessCarBasic();

System.Console.WriteLine(uselessCar.Cost);

UselessCarWithDoors uselessCarWithDoors = new UselessCarWithDoors(uselessCar);

System.Console.WriteLine(uselessCarWithDoors.Cost);

UselessCarWithSeats uselessWithCarDoorsandSeats = new UselessCarWithSeats(uselessCarWithDoors);

System.Console.WriteLine(uselessWithCarDoorsandSeats.Cost);

UselessCarWithABS uselessCarWithABS = new UselessCarWithABS(uselessCar);

System.Console.WriteLine(uselessCarWithABS.Cost);

}

}

For using decorator design pattern the client will create an instance of “UselessCarBasic” and

can add as many features as he wants to by creating the object of features by passing the referenceof “UselessCar” and can perform operation “Cost” on those feature objects.

Page 20: Decorator design pattern (A Gift Wrapper)

Implementation (C#)Class Structure << interface >>

UselessCar

+ Cost ()

UselessCarBasic

+ Cost()

UselessCarDecorator

+ Cost()

+ UselessCar

UselessCarWithABS

+ Cost()

UselessCarWithDoors

+ Cost()

UselessCarWithSeats

+ Cost()

Inheritance

Inheritance

Client

Page 21: Decorator design pattern (A Gift Wrapper)

Example and applicability

GUI framework: GUI framework can use decorator pattern for extending the functionality

dynamically.

Whenever a programmer is having a requirement where he/she has to extend the functionality at

runtime on the top of some basic functionality can opt for decorator design pattern.

Page 22: Decorator design pattern (A Gift Wrapper)

References

1. Design Patterns: Elements of Reusable Object-Oriented Software

• by Ralph Johnson, John Vlissides, Richard Helm, and Erich Gamma

2. Head First Design Patterns

• Kathy Sierra, Eric Freeman, Elisabeth Freeman, Bert Bates

Page 23: Decorator design pattern (A Gift Wrapper)

End of Presentation . . .