APPLYING GOF DESIGN PATTERNS PART 3: Façade, Decorator and Observer
Beware of bugs in the above code;
I have only proved it correct, not tried it.
Lecturer: Philip Dart
Larman Chapter 26
—Donald Knuth
SWEN30006
Software Modelling and Design
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Objectives
On completion of this topic you should be able to:
Apply some GoF design patterns o Adapter
o Factory (not GoF) o Singleton
o Strategy
o Composite
o Façade
o Decorator o Observer
Recognise the similarities and differences among related patterns.
4
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Multiple Patterns in a Design
Use this diagram for the exercises in this lecture
6
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Problem 3: Pluggable Business Rules
Different companies who wish to purchase the NextGen POS would like to customise its behaviour slightly.
E.g. to invalidate an action: o PaidbyaGiftcard
Allow one item to be purchased -> Invalidate subsequent EnterItem operations
Invalidate request for change as cash or store a/c credit.
o Charitabledonation(bystore)sale
If cashier is not manager, CreateCharitableSale invalidated
EnterItem operation for items over $250 invalidated.
8
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Analysis
This customisation should have low impact on the existing software components
A “rule engine” subsystem, whose specific implementation is not yet known. It may be implemented with
o theStrategypattern;or
o Freeopen-sourceruleinterpreters;or o Commercialruleinterpreters;or
o Othersolutions.
9
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Façade (GoF)
Problem:
Require 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 objects in the subsystem, or the implementation of the subsystem may change. What to do?
Solution (advice):
Define a single point of contact to the subsystem—a facade object that wraps the subsystem. This facade object presents a single unified interface and is responsible for collaborating with the subsystem components.
10
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Façade: Generalised Structure
11
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
UML Package Diagram: Facade
Domain
package name may be shown in the tab
+ Sale + Register
…
visibility of the package element (to outside the package) can be shown by preceding the element name with a visibility symbol
POSRuleEngine
«interface» – IRule
…
+ POSRuleEngineFacade instance : RuleEngineFacade getInstance() : RuleEngineFacade
isInvalid( SalesLineItem, Sale ) isInvalid( Payment, Sale )
…
1
*
…
– Rule2
…
– Rule1
… 12
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Using the Facade
public class Sale {
public void makeLineItem( ProductDescription desc, int quantity ) {
SalesLineItem sli = new SalesLineItem( desc, quantity );
// call to the Facade
if ( POSRuleEngineFacade.getInstance().isInvalid( sli, this ) ) return;
lineItems.add( sli ); }
// …
} // end of class
13
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Example: ATM (w/o Façade)
14
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Example: ATM w/ Facade
15
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Example: MyATM (Main function)
BankAccountFacade accessingAccount = new BankAccountFacade(accountNumber, code);
boolean end = false; while(!end) {
switch(selectMenu()) { case Deposit:
double cashToDeposit = getMoneyAmount(); accessingAccount.depositCash(cashToDeposit); break;
case Withdraw:
double cashToGet = getMoneyAmount(); accessingAccount.withdrawCash(cashToGet); break;
case Exit: end = true; break;
} 16 }
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Example: BankAccountFacade
public class BankAccountFacade {
private int accountNumber;
private int securityCode;
private AccountNumberCheck acctChecker; private SecurityCodeCheck codeChecker; private FundsCheck fundChecker;
private Account account; private Transaction transaction;
public BankAccountFacade(int newAcctNum, int newSecCode){ } //Instantiate related objects
public void withdrawCash(double cashToGet){
//Check account number, security code, available fund //If all is valid, decrease cash in account
}public void depositCash(double cashToDeposit){ //Check account number, security code
} //If all is valid, increase cash in account }
17
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Façade VS GRASP Controller
Façade provides a simpler interface of a complex subsystem for a client class
Controller handles user inputs based on business
logics and workflow
Façade
Controller
18
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Façade VS Adapter
Façade wraps access to a subsystem or system with a single object
Adaptor wraps each API with the required mapping to provide a single interface
19
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Problem 4: Dynamic Behavior at Run-time
You want to add behavior or state to specific individual objects at run-time.
o Irrespective of combination of number of features or behaviours added, you don’t want to change the interface presented to the client.
o Inheritance is not feasible because it is static and applies to an entire class.
23
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Decorator (GoF)
Problem:
How to dynamically add behaviour or state to individual objects at run-time without changing the interface presented to the client. What to do?
Solution (advice):
Encapsulate the original concrete object inside an abstract wrapper interface. Then, let the decorators that contain the dynamic behaviours also inherit from this abstract interface. The interface will then use recursive composition to allow an unlimited number of decorator “layers” to be added to each core object.
24
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Decorator: General Form
Recursive Composition
A client is always interested in ConcreteComponent.operation() but may or may not be interested in ConcreteDecorator.operation(). More optional ConcreteDecotrators can be added to provide more behaviours.
26
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Decorator: Multiple “options”
Recursive Composition
Source: https://sourcemaking.com/design_patterns/decorator
27
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Decorator Example
Source: https://sourcemaking.com/design_patterns/decorator
28
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Collaboration and Sequencing
29
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Example: Shape Decorator
30
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Example: Shape Decorator
31
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Example: Shape Decorator
https://www.tutorialspoint.com/design_pattern/decorator_pattern.htm
32
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Shape Decorator Client
https://www.tutorialspoint.com/design_pattern/decorator_pattern.htm
33
Composite Vs Decorator
Irrespective of the close similarity in the UML models, Composites and Decorators solve different kinds of problem.
• Decorators decorate one object, which is the primary focus. Zero or more
decorators are used as needed to embellish that object.
• Composites exist out of necessity; while a composite needs at least one leaf
object, the composite itself is the primary focus.
34
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Problem 5: Refreshing Sales Total UI
a GUI window refreshes its display of the sale total when the total changes
Sale object should not send a message to a window, asking it to refresh its display
o Low coupling from other layers to the UI layer
“To handle this problem, let’s have an object observing the Sale object”
36
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Observer (aka Publish-Subscribe) (GoF)
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 unique way when the publisher generates an event. Moreover, the publisher wants to maintain low coupling to the subscribers. What to do?
Solution (advice):
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.
37
SWEN30006 Software Modelling and Design Applying GoF Design Patterns Observer: Generalised Structure
or publish()
a.k.a Publisher
a.k.a Listener, Subscriber
38
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Who is?: Observer, Listener, Subscriber, Publisher
Sale
addPropertyListener( PropertyListener lis ) publishPropertyEvent( name, value )
setTotal( Money newTotal ) …
• publishes events to observers/listeners/
subscribers
• registers them when
they ask to subscribe
javax.swing.JFrame
… setTitle() setVisible() …
propertyListeners
*
«interface» PropertyListener
onPropertyEvent( source, name, value )
• listens for events
• observes events
• subscribes to notification of events
SaleFrame1
onPropertyEvent( source, name, value )
initialize( Sale sale ) …
39
SWEN30006 Software Modelling and Design Applying GoF Design Patterns The Observer Pattern (Sale Total)
Concrete Subject
Sale
addPropertyListener( PropertyListener lis ) publishPropertyEvent( name, value )
setTotal( Money newTotal ) …
{
for each PropertyListener pl in propertyListeners
pl.onPropertyEvent( this, name, value ); }
{
propertyListeners.add( lis ); }
javax.swing.JFrame
… setTitle() setVisible() …
Concrete Observer
SaleFrame1 onPropertyEvent( source, name, value )
initialize( Sale sale ) …
propertyListeners
* «interface»
PropertyListener onPropertyEvent( source, name, value )
Observer Base
{
total = newTotal;
publishPropertyEvent( “sale.total”, total ); }
{
if ( name.equals(“sale.total”) )
saleTextField.setText( value.toString() ); }
{
sale.addPropertyListener( this )
… }
40
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Ob. SalesFrame1 Subscribes to Pub. Sale initialize( s : Sale )
sf : SaleFrame1
s : Sale
propertyListeners : List
addPropertyListener( sf )
add( sf )
41
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Sale Publishes Property Event to Subscribers
s :Sale
setTotal( total )
publishPropertyEvent ( “sale.total”, total )
propertylisteners[ i ] : PropertyListener
onPropertyEvent( s, “sale.total”, total )
loop
42
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Subscriber SaleFrame1 Receives Notification
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 concise.
43
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Summary of related GoF Patterns
Adapter provides a different interface to its subject. Decorator provides an enhanced interface.
Composite and Decorator have similar structure, reflecting the fact that both rely on recursive composition to organize an open-ended number of objects.
Composite, unlike Decorator, is not focused on embellishment but on representation. These intents are distinct but complementary. Consequently, Composite and Decorator are often used in concert.
Decorator lets you change the skin of an object. Strategy lets you change the guts.
44
Lecture Identification
Coordinator/Lecturer: Philip Dart
Semester: S1 2021
© University of Melbourne 2021 These slides include materials from:
Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development, Third Edition, by Craig Larman, Pearson Education Inc., 2005.
46