Sunteți pe pagina 1din 5

29.4.

2013
1
2012-2013 Dr. Feza BUZLUCA
http://www.faculty.itu.edu.tr/buzluca
http://www.buzluca.info
Object Oriented Modeling and Design
9.1
GoF Design Patterns (cont'd)
The Strategy Pattern (Behavioral)
Example:
Such a design problem in the example POS system is the complex pricing policy,
such as discount for the day, senior citien discounts, and so forth!
"he pricing strategy (#hich may also be called a rule, policy, or algorithm) for a
sale can vary!
$or example,
%ondays it may be &'( and "hursdays )( off all sales,
*t may be &'"+ off if the sale total is greater than ,''"+,
$or customers #ith a loyalty card there may be other discounts!
-ll these different algorithms (pricing strategies) seem to be variations of the
getTotal() responsibility (behavior) of the Sale class!
.o#ever, to add all these algorithms into getTotal() method of the Sale using if-
then-else or switch-case statements, #ill cause coupling and cohesion problems!
-ll changes in pricing strategies #ill affect the Sale!
- certain behavior of a class may change during the
lifetime (runtime) of a an ob/ect of this class!
Client
2012-2013 Dr. Feza BUZLUCA
http://www.faculty.itu.edu.tr/buzluca
http://www.buzluca.info
Object Oriented Modeling and Design
9.2
Definition: Strategy
Problem:
.o# to design for varying, but related, algorithms or policies0
.o# to design for the ability to change these algorithms or policies0
(- certain behavior of a class may change during the lifetime of a an ob/ect of
this class!)
Solution:
1efine each algorithm2policy2strategy in a separate class, #ith a common
interface!
-ccording to the strategy pattern, #e create multiple SalePricingStrategy classes,
for different discount algorithms, each #ith a polymorphic getTotal method!
"he implementation of each getTotal method #ill be different:
PercentDiscountPricingStrategy #ill discount by a percentage, and so on!
Each getTotal method ta3es the Sale ob/ect as a parameter, so that the pricing
strategy ob/ect can find the pre4discount price from the Sale, and then apply the
discounting rule!
2012-2013 Dr. Feza BUZLUCA
http://www.faculty.itu.edu.tr/buzluca
http://www.buzluca.info
Object Oriented Modeling and Design
9.3
PercentDiscount
PricingStrategy
percentage : float
getTotal( s:Sale ) : Money
{
return s.getPreDiscountTotal() * percentage
}
AbsoluteDiscount
OverThreshold
PricingStrategy
discount : Money
threshold : Money
getTotal( s:Sale ) : Money
pdt := s.getPreDiscountTotal()
if ( pdt < threshold )
return pdt - discount
}
{
return pdt
else
???
PricingStrategy
...
getTotal( s:Sale ) : Money
interface
ISalePricingStrategy
getTotal( Sale ) : Money
Sale
getTotal( ) : Money
pricingStrategy
Example:
Solution of the problem about different discount policies using the Strategy!
Reference in Java
or pointer in C++
getTotal() // in C++ {
...
pricingStrategy -> getTotal( this )
...
2012-2013 Dr. Feza BUZLUCA
http://www.faculty.itu.edu.tr/buzluca
http://www.buzluca.info
Object Oriented Modeling and Design
9.4
- strategy ob/ect is attached to a context ob/ect the ob/ect to #hich it applies
the algorithm!
*n this example, the context ob/ect is a Sale!
5hen a getTotal message is sent to a Sale, it delegates some of the #or3 to its
strategy ob/ect,
Object s of Sale is sent to
the strategy object to
establish parameter
visibility.
Now strategy can ask for
prediscount total
s : Sale
st := getSubtotal()
t := getTotal()
:SalesLineItem
lineItems[i]
loop
pdt := getPreDiscountTotal()
:PercentDiscount
PricingStrategy
ISalePricingStrategy
t := getTotal( s )
{ t = pdt * percentage }
2012-2013 Dr. Feza BUZLUCA
http://www.faculty.itu.edu.tr/buzluca
http://www.buzluca.info
Object Oriented Modeling and Design
9.5
"his is one of the principles that the Strategy pattern is based on!
*n our case study, varying parts are different discount strategies!
5e separate these varying parts from the stable part of the system and
encapsulate (group) them behind an abstract class (or interface in 6ava)!
(7emember 8Protected 9ariations8)
"he details (types) of these strategies are hidden for the user (Sale)!
"he context ob/ect (Sale) must include a reference or a pointer (:;;) to the
interface (6ava) or base class of different strategies!
So, it gets attribute visibility to its strategy and can be connected to different
strategy ob/ects in runtime!
Principle: <Find what varies and encapsulate it=
2012-2013 Dr. Feza BUZLUCA
http://www.faculty.itu.edu.tr/buzluca
http://www.buzluca.info
Object Oriented Modeling and Design
9.6
PercentDiscount
PricingStrategy
percentage : float
getTotal( Sale ) : Money
AbsoluteDiscount
OverThreshold
PricingStrategy
discount : Money
threshold : Money
getTotal( Sale ) : Money
interface
ISalePricingStrategy
getTotal( Sale ) : Money
Sale
date
...
getTotal()
...
1
*
pricingStrategy
Attribute visibility.
UML notation: Writing in the class is not
necessary
pricingStrategy: ISalePricingStrategy
getTotal() // in Java
{
...
return pricingStrategy.getTotal( this )
}
Principle&: <Find what varies and encapsulate it=
5e found varying strategies and encapsulated them!
Principle,: <Design to interface not to implementation"
5e designed the Sale according to common interface of different strategies!
29.4.2013
2
2012-2013 Dr. Feza BUZLUCA
http://www.faculty.itu.edu.tr/buzluca
http://www.buzluca.info
Object Oriented Modeling and Design
9.7
>%+ ,!? notation for interface implementation and usage.
(Same diagram as in @!A)
Sale
date
...
getTotal()
...
1
*
pricingStrategy
Uses
ISalePricingStrategy
interface
pricingStrategy: ISalePricingStrategy
ISalePricingStrategy
getTotal( Sale ) : Money
PercentDiscount
PricingStrategy
percentage : float
ISalePricingStrategy
Implements
ISalePricingStrategy
interface
AbsoluteDiscount
OverThreshold
PricingStrategy
discount : Money
threshold : Money
getTotal( Sale ) : Money
ISalePricingStrategy
2012-2013 Dr. Feza BUZLUCA
http://www.faculty.itu.edu.tr/buzluca
http://www.buzluca.info
Object Oriented Modeling and Design
9.8
Sale can get a strategy in
runtime and change its
behaviour dynaically!
Creating strategies ith a Factory:
1 PricingStrategyFactory
instance : PricingStrategyFactory
getInstance() : PricingStrategyFactory
getSalePricingStrategy() : ISalePricingStrategy
getSeniorPricingStrategy() : ISalePricingStrategy
...
:Register
makeNewSale()
:Sale
create()
1
:PricingStrategyFactory
ps :=
getSalePricingStrategy()
create( percent )
ps : PercentDiscount
PricingStrategy
ISalePricingStrategy
"he $actory pattern can be applied to create the necessary strategy ob/ect!
- PricingStrategyFactory can be responsible for creating strategies!
"he ne# factory is different than the ServicesFactory! "his supports the goal of
.igh :ohesion, each factory is focused only on creating a related family of ob/ects!
2012-2013 Dr. Feza BUZLUCA
http://www.faculty.itu.edu.tr/buzluca
http://www.buzluca.info
Object Oriented Modeling and Design
9.9
$actory and strategies:
PercentDiscount
PricingStrategy
percentage : float
getTotal( s:Sale ) : Money
AbsoluteDiscount
OverThreshold
PricingStrategy
discount : Money
threshold : Money
getTotal( s:Sale ) : Money
???
PricingStrategy
...
getTotal( s:Sale ) : Money
interface
ISalePricingStrategy
getTotal( Sale ) : Money
Sale
getTotal( ) : Money
pricingStrategy
1 PricingStrategyFactory
instance : PricingStrategyFactory
getInstance() : PricingStrategyFactory
getSalePricingStrategy() : ISalePricingStrategy
2012-2013 Dr. Feza BUZLUCA
http://www.faculty.itu.edu.tr/buzluca
http://www.buzluca.info
Object Oriented Modeling and Design
9.10
Disc!ssion: Favor composition over inheritance principle
*s it possible to solve the same problem using the *nheritance0
5e assume that #e have different Sale classes #ith different pricing policies!
PercentDiscount
Sale
percentage : float
getTotal() : Money
AbsoluteDiscount
OverThreshold
Sale
discount : Money
threshold : Money
getTotal() : Money
???
PricingStrategySale
...
getTotal() : Money
Sale
date : Date
time: Time
makeLineItem()
getBalance( ) : Money
getTotal() : Money
"ot prefera#le$
"his solution may #or3 but it has
some problems!
4 :oncerns are not separated!
4 Behavior of ob/ects can not be
changed dynamically!
Each getTotal() method calculates
the total applying a different
discount policy!
Solution #ith 8is4a8
(inheritance) 0
2012-2013 Dr. Feza BUZLUCA
http://www.faculty.itu.edu.tr/buzluca
http://www.buzluca.info
Object Oriented Modeling and Design
9.11
Disc!ssion: Fa%or composition o%er inheritance principle
&d%antages of the solution #ith composition (has4a relation):
Separation of concerns: Each class focuses on o#n tas3 (Sale B Pricing Strategy)
$lexibility: Sale can reCuest a ne# strategy from the factory at any time and
can change its behavior dynamically!
"here is a #ea3 connection (only a pointer or reference) bet#een the context
ob/ect (Sale) and strategies!
Disad%antages of the solution #ith inheritance (is4a relation):
:oncerns are not separated : 5e have only Sale classes! 1ifferent tas3s are
mixed in the same class!
*nflexibility: *f #e create a Sale ob/ect of a specific type (for example
PercentDiscountSale) #e can not change its behavior dynamically!
*f #e #ant to use another pricing strategy #e have to delete the existing ob/ect
and create a ne# one!
"here is a strong connection bet#een the base class and the derived classes!
2012-2013 Dr. Feza BUZLUCA
http://www.faculty.itu.edu.tr/buzluca
http://www.buzluca.info
Object Oriented Modeling and Design
9.12
The Composite Pattern (Structural)
Sometimes a client ob/ect may get a service from an
individual (atomic) ob/ect and sometimes it may get the
same service from a composition of ob/ects!
"he client ob/ect treats them (atomic or composition)
identically (polymorphically), and does not have to ma3e this
distinction!
Pro#lem: .o# to treat composition structure of ob/ects the same #ay
(polymorphically) as a non4composite (atomic) ob/ect0
Sol!tion: 1efine classes for composite and atomic ob/ects so that they
implement the same interface!
-dd a list in the composite class that can include atomic ob/ects!
Definition:
Client
29.4.2013
3
2012-2013 Dr. Feza BUZLUCA
http://www.faculty.itu.edu.tr/buzluca
http://www.buzluca.info
Object Oriented Modeling and Design
9.13
Graphic
+draw()
+add (Graphic)
+remove(Graphic)
Line
+draw()
Circle
+draw()
Text
+draw()
Picture
+draw()
+add (Graphic)
+remove(Graphic)
Client
currentGraphic
Atomic
Composite
foreach g in graphics
g.draw();
graphics
1..*
Example: ($rom the boo3 of the Do$)
List of atomic objects
*n this example, the class Client can get the same service (draw) from an atomic
ob/ect (Line, Circle, Text) and at the same time from a composite ob/ect (Picture)
that can include atomic ob/ects!
is-a
has-a
2012-2013 Dr. Feza BUZLUCA
http://www.faculty.itu.edu.tr/buzluca
http://www.buzluca.info
Object Oriented Modeling and Design
9.14
.o# do #e handle the case of multiple, conflicting pricing policies0
$or example, suppose a store has the follo#ing policies:
On %onday, there is &'"+ off purchases over &''"+
Preferred customer discount of &)(!
Buy the product of the day, get )( discount off of everything!
*f a preferred customer buys the product of the day and spends &)'"+ on
%onday, #hat pricing policy should be applied0
Properties of the problem:
Ob/ects of the Sale class are sometimes connected to a single pricing strategy
(atomic) and sometimes to a collection (composition) of strategies!
"he composite strategy solve this part of the problem!
"he pricing strategies are dependent on different attributes of the Sale:
1ate, total, customer type, a particular line item product !
1ifferent strategies are conflicting!
Example: ($rom +arman)
2012-2013 Dr. Feza BUZLUCA
http://www.faculty.itu.edu.tr/buzluca
http://www.buzluca.info
Object Oriented Modeling and Design
9.15
5e create a composite class CompositePricingStrategy that is derived from the
same base class (ISalePricingStrategy) as the atomic strategies!
"his composite class can also contain other ISalesPricingStrategy ob/ects!
- list in the CompositePricingStrategy class contains currently valid pricing
strategies! (:omposite pattern)
.o# to handle different conflicting strategies in the composite ob/ect is another
strategy! (Strategy pattern again)
$or example, the CompositeBestForCustomerPricingStrategy can try all strategies
in its list and apply the strategy #hich returns the lo#est total!
-nother composite strategy (not so realistic) can be
CompositeBestForStorePricingStrategy, #hich returns the highest total!
5e can attach either a composite CompositeBestForCustomerPricingStrategy
ob/ect (#hich contains other strategies inside of it) or an atomic
PercentDiscountPricingStrategy ob/ect to the Sale ob/ect!
"he Sale does not 3no# or care if its pricing strategy is an atomic or compositeE
it loo3s the same to the Sale ob/ect, because they are all derived from the same
base class ISalePricingStrategy!
Sol!tion:
2012-2013 Dr. Feza BUZLUCA
http://www.faculty.itu.edu.tr/buzluca
http://www.buzluca.info
Object Oriented Modeling and Design
9.16
CompositeBestForCustomer
PricingStrategy
getTotal( Sale ) : Money
CompositeBestForStore
PricingStrategy
getTotal( Sale ) : Money
{
lowestTotal = INTEGER.MAX
for each ISalePricingStrategy strat in pricingStrategies
{
total := strat.getTotal( sale )
lowestTotal = min( total, lowestTotal )
}
return lowestTotal
}
interface
ISalePricingStrategy
getTotal( Sale ) : Money
AbsoluteDiscount
OverThreshold
PricingStrategy
discount : Money
threshold : Money
getTotal( Sale ) : Money
PercentageDiscount
PricingStrategy
percentage : float
getTotal( Sale ) : Money
{
return sale.getPreDiscountTotal() * percentage
}
Composite
PricingStrategy
add( ISalePricingStrategy )
getTotal( Sale ) : Money
1.. *
pricingStrategies
pricingStrategies : List
List of ISalePricingStrategy
{
Sale
date
...
getTotal()
...
1 *
pricingStrategy
...
return pricingStrategy.getTotal( this )
}
Solution for multiple, conflicting pricing policies:
Atomic strategies
Composite strategies
2012-2013 Dr. Feza BUZLUCA
http://www.faculty.itu.edu.tr/buzluca
http://www.buzluca.info
Object Oriented Modeling and Design
9.17
:ollaboration #ith a :omposite:
Sale can be attached to any ob/ect that implements the ISalePricingStrategy
interface and understands the getTotal message!
*n this example, a CompositeBestForCustomerPricingStrategy ob/ect is attached to
Sale!
s : Sale
t := getTotal()
:CompositeBestForCustomer
PricingStrategy
ISalePricingStrategy
t := getTotal( s )
{ t = min(set of all x) }
st := getSubtotal()
:SalesLineItem
SalesLineItem
loop
lineItems[i]:
loop x := getTotal( s )
strategies[j]
:ISalePricingStrategy
// superclass so all subclasses can inherit a List of strategies
public abstract class CompositePricingStrategy implements ISalePricingStrategy
{
protected List pricingStrategies = new ArrayList!"
public add ISalePricingStrategy s !
{
pricingStrategies#add s !"
$
public abstract %oney getTotal Sale sale !"
$ // end of class
// a Composite Strategy that returns the lowest total of its inner SalePricingStrategies
public class Composite&est'orCustomerPricingStrategy e(tends CompositePricingStrategy
{
public %oney getTotal Sale sale !
{
%oney lowestTotal = new %oney Integer#%A)*+AL,- !"
// iterate o.er all the inner strategies
for Iterator i = pricingStrategies#iterator!" i#has/e(t!" !
{
ISalePricingStrategy strategy = ISalePricingStrategy!i#ne(t!"
%oney total = strategy#getTotal sale !"
lowestTotal = total#min lowestTotal !"
$
return lowestTotal"
$
$ // end of class
-bsrtract :omposite
+ist of atomic strategies
:oncrete :omposite
29.4.2013
4
2012-2013 Dr. Feza BUZLUCA
http://www.faculty.itu.edu.tr/buzluca
http://www.buzluca.info
Object Oriented Modeling and Design
9.19
5hen an ob/ect of the Sale is created, it can reCuest a strategy from the
factory PricingStrategyFactory!
-ccording to current conditions the factory can decide to create a composite
strategy such as the CompositeBestForCustomerPricingStrategy!
-t the beginning the factory can add the present momentFs store discount
policy (#hich could be set to '( discount if none is active), such as some
PercentageDiscountPricingStrategy to the composite ob/ect!
"hen, if at a later step in the scenario, another pricing strategy is discovered
(such as preferred customer discount), it #ill be easy to add it to the
composite, using the CompositePricingStrategy.add method!
Creating '!ltiple Sale Pricing Strategies
2012-2013 Dr. Feza BUZLUCA
http://www.faculty.itu.edu.tr/buzluca
http://www.buzluca.info
Object Oriented Modeling and Design
9.20
:Register
makeNewSale()
:Sale
create()
1
:PricingStrategyFactory
ps :=
getSale
PricingStrategy()
create( percent ) st : PercentageDiscount
PricingStrategy
ISalePricingStrategy
add( st )
ISalePricingStrategy
create()
ps :CompositeBestForCustomer
PricingStrategy
Example: Creating '!ltiple Sale Pricing Strategies
2012-2013 Dr. Feza BUZLUCA
http://www.faculty.itu.edu.tr/buzluca
http://www.buzluca.info
Object Oriented Modeling and Design
9.21
*f there are preferred customers in this system #e need to handle a ne# system
operation: enterCustomerForDiscount
*f there is a valid discount for this customer it needs to be added to the
composite strategy!
Example: Creating the pricing strategy for a preferred c!stomer disco!nt:
:Register
enterCustomerForDiscount( custID )
Controller
Customer
ID number
:Store
c := getCustomer( custID )
Customer
object
Expert:
From ID to
object
s :Sale
enterCustomerForDiscount( c : Customer ) ref
Enter Customer For
Discount
2012-2013 Dr. Feza BUZLUCA
http://www.faculty.itu.edu.tr/buzluca
http://www.buzluca.info
Object Oriented Modeling and Design
9.22
1
:PricingStrategy
Factory
s :Sale
ps :CompositeBestForCustomer
PricingStrategy
ISalePricingStrategy
Factory
High Cohesion
pct :=
getCustomer
Percentage( c )
enterCustomer
ForDiscount( c : Customer )
addCustomer
PricingStrategy( s )
c := getCustomer()
ps := getPricing
Strategy()
create( pct )
st : PercentageDiscount
PricingStrategy
ISalePricingStrategy
add( st )
Expert
Factory and Composite
Instead of
attributes
pass object
as parameter
High Cohesion
sd enter Customer For Discount
2012-2013 Dr. Feza BUZLUCA
http://www.faculty.itu.edu.tr/buzluca
http://www.buzluca.info
Object Oriented Modeling and Design
9.23
5hy do not the Register send a message to the PricingStrategyFactory, to create
this ne# pricing strategy and then pass it to the Sale0
7eason is to support Low oupling! "he Sale is already coupled to the factory!
$urthermore, the Sale is the !nformation "#pert that 3no#s its current pricing
strategy!
customerID is transformed into a Customer ob/ect by the Store !
7eason: By !nformation "#pert and the goal of low representational gap, the
Store can 3no# all the :ustomers!
"he Register as3s the Store, because the Register already has attribute
visibility to the Store (from earlier design #or3)!
5hy to transform the customerID (perhaps a number) into a Customer ob/ect0
*t doesnFt have a pattern name but this is a common practice in ob/ect design
to transform 3eys and *1s for things into true ob/ects!
.aving a true Customer ob/ect that contains information about the customer,
and #hich can have behavior becomes beneficial and flexible as the design
gro#s!
7emember: itemID into a ProductDescription ob/ect in the enterItem operation!
Considering principles and patterns in the design a#o!t c!stomer disco!nt
2012-2013 Dr. Feza BUZLUCA
http://www.faculty.itu.edu.tr/buzluca
http://www.buzluca.info
Object Oriented Modeling and Design
9.24
Passing aggregate ob/ect as parameter:
*n the addCustomerPricingStrategy(s:Sale) message #e pass a reference to the
Sale ob/ect s to the factory, and then the factory as3s for the Customer and
PricingStrategy from the Sale!
5hy not to /ust send these t#o parameters to the factory0
Principle: *nstead of individual attributes or child ob/ects, pass the aggregate
ob/ect (actually the reference) that contains child ob/ects!
7eason: $ollo#ing this principle increases flexibility, because then the factory
can collaborate #ith the entire Sale in #ays #e may not have previously
foreseen as necessary!
*n future steps of the design ne# parameters (attributes) may be necessary!
*n this case, #e donFt need to change interfaces of our methodsE the factory
can get them from Sale by calling the necessary get functions!
000000000000000
"ote: "he composite pattern is not used only #ith the strategies!
"his pattern provides that a client ob/ect treats individual ob/ects (atomic) and
group of ob/ects (composition) identically (polymorphically), and does not have
to ma3e this distinction!
Considering principles and patterns in the design (cont'd)
29.4.2013
$
2012-2013 Dr. Feza BUZLUCA
http://www.faculty.itu.edu.tr/buzluca
http://www.buzluca.info
Object Oriented Modeling and Design
9.25
Atomic
operation()
Composite
remove(Component)
operation()
1.. *
add(Component)
General Str!ct!re of the Composite Pattern:
Component
operation( )
myComponent
Client
job ()
public class Client {
pri.ate Component myComponent" // reference or pointer!
public 1ob!
{
22
myComponent#operation!" // it can be atomic or composite
$
$

S-ar putea să vă placă și