Unit -IV Objects Design

Unit IV: GoF Design Patterns
Objects Design means Object identification and their
relationships, how they interact with each other. (Blue print
of the problem, that shows objects and their relationships)
Designing Objects With Responsibilities
“Identify requirements, create a domain model and define
dynamic behaviour , define messages to meet requirements ,
add methods to the software classes …”
 Too Simple!
 How do we assign responsibilities to classes?
 What methods belong where?
6
Object Design : Input
• Use case text
– Defining the behavior
• System sequence diagram
– Identifying the system operation messages
• The operation contract
– Stating events to design for, and detailed post-condition to satisfy
• Supplementary specification
– Defines non-functional goals
• Glossary
– Data format, data related with UI and database
• Domain model
– initial attempt of software object in the domain layer of software
architecture
7
Responsability Driven Design-RDD
Design of behavior implies assigning responsibilities to software classes.
Responsibilities are assigned to classes of objects during object design.
Responsibility is a contract or obligation of a class
– What must a class “know”? [knowing responsibility]
– What must a class “do”? [doing responsibility]
8
Doing Responsability
What must a class “do”? [doing responsibility]
 Take action (create an object, do a calculation)
 Initiate action in other objects
 Control/coordinate actions in other objects
Doing responsibilities are implemented by means of methods
Methods fulfill responsibilities alone or through collaboration with other
objects and methods.
Ex: A Sale is responsible for creating SalesLineItems” (doing)
9
Responsibilities and methods : create
: Sale
makePayment(cashTendered)
create(cashTendered)
abstract, implies Sale objects have a
responsibility to create Payments
Sale objects are given a responsibility to create Payments.
The responsibility is invoked with a makePayment message
: Payment
knowing responsibility
What must a class “know”? [knowing responsibility]
Knowing responsibilities are related to attributes, associations in the
domain model.
Domain model illustrates
attributes and associations
=>
inspires the
“knowing” responsibilities.
Ex : a Sale is responsible for knowing its total” (knowing)
11
Responsibilities and attribute
getDueDate message implies
Book has responsibility for
knowing its due date.
d := getDueDate()
:Book
12
RDD and Collaboration
Responsibilities are implemented by methods. Some methods act alone and do
a task. Some collaborate with other objects to fulfill their responsibility.
Example:
Sale class has getTotal() method, the getTotal() collaborates with
SalesLineItem objects to get the subtotal through getSubtotal()
methods
13
Well‐known Pattern Families
GRASP = General Responsibility Assignment Software Patterns
Describe fundamental principles for assigning
responsibilities to classes and for designing
=>
interactions between classes
GoF: Gang of Four Design Patterns : 23 pattrens
We’ll cover with GOF
14
Definitions
• A pattern is a recurring solution to a standard
problem, in a context.
• “A pattern describes a problem which occurs over and over
again in our environment, and then describes the core of the
solution to that problem, in such a way that you can use this
solution a million times over, without ever doing it the same
way twice.”
-by Christopher Alexander,
a professor of architecture…
Software pattern
What is a software pattern?
A design pattern is a general reusable and proven solution to a
commonly occurring problem in software design.
“ a pattern is a named problem/solution pair that can be
applied in new contexts, with advice on how to apply it in
novel situations”
-by Craig Larman:
16
The “gang of four” (GoF)
•
•
•
•
Erich Gamma
Richard Helm
Ralph Johnson
John Vlissides
The “gang of four” (GoF)
– Design Patterns book catalogs 23 different
patterns as solutions to different classes of
problems, in C++ & Smalltalk
– The problems and solutions are broadly
applicable, used by many people over many years
– Patterns suggest opportunities for reuse in
analysis, design and programming
– GOF presents each pattern in a structured format
Elements of Design Patterns
• Design patterns have 4 essential elements:
– Pattern name: increases vocabulary of designers
– Problem: intent, context, when to apply
– Solution: UML-like structure, abstract code
– Consequences: results and tradeoffs
Three Types of Patterns
• Creational patterns (5):
– Deal with initializing and configuring classes and objects
• Structural patterns (7):
– Deal with decoupling interface and implementation of classes
and objects
– Composition of classes or objects
• Behavioral patterns (11):
– Deal with dynamic interactions among societies of classes and
objects
– How they distribute responsibility
Creational Patterns
• Abstract Factory:
– Factory for building related objects
• Builder:
– Factory for building complex objects incrementally
• Factory Method:
– Method in a derived class creates associates
• Prototype:
– Factory for cloning new instances from a prototype
• Singleton:
– Factory for a singular (sole) instance
Structural Patterns
• Adapter:
– Translator adapts a server interface for a client
• Bridge:
– Abstraction for binding one of many implementations
• Composite:
– Structure for building recursive aggregations
• Decorator:
– Decorator extends an object transparently
• Facade:
– Simplifies the interface for a subsystem
• Flyweight:
– Many fine-grained objects shared efficiently.
• Proxy:
– One object approximates another
Behavioral Patterns
• Chain of Responsibility:
– Request delegated to the responsible service provider
• Command:
– Request or Action is first-class object, hence re-storable
• Iterator:
– Aggregate and access elements sequentially
• Interpreter:
– Language interpreter for a small grammar
• Mediator:
– Coordinates interactions between its associates
• Memento:
– Snapshot captures and restores object states privately
Behavioral Patterns (cont.)
• Observer:
– Dependents update automatically when subject changes
• State:
– Object whose behavior depends on its state
• Strategy:
– Abstraction for selecting one of many algorithms
• Template Method:
– Algorithm with some steps supplied by a derived class
• Visitor:
– Operations applied to elements of a heterogeneous object
structure
GoF Design Patterns
If you aren't an experienced object-oriented
designer, then start with the simplest and most
common patterns:
–
–
–
–
–
–
–
–
Adapter (Structural pattern)
Factory(Creational pattern)
Singleton(Creational pattern)
Strategy(Behavioral pattern)
Composite(Structural pattern)
Façade(Structural pattern)
Observer (Behavioral pattern)
Command (Behavioral pattern)
Describing Design Patterns
• Pattern Name and Classification
• Intent
– A short statement that answers the following
questions:
• What does the design pattern do?
• What is its rationale and intent?
• What particular design issue or problem does it
address?
• Also Known As
– Other well-known names for the pattern, if any.
• Motivation
– A scenario that illustrates a design problem and how
the class and object structures in the pattern solve the
problem. The scenario will help you understand the
more abstract description of the pattern that follows.
• Applicability
– What are the situations in which the design pattern
can be applied?
– What are examples of poor designs that the pattern
can address? How can you recognize these situations
• Structure
– A graphical representation of the classes in the
pattern using a notation based on the Object
Modeling Technique (OMT) [RBP+91]. We also use
interaction diagrams [JCJO92, Boo94] to illustrate
sequences of requests and collaborations
between objects.
• Participants
– The classes and/or objects participating in the
design pattern and their responsibilities.
• Consequences
– How does the pattern support its objectives?
What are the trade-offs and results of using the
pattern? What aspect of system structure does it
let you vary independently?
• Implementation
– What pitfalls, hints, or techniques should you be
aware of when implementing the pattern? Are
there language-specific issues?
• Sample Code
– Code fragments that illustrate how you might
implement the pattern in C++ or Smalltalk.
• Known Uses
– Examples of the pattern found in real systems. We
include at least two examples from different domains.
• Related Patterns
– What design patterns are closely related to this one?
What are the important differences? With which
other patterns should this one be used?
Adapter Pattern (26.1)
Problem: How to resolve incompatible interfaces, or
how to 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.
Note: the Adapter pattern is an application of
Polymorphism
Adapter Pattern (26.1)
Example: POS needs to adapt several kinds of
external third-party services: tax calculators,
credit authorization services, inventory
systems, accounting systems. Each has a
different API which can’t be changed.
Fig. 26.1
Adapters use interfaces and
polymorphism to add a level of
indirection to varying APIs in other
components.
«interface»
ITaxCalculatorAdapter
getTaxes( Sale ) : List of TaxLineItems
TaxMasterAdapter
GoodAsGoldTaxPro
Adapter
getTaxes( Sale ) : List of TaxLineItems
getTaxes( Sale ) : List of TaxLineItems
«interface»
IAccountingAdapter
postReceivable( CreditPayment )
postSale( Sale )
...
«interface»
ICreditAuthorizationService
Adapter
requestApproval(CreditPayment,TerminalID, MerchantID)
...
«interface»
IInventoryAdapter
SAPAccountingAdapter
postReceivable( CreditPayment )
postSale( Sale )
...
GreatNorthernAccountingAdapter
postReceivable( CreditPayment )
postSale( Sale )
...
...
Fig. 26.2
:Register
: SAPAccountingAdapter
makePayment
...
SOAP over
HTTP
postSale( sale )
xxx
«actor»
: SAPSystem
the Adapter adapts to
interfaces in other components
Adapter Pattern (26.1)
Note: Adapter pattern follows GRASP principles:
Polymorphism, Protected Variation,
Indirection
See Fig. 26.3 for conceptual connection among
GRASP principles and Adapter pattern
Fig. 26.3
Low coupling is a way to achieve protection at a
variation point.
Protected Variation
Mechanism
GRASP
Principles
Polymorphism is a way to achieve protection at a
variation point, and a way to achieve low coupling.
An indirection is a way to achieve low coupling.
Low Coupling
Mechanism
High Cohesion
Mechanism
Indirection
Mechanism
Pure
Fabrication
The Adapter design pattern is a kind of Indirection
and a Pure Fabrication, that uses Polymorphism.
Polymorphism
Example
Adapter
GoF Design
Patterns
Factory Pattern (26.4)
Problem: Who should be responsible for
creating objects when there are special
considerations such as complex creation logic,
a desire to separate creation responsibilities
for better cohesion, etc.?
Solution: Create a Pure Fabrication object called
a Factory that handles the creation.
Factory Pattern (26.4)
• A variation of GoF Abstract Factory pattern
Fig. 26.5
ServicesFactory
accountingAdapter : IAccountingAdapter
inventoryAdapter : IInventoryAdapter
taxCalculatorAdapter : ITaxCalculatorAdapter
note that the factory methods
return objects typed to an
interface rather than a class, so
that the factory can return any
implementation of the interface
getAccountingAdapter() : IAccountingAdapter
getInventoryAdapter() : IInventoryAdapter
getTaxCalculatorAdapter() : ITaxCalculatorAdapter
...
if ( taxCalculatorAdapter == null )
{
// a reflective or data-driven approach to finding the right class: read it from an
// external property
String className = System.getProperty( "taxcalculator.class.name" );
taxCalculatorAdapter = (ITaxCalculatorAdapter) Class.forName( className ).newInstance();
}
return taxCalculatorAdapter;
Factory Pattern (26.4)
Note: In Fig. 26.5 the implementation of
ServicesFactory illustrates data-driven design –
a form of Protected Variation
Factory Pattern (26.4)
Idea: Define an object whose purpose is to
create objects
Benefits:
– Separate the responsibility of complex creation
into cohesive helper objects
– Can provide object caching (e.g. having only one
random number generator)
Singleton Pattern (26.5)
Problem: Exactly one instance of a class is
allowed. Objects need a global and single
point of access.
Solution: Define a static method of the class
that returns the singleton: getInstance()
Singleton Pattern (26.5)
Consider the factory and how it is accessed – who creates the
factory?
– Only want one instance of the factory
– Methods may need to be called from various places => how to make
single instance of the factory globally visible
Could pass the ServicesFactory instance around as a parameter
whenever visibility is required or initialize all objects that
need it with a permanent reference to it
Singleton – supports global visibility or a single access point to a
single instance
Fig. 26.6
UML notation: this '1' can optionally be used to
indicate that only one instance will be created (a
singleton)
1
ServicesFactory
UML notation: in a
class box, an
underlined attribute or
method indicates a
static (class level)
member, rather than
an instance member
instance : ServicesFactory
singleton static
attribute
accountingAdapter : IAccountingAdapter
inventoryAdapter : IInventoryAdapter
taxCalculatorAdapter : ITaxCalculatorAdapter
getInstance() : ServicesFactory
getAccountingAdapter() : IAccountingAdapter
getInventoryAdapter() : IInventoryAdapter
getTaxCalculatorAdapter() : ITaxCalculatorAdapter
...
// static method
public static synchronized ServicesFactory getInstance()
{
if ( instance == null )
instance = new ServicesFactory()
return instance
}
singleton
static
method
Singleton Pattern (26.5)
Note: concurrency control in ServicesFactory –
making getInstance() synchronized
Fig. 26.8 shows how Adapter, Factory, Singleton
patterns are used in design
Fig. 26.8
1
:Store
:ServicesFactory
create
create
:Register
accountingAdapter =
getAccountingAdapter
create
: SAPAccounting
Adapter
accountingAdapter:
SAPAccountingAdapter
:Register
makePayment
create(cashTendered)
: Payment
SOAP over
HTTP
postSale( sale )
xxx
«actor»
: SAPSystem
Singleton pattern (creational)
• Ensure that a class has only one instance and provide a global point of access
to it
– Why not use a global variable?
class Singleton
{ public:
static Singleton* getInstance();
protected: //Why are the following protected?
Singleton();
Singleton(const Singleton&);
Singleton& operator= (const Singleton&);
private: static Singleton* instance;
};
Singleton *p2 = p1->getInstance();
Strategy Pattern (26.7)
Problem: How to design for varying but related
algorithms or policies? How to design for the
ability to change these algorithms or policies?
Solution: Define each algorithm/strategy in a
separate class with a common interface
Strategy Pattern (26.7)
Example: How to provide more complex pricing
logic, e.g. store-wide discount, senior citizen
discount, employee discount, etc.
A pricing strategy for a sale can vary, how do we
design for these varying pricing algorithms?
Fig. 26.9
«interface»
ISalePricingStrategy
getTotal( Sale ) : Money
PercentDiscount
PricingStrategy
AbsoluteDiscount
OverThreshold
PricingStrategy
percentage : float
getTotal( s:Sale ) :
Money
...
discount : Money
threshold : Money
getTotal( s:Sale ) :
Money
{
return s.getPreDiscountTotal() * percentage
}
???
PricingStrategy
{
pdt := s.getPreDiscountTotal()
if ( pdt < threshold )
return pdt
else
return pdt - discount
}
...
Strategy Pattern (26.7)
Example: Create multiple SalePricingStrategy classes each with a
polymorphic getTotal() operation
Note: each getTotal() operation takes a Sale object as a
parameter so that the strategy object can find the prediscount price from the Sale
The implementation of each getTotal() will differ
A strategy object is attached to a context object – the object to
which it applies the algorithm, e.g. Sale
Fig. 26.10
s : Sale
lineItems[ i ] :
SalesLineItem
:PercentDiscount
PricingStrategy
t = getTotal
loop
{ t = pdt * percentage }
st = getSubtotal
t = getTotal( s )
pdt = getPreDiscountTotal
note that the Sale s is
passed to the Strategy so
that it has parameter
visibility to it for further
collaboration
Strategy Pattern (26.7)
Example:
– When a getTotal() message is sent to a Sale it
delegates work to its strategy object
– It is common for the context object to pass a
reference to itself to the strategy object so that
the strategy object has parameter visibility to the
context object
Fig. 26.11
Sale needs attribute
visibility to its Strategy
Sale
date
...
getTotal()
...
1
pricingStrategy
getTotal()
{
...
return pricingStrategy.getTotal( this )
percentage : float
}
getTotal( Sale ) : Money
PercentDiscount
PricingStrategy
«interface»
ISalePricingStrategy
getTotal( Sale ) : Money
AbsoluteDiscount
OverThreshold
PricingStrategy
discount : Money
threshold : Money
getTotal( Sale ) : Money
Strategy Pattern (26.7)
Example: Who should create the strategy?
– Apply the Factory pattern: a
PricingStrategyFactory
– The PricingStrategyFactory is a singleton and
accessed via the Singleton pattern
Fig. 26.12
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;
}
Fig. 26.13
1
:Register
:PricingStrategyFactory
makeNewSale
create
:Sale
ps =
getSalePricingStrategy
create(percent)
ps : PercentDiscount
PricingStrategy
Strategy Pattern (26.7)
Note:
– Strategy is based on Polymorphism and provides
Protected Variation with respect to changing
algorithms
– Strategies are often/usually created by a Factory
Composite Pattern (26.8)
Problem: How to treat a group or composition
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 Pattern (26.8)
Design problem: How to handle multiple conflicting
pricing policies?
Example:
–
–
–
–
20% senior discount
Preferred customer discount of 15% off sales over $400
On Monday, there is a $50 off purchases over $500
Buy one case of Darjeeling tea, get 15% discount off
everything
Composite Pattern (26.8)
Example (cont.): Pricing strategies determined by
– Time period (Monday)
– Customer type (senior)
– Line item product (Darjeeling tea)
In addition to pre-discount price
• May have multiple co-existing strategies
• Customer type and type of product may need to be
known at time strategy is created (i.e. known by
StrategyFactory)
Composite Pattern (26.8)
Example (cont.): Now how do we design so that
the Sale object does not know if it is dealing
with one or many pricing strategies and also
offer a design for the conflict resolution
Composite pattern!
Composite Pattern (26.8)
Key feature:
– The composite object contains a list of inner
objects and both the composite object and the
inner objects implement the same interface
Fig. 26.14
{
...
return pricingStrategy.getTotal( this )
}
All composites maintain a list of
contained strategies. Therefore,
define a common superclass
CompositePricingStrategy that
defines this list (named strategies).
Sale
date
...
1
«interface»
ISalePricingStrategy
pricingStrategy getTotal( Sale ) : Money
getTotal()
...
PercentageDiscount
PricingStrategy
AbsoluteDiscount
OverThreshold
PricingStrategy
1..*
strategies
Composite
PricingStrategy
percentage : float
getTotal( Sale ) : Money
discount : Money
threshold : Money
add( ISalePricingStrategy )
getTotal( Sale ) : Money
getTotal( Sale ) : Money
{
return sale.getPreDiscountTotal() *
percentage
}
CompositeBestForCustomer
PricingStrategy
getTotal( Sale ) : Money
{
lowestTotal = INTEGER.MAX
for each ISalePricingStrategy strat in pricingStrategies
{
total := strat.getTotal( sale )
lowestTotal = min( total, lowestTotal )
}
return lowestTotal
}
CompositeBestForStore
PricingStrategy
getTotal( Sale ) : Money
Composite Pattern (26.8)
The Sale object treats a Composite Strategy that
contains other strategies as any object that
implements ISalePricingStrategy (i.e., calls its
getTotal(s) operation)
See code pp. 455-456
Notation for abstract classes and abstract methods –
see Fig. 26.16
Fig. 26.16
UML notation: An abstract class is
shown with an italicized name
Composite
PricingStrategy
abstract methods are also shown with
italics
add( ISalePricingStrategy )
getTotal( Sale ) : Money
CompositeBestForCustomer
PricingStrategy
getTotal( Sale ) : Money
CompositeBestForStore
PricingStrategy
getTotal( Sale ) : Money
Façade Pattern (26.9)
Problem: A common unified interface to a disparate set
of implementations or interfaces – such as within a
subsystem – is required. There may be undesirable
coupling to many things in the subsystem, or the
implementation of the subsystem may change. What
to do?
Solution: Define a single point of contact to the
subsystem – a façade that wraps the subsystem. This
façade object presents a single unified interface and
is responsible for collaborating with the subsystem
components.
Façade Pattern (26.9)
A façade object serves as a “front-end” object
that is the single point of entry for the services
of a subsystem
Façade provides Protected Variation from
changes in the implementation of the
subsystem
Façade Pattern (26.9)
Example: A “rule engine” subsystem – responsible for
evaluating a set of rules against an operation and
indicating if any rules invalidate the operation
Example of a rule: If the sale is paid by a gift certificate,
invalidate all payment types of change due back to
the customer except for another gift certificate.
Also known as pluggable business rules
Façade Pattern (26.9)
Example (cont): Define a façade object to this
subsystem: POSRuleEngineFacade
Calls to this façade placed near the start of
methods that are points for pluggable rules,
see code p. 462
The hidden subsystem could contain any
number of rules
Fig. 26.20
package name may be
shown in the tab
Domain
+ Sale
+ Register
...
visibility of the package element (to
outside the package) can be shown
by preceding the element name with a
visibility symbol
POSRuleEngine
+ POSRuleEngineFacade
*
instance : RuleEngineFacade
«interface»
- IRule
...
getInstance() : RuleEngineFacade
isInvalid( SalesLineItem, Sale )
isInvalid( Payment, Sale )
...
- Rule1
...
- Rule2
...
...
Façade Pattern (26.9)
Notes:
– Façade is usually accessed via Singleton
– Similar to Adapter but Adapter applies to varying
interfaces not hiding implementation of
subsystem
Observer pattern
• Intent:
– Define a one-to-many dependency between objects
so that when one object changes state, all its dependents are
notified and updated automatically
• Used in Model-View-Controller framework
– Model is problem domain
– View is windowing system
– Controller is mouse/keyboard control
• How can Observer pattern be used in other applications?
• JDK’s Abstract Window Toolkit (listeners)
• Java’s Thread monitors, notify(), etc.
Structure of Observer Pattern
Subject
for all observers obs
{
obs->update()
}
+notify()
+attach(in Observer)
+detach(in Observer)
Observer
*
+update()
1
ConcreteObserver
ConcreteSubject
-subjectSate
+getState()
return subjectState
*
+update()
1
observerState = subject->getState()
Observer Pattern (26.10)
Also known as Publish-Subscribe Pattern
Problem: Different kinds of subscriber objects are interested in
state changes or events of a publisher object and want to
react in their own unique way when the publisher generates
an event. The publisher wants to maintain low coupling to
the subscribers.
Solution: Define a subscriber or listener interface. Subscribers
implement the interface. The publisher can dynamically
register subscribers who are interested in an event and notify
them when an event occurs.
Observer Pattern (26.10)
Example: Want a GUI window to refresh
(update) its display of sale total when the total
changes
See Fig. 26.21
Fig. 26.21
Goal: When the total of the sale
changes, refresh the display with
the new value
Sale
total
...
setTotal( newTotal )
...
Observer Pattern (26.10)
Example (cont):
Simple solution – when Sale changes its total
the object sends a message to the window
telling it to refresh its display
Problem – high coupling between domain
objects and UI objects
Observer Pattern (26.10)
Example (cont):
Want to be able to easily replace UI objects or
even add other UI objects that can be notified
of this event
That is, want model-view separation
Model objects shouldn’t know about view
objects => Protected Variations with respect
to a changing user interface
Fig. 26.22
{
{
for each PropertyListener pl in propertyListeners
pl.onPropertyEvent( this, name, value );
propertyListeners.add( lis );
}
}
Sale
addPropertyListener( PropertyListener lis )
publishPropertyEvent( name, value )
setTotal( Money newTotal )
...
{
total = newTotal;
publishPropertyEvent( "sale.total", total );
}
javax.swing.JFrame
...
setTitle()
setVisible()
...
propertyListeners
*
«interface»
PropertyListener
onPropertyEvent( source, name, value )
{
if ( name.equals("sale.total") )
saleTextField.setText( value.toString() );
}
SaleFrame1
onPropertyEvent( source, name, value )
{
initialize( Sale sale )
...
}
sale.addPropertyListener( this )
...
Observer Pattern (26.10)
Steps (p. 465)
1.
2.
3.
4.
5.
6.
Define an interface PropertyListener with operation
onPropertyEvent
Define window (SaleFrame1) to implement the interface
When SaleFrame1 is initialized pass it the Sale instance from which
it is displaying the total
SaleFrame1 registers to the Sale instance for notification of
“property events” via the addPropertyListener message
Note that the Sale does not know about SaleFrame1 objects; it only
knows about objects that implement the PropertyListener interface.
(This lowers the coupling of the Sale to the window – the coupling is
only to an interface, not to a GUI class.)
The Sale instance is the publisher of “property events”. When the
total changes, it iterates across all subscribing PropertyListeners,
notifying each
Observer Pattern (26.10)
Notes:
– The SaleFrame1 object is the
observer/subscriber/listener
– Sale is the publisher of property events
– Sale adds SaleFrame1 object to its list of
PropertyListener subscribers – Fig. 26.23
Fig. 26.23
sf : SaleFrame1
s : Sale
propertyListeners :
List<PropertyListener>
initialize( s : Sale )
addPropertyListener( sf )
add( sf )
Observer Pattern (26.10)
Notes:
– When the Sale total changes it iterates over all
registered subscribers and sends the
onPropertyEvent message to each – Figs. 26.24,
26.25
Fig. 26.24
propertylisteners[ i ] :
PropertyListener
s :Sale
setTotal( total )
publishPropertyEvent
( "sale.total", total )
loop
onPropertyEvent( s, "sale.total", total )
Fig. 26.25
Since this is a polymorphic operation implemented by
this class, show a new interaction diagram that starts
with this polymorphic version
: SaleFrame1
saleTextField
: JTextField
onPropertyEvent( source, name, value )
setText( value.toString() )
UML notation: Note this little expression within the
parameter. This is legal and consise.
Fig. 26.26
Sale
addPropertyListener( PropertyListener lis )
publishPropertyEvent( name, value )

setTotal( Money newTotal )
...

javax.swing.JFrame
propertyListeners
...
setTitle()
setVisible()
...
publishes events to
observers/listeners/
subscribers
registers them when
they ask to subscribe
*
«interface»
PropertyListener
onPropertyEvent( source, name, value )
SaleFrame1



listens for events
observes events
subscribes to notification of events
onPropertyEvent( source, name, value )
initialize( Sale sale )
...
Who is the observer, listener, subscriber, and publisher?
Observer Pattern (26.10)
Notes:
– Sale is coupled to view object but only loosely since it only
knows subscribers as implementing the PropertyListener
interface
– In Java this was called Delegation Event Model
Observer pattern is basis for GUI widget event handling
in both Java (AWT & Swing) and .NET
Widgets are publishers of events, other objects can
register as listeners
Observer Pattern (26.10)
Example of AlarmClock:
AlarmClock is publisher of alarm events
Different types of objects can register as listeners
and react to same alarm event in their own ways
Fig. 26.27
{
for each AlarmListener al in alarmListeners
al.onAlarmEvent( this, time );
{
}
alarmListeners.add( lis );
}
AlarmClock
addAlarmnListener( AlarmListener lis )
publishAlarmEvent( time )
{
setTime( newTime )
...
time = newTime;
if ( time == alarmTime )
publishAlarmEvent( time );
}
javax.swing.JFrame
...
setTitle()
setVisible()
...
alarmListeners
*
«interface»
AlarmListener
onAlarmEvent( source, time )
AlarmWindow
Beeper
ReliabilityWatchDog
onAlarmEvent( source, time )
...
onAlarmEvent( source, time )
...
onAlarmEvent( source, time )
...
{
{
{
display notification dialog
box
}
check that all required processes
are executing normally
beep
}
}
Command pattern
• Synopsis or Intent: Encapsulate a request as an object, thereby letting
you parameterize clients with different requests, queue or log requests,
and support undoable operations
• Context: You want to model the time evolution of a program:
– What needs to be done, e.g. queued requests, alarms, conditions for
action
– What is being done, e.g. which parts of a composite or distributed action
have been completed
– What has been done, e.g. a log of undoable operations
• What are some applications that need to support undo?
– Editor, calculator, database with transactions
– Perform an execute at one time, undo at a different time
• Solution: represent units of work as Command objects
– Interface of a Command object can be a simple execute() method
– Extra methods can support undo and redo
– Commands can be persistent and globally accessible, just like normal
objects
Command pattern, continued
• Structure:
Participants (the classes and/or objects participating in this pattern):
Command (Command) declares an interface for executing an operation
ConcreteCommand defines a binding between a Receiver object and an action
implements Execute by invoking the corresponding operation(s) on Receiver
Invoker asks the command to carry out the request
Receiver knows how to perform operations associated with carrying out the request
Client creates a ConcreteCommand object and sets its receiver
Command pattern, continued
• Consequences:
– You can undo/redo any Command
• Each Command stores what it needs to restore state
– You can store Commands in a stack or queue
• Command processor pattern maintains a history
– It is easy to add new Commands, because you do
not have to change existing classes
• Command is an abstract class, from which you derive
new classes
• execute(), undo() and redo() are polymorphic functions
Benefits of Design Patterns
• Design patterns enable large-scale reuse of software
architectures and also help document systems
• Patterns explicitly capture expert knowledge and design
tradeoffs and make it more widely available
• Patterns help improve developer communication
• Pattern names form a common vocabulary