0% found this document useful (0 votes)
70 views

Assignment 3

Here are the key steps in Jamie's recipe using the Decorator Pattern: 1. Create a DarkRoast object to represent the basic beverage 2. Decorate the DarkRoast with a Mocha object to add mocha flavoring 3. Decorate the resulting drink with a Whip object to add whipped cream 4. Call the cost() method on the final drink object to calculate the total cost by delegating to each CondimentDecorator object The Decorator Pattern allows additional responsibilities to be added to an individual object dynamically at runtime without affecting other objects. This provides an alternative to subclassing for extending functionality. The pattern also supports recursive composition - the ability to decorate decorated objects.

Uploaded by

maira
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
70 views

Assignment 3

Here are the key steps in Jamie's recipe using the Decorator Pattern: 1. Create a DarkRoast object to represent the basic beverage 2. Decorate the DarkRoast with a Mocha object to add mocha flavoring 3. Decorate the resulting drink with a Whip object to add whipped cream 4. Call the cost() method on the final drink object to calculate the total cost by delegating to each CondimentDecorator object The Decorator Pattern allows additional responsibilities to be added to an individual object dynamically at runtime without affecting other objects. This provides an alternative to subclassing for extending functionality. The pattern also supports recursive composition - the ability to decorate decorated objects.

Uploaded by

maira
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 33

FDA149

Software Engineering

Design Patterns
Examples

Peter Bunus
Dept of Computer and Information Science
Linköping University, Sweden
[email protected]

pelab
pelab

Decorator
Pattern

TDDB84 Design Patterns Peter Bunus 2


pelab
Extending the Business

Joe, people are not coming to our


pizza places in the morning. They
need coffee in the morning. I
decided to open a coffee shop
next to each pizzeria. Could you
please implement an application
for ordering coffee?

TDDB84 Design Patterns Peter Bunus 3


pelab
The First Design of the Coffee Shop

No problem boss. I can fix this. I have


now experience with the pizza store so
this will be a piece of cake

Beverage
The cost() method is
-description abstract; subclasses need to
+getDescription() define their implementation
+cost()

HouseBlend DarkRoast Decaf Expresso

+cost() +cost() +cost() +cost()

Each subclass implements cost() the cost of the beverage

TDDB84 Design Patterns Peter Bunus 4


pelab
Class Explosion
Beverage What I’m doing wrong here?
-description
+getDescription() Which of the design principles we
+cost()
are violating here?

HouseBlend DarkRoast Decaf Expresso


????????

+cost() +cost() +cost() +cost()


????????
Mocaccino
????????
????????
+cost() ???????? ????????
????????
????????
????????
????????
???????? ????????
????????
????????
????????
????????
???????? ????????
????????
????????
???????? ???????? ????????
????????

TDDB84 Design Patterns Peter Bunus 5


pelab
The Constitution of Software Architectcts

„ Encapsulate that vary.


„ Program to an interface not to an
implementation.
„ Favor Composition over Inheritance.
„ ?????????
„ ?????????
„ ?????????
„ ?????????
„ ?????????
„ ?????????

TDDB84 Design Patterns Peter Bunus 6


pelab

Why do we need so many classes ???

We add instance variables to represent whether


or not each beverage has milk, soy, mocha and
whip...

Now we’ll implement cost() in Beverage (instead


of keeping it abstract), so that it can calculate the
costs associated with the condiments for a
particular beverage instance.

Subclasses will still override cost(), but they will


also invoke the super version so that they can
calculate the total cost of the basic beverage
plus the costs of the added condiments.

TDDB84 Design Patterns Peter Bunus 7


pelab

I’m not so sure about this. My


Excellent Joe, good job. Five experience with high management
classes. This will decrease the is not so good. They change the
complexity of our ordering requirements all the time. An the
system customers they want new things
all the time

TDDB84 Design Patterns Peter Bunus 8


pelab
What can happend?

„ New condiments will appear and will force us to


add new methods and change the cost method
each time

„ Price changes for condiments so we need to


change the cost method.

„ New beverages like iced tea. The iced tee class


will still inherit the methods like hasWhip().

„ How about double espresso.

TDDB84 Design Patterns Peter Bunus 9


pelab
Decorating Coffee

„ Inheritance doesn’t worked very well for us. What we should do?

Hi Jamie. One of my
guys have problem with
coffee classes. Could
you please help him out.
1. Take the DarkRoast object
2. Decorate it with a Mocha
object
3. Decorate it with the Whip
object
4. Call the cost() method and
relay on delegation to add to the
condiment cost.

TDDB84 Design Patterns Peter Bunus 10


pelab
Jamie’s recipe
1. Take the DarkRoast object

2. Decorate it with a Mocha object


cost() cost() cost()
Whip Mocha DarkRoast 3. Decorate it with the Whip object

4. Call the cost() method


class DarkRoast : public Beverage{
public:
DarkRoast();
double cost();
};

class Whip : public CondimentDecorator{ class Mocha : public CondimentDecorator{


Beverage *beverage; Beverage *beverage;
public: public:
Whip(Beverage *p_beverage) ; Mocha(Beverage *p_beverage) ;
string getDescription(); string getDescription();
double cost(); double cost();
}; };

TDDB84 Design Patterns Peter Bunus 11


pelab
Barista Training for Sofware Engineers
class Beverage{
Beverage acts public:
like an abstract string description;
component * Beverage();
class Beverage virtual string getDescription();
-description virtual double cost()=0;
+getDescription() };
+cost()
CondimentDecorator

1
class CondimentDecorator : public Beverage{
+getDescription()()
public:
HouseBlend Expresso CondimentDecorator(){};
virtual string getDescription()=0;
+cost() +cost() };
Milk Soy
Decaf DarkRoast -beverage : Beverage -beverage : Beverage
+cost() +cost()
+cost() +cost() +getDescription() +getDescription()

class Mocha : public CondimentDecorator{


Whip Mocha
Beverage *beverage;
-beverage : Beverage -beverage : Beverage
public:
+cost() +cost()
Mocha(Beverage
+getDescription()
*p_beverage){
+getDescription()
class DarkRoast : public Beverage{ beverage = p_beverage;
public: };
DarkRoast(); string getDescription(){
double cost(); return beverage->getDescription()+ " Whip";
}; };
double cost(){
return beverage->cost() + 0.76;
};
TDDB84 Design Patterns Peter
}; Bunus 12
pelab
Running the Coffe Shop

A Whipped Dark
Roast with double
Mocha

expresso

House void main(){


blend cout << "Testing the Coffe Shop application" << endl;

Beverage *beverage1 = new Expresso();


cout << beverage1->getDescription() << endl;
cout << "Cost: " << beverage1->cost() << endl << endl;

Beverage *beverage2 = new DarkRoast();


beverage2 = new Mocha(beverage2);
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);
cout << beverage2->getDescription() << endl;
cout << "Cost: " << beverage2->cost() << endl << endl;

Beverage *beverage3 = new HouseBlend();


cout << beverage3->getDescription() << endl;
cout << "Cost: " << beverage3->cost() << endl << endl;

TDDB84 Design Patterns Peter Bunus 13


pelab
Running the Coffe Shop

void main(){
cout << "Testing the Coffe Shop application" << endl;

Beverage *beverage1 = new Expresso();


cout << beverage1->getDescription() << endl;
cout << "Cost: " << beverage1->cost() << endl << endl;

Beverage *beverage2 = new DarkRoast();


beverage2 = new Mocha(beverage2);
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);
cout << beverage2->getDescription() << endl;
cout << "Cost: " << beverage2->cost() << endl << endl;

Beverage *beverage3 = new HouseBlend();


cout << beverage3->getDescription() << endl;
cout << "Cost: " << beverage3->cost() << endl << endl;

TDDB84 Design Patterns Peter Bunus 14


pelab
How is the Cost Computed?
.....
Beverage *beverage2 = new DarkRoast();
beverage2 = new Mocha(beverage2);
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);
cout << beverage2->getDescription() << endl;
cout << "Cost: " << beverage2->cost() << endl;
.....

cost() cost() cost() cost()


Whip Mocha Mocha DarkRoast

0.99
double Whip::cost(){
0.99+0.9+0.9 0.99+0.9 return beverage->cost() + 0.76;
}

double Mocha::cost(){
0.99+0.9+0.9 + 0.76 = 3.55 return beverage->cost() + 0.9;
}
double DarkRoast::cost(){
return 0.99;
}
TDDB84 Design Patterns Peter Bunus 15
pelab
The Decorator Pattern

Attach additional responsibilities to an object dynamically. Decorators provide


a flexible alternative to subclassing for extending functionality

TDDB84 Design Patterns Peter Bunus 16


pelab
The Constitution of Software Architectcts

„ Encapsulate that vary.


„ Program to an interface not to an
implementation.
„ Favor Composition over Inheritance.
„ Classes should be open for extension but closed for modification
„ ?????????
„ ?????????
„ ?????????
„ ?????????
„ ?????????

TDDB84 Design Patterns Peter Bunus 17


pelab
Decorating Text

TDDB84 Design Patterns Peter Bunus 18


pelab
Decorator – Non Software Example

TDDB84 Design Patterns Peter Bunus 19


pelab
The Decorator Advantages/Disadvantages

„ Provides a more flexible way to add responsibilities to a class than


by using inheritance, since it can add these responsibilities to
selected instances of the class
„ Allows to customize a class without creating subclasses high in the
inheritance hierarchy.

„ A Decorator and its enclosed component are not identical. Thus,


tests for object types will fail.
„ Decorators can lead to a system with “lots of little objects” that all
look alike to the programmer trying to maintain the code

TDDB84 Design Patterns Peter Bunus 20


pelab
What we have learned?

„ Inheritance is one form of extension, but not necessarily he best way


to achieve flexibility in our design
„ In our design we should allow behavior to extended without the
need to modify the existing code
„ Composition and delegation can often be used to add new
behaviors at runtime
„ The Decorator Pattern involves a set of decorator classes that are
used to wrap concrete components
„ Decorators change the behavior of their components by adding new
functionality before and/or after (or even in place of) method calls to
the component
„ Decorators can result in many small objects in our design, and
overuse can be complex

TDDB84 Design Patterns Peter Bunus 21


pelab

The Mediator

TDDB84 Design Patterns Peter Bunus 22


pelab
The Mediator – Non Software Example
Control Tower
Mediator

Flight 34

Flight 456

Air Force One Flight 111

„ The Mediator defines an object that controls how a set of objects interact.
„ The pilots of the planes approaching or departing the terminal area communicate with
the tower, rather than explicitly communicating with one another.
„ The constraints on who can take off or land are enforced by the tower.
„ the tower does not control the whole flight. It exists only to enforce constraints in the
terminal area.
TDDB84 Design Patterns Peter Bunus 23
pelab
The Mediator – Another Example
„ Bob lives in the HouseOfFuture where everthing is automated:
… When Bob hits the snooze button of the alarm the coffee maker starts
brewing coffee
… No coffee in weekends
… .......
onEvent(){
onEvent(){ checkCalendar();
checkCalendar(); checkAlarm();
checkSprinkler(); //do more stuff
startCoffee(); }
//do more stuff
}

onEvent(){ onEvent(){
checkDayOfTheWeek(); checkCalendar();
doShower(); checkShower();
doCoffee(); checkTemperature
doAlarm(); //do more stuff
//do more stuff }
}
TDDB84 Design Patterns Peter Bunus 24
pelab
The Mediator in Action

„ With a Mediator added to the system all the appliance objects can be
greatly simplified
… They tell the mediator when their state changes
It’s such a relief,
… They respond to requests from the Mediator not having to
figure out that
Alarm clock picky
rules

if(alarmEvent)(){
checkCalendar();
checkShower();
checkTemp();
//do more stuff
}
if(weekend){
checkWeather();
}
if(trashDay){
resetAlarm();
}

TDDB84 Design Patterns Peter Bunus 25


pelab
Mediator and MFC (Microsoft Foundation Classes)

„ The Client creates aFontDialog and invokes it.


„ The list box tells the FontDialog ( it's mediator ) that it has changed
„ The FontDialog (the mediator object) gets the selection from the list box
„ The FontDialog (the mediator object) passes the selection to the entry field edit box

TDDB84 Design Patterns Peter Bunus 26


pelab
Actors in the Mediator Pattern

«interface» «interface»
Mediator Collegue
+broadcasEvent() +handleEvent()
+changed()

ConcreteMediator
* ConcreteColleague1 ConcreteCollague2

+broadcastEvent()
+handleEvent() +handleEvent()
+changed() +changed()
* * *

for each c in theConcreteClients


c.handleEvent()
* theMediator.broadcastEvent()
*

Mediator
defines an interface for communicating with Colleague objects
ConcreteMediator
implements cooperative behavior by coordinating Colleague objects
knows and maintains its colleagues
Colleague classes (Participant)
each Colleague class knows its Mediator object (has an instance of the
mediator)
each colleague communicates with its mediator whenever it would have
otherwise communicated with another colleague
TDDB84 Design Patterns Peter Bunus 27
pelab
Yet Another Example

Robbery in
progress. I
need backup
Officer down,
officer
down!!! We
have
casualties

TDDB84 Design Patterns Peter Bunus 28


pelab
Mediator advantages and disadvantages

„ Changing the system behavior means just sub classing the mediator. Other
objects can be used as is.

„ Since the mediator and its colleagues are only tied together by a loose
coupling, both the mediator and colleague classes can be varied and
reused independent of each other.

„ Since the mediator promotes a One-to-Many relationship with its


colleagues, the whole system is easier to understand (as opposed to a
many-to-many relationship where everyone calls everyone else).

„ It helps in getting a better understanding of how the objects in that system


interact, since all the object interaction is bundled into just one class - the
mediator class.

„ Since all the interaction between the colleagues are bundled into the
mediator, it has the potential of making the mediator class very complex and
monolithically hard to maintain.

TDDB84 Design Patterns Peter Bunus 29


pelab
Issues

„ When an event occurs, colleagues must communicate that event


with the mediator. This is somewhat reminiscent of a subject
communicating a change in state with an observer.

„ One approach to implementing a mediator, therefore, is to


implement it as an observer following the observer pattern.

TDDB84 Design Patterns Peter Bunus 30


pelab
Seven Layers of Architecture
Enterprise-Architecture
Global-Architecture

System-Architecture OO Architecture

Application-Architecture Subsystem

Macro-Architecture Frameworks

Micro-Architecture Design-Patterns

Objects OO Programming

TDDB84 Design Patterns Peter Bunus 31


pelab
Antipatterns Sources

TDDB84 Design Patterns Peter Bunus 32


pelab
Congratulations: You have now completed TDDB84

TDDB84 Design Patterns Peter Bunus 33

You might also like