GoF Design Patterns

advertisement
SOEN 6011
Software Engineering Processes
Section SS Fall 2007
Dr Greg Butler
http://www.cs.concordia.ca/~gregb/home/soen6011-f2007.html
Week 9
• Design patterns
Gang Of Four
• Gamma, Helm, Johnson, Vlissides
• Some patterns in Larman, Chap. 23,…
• All patterns in XDE
– As documentation.
– As dynamic templates.
Overview of Patterns
•Present solutions
to common
software problems
arising within a
certain context
•Help resolve
key software
design
forces
•Capture recurring structures &
dynamics among software
participants to facilitate reuse of
successful designs
•Generally codify expert
knowledge of design strategies,
constraints & “best practices”
AbstractService
service
Client
Proxy
service
Service
1
1
service
The Proxy Pattern
•Flexibility
•Extensibility
•Dependability
•Predictability
•Scalability
•Efficiency
Design – Repeat Successes
• Has a (successful) similar product been
built?
• Yes, then reuse domain specific:
– Architectural
• Style (e.g. client/server, database, process control)
• Patterns.
– Design Patterns (& idioms).
• Use Domain model as source of
inspiration.
Design – New Application Area?
• Has a (successful) similar product been
built?
• No, then choose among general:
– Architectural
• Style (e.g. client/server, database, process control)
• Patterns.
– Design Patterns (& idioms).
• Use Domain model as source of
inspiration.
GoF Pattern Classification
• Behavioral Patterns
• Creational Patterns
• Structural Patterns
GoF Pattern
Summary
&
Relationships
GoF Behavioral Patterns
• Chain of
Responsibility
• Command
• Interpreter
• Iterator
• Mediator
• Memento
•
•
•
•
•
Observer
State
Strategy
Template Method
Visitor
GoF Creational Patterns
•
•
•
•
•
Abstract Factory
Builder
Factory Method
Prototype
Singleton
GoF Structural Patterns
•
•
•
•
•
•
•
Adapter
Bridge
Composite
Decorator
Facade
Flyweight
Proxy
Command Pattern
(for Front Controller)
Problem: How to allow the same command
to be invoked by
– Menu selection
– Alt-ctrl shortcut
– Commandline text entry, etc
• How to allow (unlimited) undo/redo
• How to keep a log/audit/history of
commands invoked
• How to allow “macro” commands to be
defined
Command Pattern
(for Front Controller)
• You have commands that need to be
– executed,
– undone, or
– queued
• Command design pattern separates
– Receiver from Invoker from Commands
• All commands derive from Command and
implement do(), undo(), and redo()
• Also allows recording history, replay
Adapter
• Context / problem
How to resolve incompatible interfaces, or
provide a stable interface to similar
components with different interfaces?
• Solution:
Convert the original interface of a
component into another interface, through
an intermediate adapter object.
Adapter
• Suppose we have a tax calculation class
(or external library) but the interface is not
well suited for our application.
GoodAsGoldTaxPro
+computeTax() : double
Adapter
• Adapter provides
an interface
suited
to the application
GoodAsGoldTaxProAdapter
getTaxes( Sale ) : List of TaxLineItems
GoodAsGoldTaxPro
computeTax(…):double
Adapter
(For More than One Class)
• What if more than one class (library)
needs to be adapted?
«interface»
ITaxCalculatorAdapter
Adapter
getTaxes( Sale ) : List of TaxLineItems
TaxMasterAdapter
GoodAsGoldTaxPro
Adapter
getTaxes( Sale ) : List of TaxLineItems
getTaxes( Sale ) : List of TaxLineItems
*
*
GoodAsGoldTaxPro
+computeTax() : double
Singleton Pattern
Notice:
• Constructor is no
longer public.
• To access the
instance use
getUniqueInstance().
• All other attribute and
method declarations
of C stay the same.
«Singleton»
C
- attribute1
- attribute2_etc
- uniqueInstance : C
-C( )
+ getUniqueInstance ( )
+ methodA ( )
+ methodB_etc ( )
Facade
Facade
Factory
• Context / problem:
Who should be responsible for creating
objects when there are special
considerations, such as complex creation
logic, a desire to separate the creation
responsibilities for better cohesion, and so
forth?
• Solution:
Create a Pure Fabrication object called a
Factory.
(Abstract) Factory Example
(GoF)
Factory (in EAs)
FrontCommand
FrontControllerServlet
# processRequest ( )
- getCommand ( ) : FrontCommand
- getCommandClass ( )
+ init ( )
+ processRequest ( )
RemoveStudentCommand
+ processRequest ( )
ViewStudInfoCommand
+ processRequest ( )
Strategy
• Context / problem:
How to design for varying, but related,
algorithms or policies? How to design for
the ability to change (even dynamically)
these algorithms or policies?
• Solution:
Define each algorithm/policy/strategy in a
separate class with a common interface
Strategy
PercentDiscount
PricingStrategy
«interface»
ISalePricingStrategy
getTotal( Sale ) : Money
AbsoluteDiscount
OverThreshold
PricingStrategy
percentage : float
getTotal( s:Sale ) : Money
discount : Money
threshold : Money
getTotal( s:Sale ) : Money
{
return s.getPreDiscountTotal() * percentage
}
{
pdt := s.getPreDiscountTotal()
if ( pdt < threshold )
return pdt
else
return pdt - discount
}
How Do We Create a Strategy?
1
PricingStrategyFactory
instance : PricingStrategyFactory
getInstance() : PricingStrategyFactory
getSalePricingStrategy() : ISalePricingStrategy
getSeniorPricingStrategy() : ISalePricingStrategy
...
{
String className = System.getProperty( "salepricingstrategy.class.name" );
strategy = (ISalePricingStrategy) Class.forName( className ).newInstance();
return strategy;
}
Composite (Larman05, 26.8)
Context/problem
• How do you treat a group or composite
structure of objects the same way
(polymorphically) as a non-composite
(atomic) object?
Solution
• Define classes for composite and atomic
objects so that they implement the same
interface.
Composite: Ex. Class Diagram
Composite: Ex. Objects
Must “add” be implemented by
Line?
• In C++ add declared virtual; subclass need
not implement it.
• In Java if add is abstract, then subclasses
must implement it.
String add(Graphic g) {
throw new UnsupportedOperationException();
}
• Can you think of a better solution?
Composite: Clients point-of-view
{
...
return pricingStrategy.getTotal( this )
}
Sale
date
...
getTotal()
...
*
1
«interface»
ISalePricingStrategy
getTotal( Sale ) : Money
1..*
pricingStrategies
Composite Pricing Strategies
• Interface
• Realization
PercentageDiscount
PricingStrategy
«interface»
ISalePricingStrategy
getTotal( Sale ) : Money
AbsoluteDiscount
OverThreshold
PricingStrategy
1..*
pricingStrategies
Composite
PricingStrategy
percentage : float
getTotal( Sale ) : Money
discount : Money
threshold : Money
getTotal( Sale ) : Money
add( ISalePricingStrategy )
getTotal( Sale ) : Money
Observer Pattern
Goal: When the total of the sale
changes, refresh the display with
the new value
Sale
total
...
setTotal( newTotal )
...
Observer
• How shall we have the display be
updated?
• Why not …
have the Sale inform the display when it
changes value.
What is Wrong
With This?
update( )
Sale
total
...
setTotal( newTotal )
...
Observer Pattern
• Context / Problem:
Different kinds of subscriber objects are
interested in the state changes or events
of a publisher object, and want to react in
their own way when the publisher
generates the event. …
Observer Pattern
• Solution:
Define a “subscriber” or “listener”
interface. Subscribers implement this
interface. The publisher can dynamically
register subscribers who are interested in
an event, and notify them when an event
occurs.
• Clarification: Publisher can dynamically
process registration requests from
subscribers.
Observer Pattern (GoF book)
Observers: Illustration
Download