APPLYING GOF DESIGN PATTERNS
The shift of focus (to patterns) will have a profound and enduring effect on the way we write programs.
—Ward Cunningham and Ralph Johnson
Larman Chapter 26
SWEN30006
Software Modelling and Design
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
A Brief History of Design Patterns
1977: Christopher Alexander publishes: “A Pattern Language: Towns, Buildings, Construction”
1987: Cunningham and Beck used Alexander’s ideas to develop a small pattern language for Smalltalk
1990: The Gang of Four (Gamma, Helm, Johnson and Vlissides) begin work compiling a catalog of design patterns
1991: Bruce Anderson gives first Patterns Workshop at OOPSLA
1993: Kent Beck and Grady Booch sponsor the first meeting of what is now
known as the Hillside Group
1994: First Pattern Languages of Programs (PLoP) conference
1995: The Gang of Four (GoF) publish their ground breaking book: “Design Patterns: Elements of Reusable Software”
2
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Patterns in Architecture
“The street cafe provides a unique setting, special to cities: a place where people can sit lazily, legitimately, be on view, and watch the world go by… Encourage local cafes to spring up in each neighborhood. Make them intimate places, with several rooms, open to a busy path, where people can sit with coffee or a drink and watch the world go by. Build the front of the cafe so that a set of tables stretch out of the cafe, right into the street.”
— Christopher Alexander et al., A Pattern Language, pages 437,439
3
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Gang of Four Design Patterns
Creational Patterns (5):
abstract the object instantiation process. Structural Patterns (7):
describe how classes and objects can be combined to form larger structures.
Behavioural Patterns (11):
are most specifically concerned with communication between objects.
4
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 (Concrete) Factory o Singleton
o Strategy
o Composite
o Façade
o Observer
o Decorator
Recognise GRASP principles as a generalization of other design patterns.
6
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Problem 1:
External Services with Varying Interfaces
POS system needs to support several kinds of external services, including:
o Tax calculators
e.g., TaxMaster, GoodAsGoldTaxPro
o Accounting systems
e.g., SAP, GreatNorthern
o Credit authorization services
Each service has a different API, which cannot be changed.
7
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Adapter (GoF)
Problem:
How to resolve incompatible interfaces, or provide a stable interface to similar components with different interfaces?
Solution (advice):
Convert the original interface of a component into another interface, through an intermediate adapter object.
8
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
The Adapter Pattern
«interface» ITaxCalculatorAdapter
getTaxes( Sale ) : List of TaxLineItems
Adapters use interfaces and polymorphism to add a level of indirection to varying APIs in other components.
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 GreatNorthernAccountingAdapter
postReceivable( CreditPayment ) postSale( Sale )
…
postReceivable( CreditPayment ) postSale( Sale )
…
9
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Using an Adapter
makePayment
:Register
: SAPAccountingAdapter
…
SOAP over HTTP
postSale( sale )
xxx
«actor»
: SAPSystem
the Adapter adapts to interfaces in other components
10
SWEN30006 Software Modelling and Design Applying GoF Design Patterns Example: Disney Madness
Using an external libraries for Disney characters o APIs cannot be modified
11
SWEN30006 Software Modelling and Design Applying GoF Design Patterns Disney Madness: Design without Adapter
12
SWEN30006 Software Modelling and Design Applying GoF Design Patterns Disney Madness: Design with Adapter
Create a common interface for the Main class and create an adapter for each library
13
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Disney Madness: Design with Adapter
14
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Disney Madness: Implement with Adapter
public interface IDisneyAdapter { } public void move();
public class SlothAdapter implements IDisneyAdapter { private Sloth theSloth;
public SlothAdapter(String name) {
} theSloth = new Sloth(name);
public void move() { theSloth.wake();
} } theSloth.pushToClimb();
15
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Disney Madness: Implement with Adapter
public class DisneyMadess {
public static void main(String[] args) {
//With adapter
IDisneyAdapter slothAdt = new SlothAdapter(“Flash”); slothAdt.move();
IDisneyAdapter ironManAdt = new IronManAdapter(“Tony”); ironManAdt.move();
IDisneyAdapter trooperAdt = new TrooperAdapter(”Storm”); } } trooperAdt.move();
16
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Issues arising from Adapter
Who creates the adapters?
Which class of adapter should be created?
o Should the Register object create SAPAccountingAdapter?
:Register
: SAPAccountingAdapter
makePayment
…
SOAP over HTTP
postSale( sale )
xxx
«actor» : SAPSyste
20
the Adapter adapts to
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Issues arising from Adapter
Who creates the adapters?
Which class of adapter should be created?
o Should the Register object create SAPAccountingAdapter?
Partial Answer:
Separation of Concerns/High Cohesion
o Creating adapters is not pure application logic o Adapter object is not a domain object
Use GRASP Pure Fabrication pattern
21
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Factory
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 (advice):
Create a Pure Fabrication object called a Factory that handles the creation.
23
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
(Concrete) Factory
Aka Simple Factory
Simplified GoF Abstract Factory pattern
Advantages:
Separate responsibility of complex creation into cohesive helper objects.
Hide potentially complex creation logic.
Allow introduction of performance-enhancing memory management strategies, such as object caching or recycling.
24
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
The Factory Pattern
ServicesFactory
accountingAdapter : IAccountingAdapter inventoryAdapter : IInventoryAdapter taxCalculatorAdapter : ITaxCalculatorAdapter
getAccountingAdapter() : IAccountingAdapter getInventoryAdapter() : IInventoryAdapter getTaxCalculatorAdapter() : 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
Properties File Entry
! taxcalculator.class.name=TaxMasterAdaptor taxcalculator.class.name=GoodAsGoldTaxProAdaptor
25
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;
SWEN30006 Software Modelling and Design Applying GoF Design Patterns Example: Disney Madness
Using an external libraries for Disney characters o APIs cannot be modified
26
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Implement DisneyMadness with Adapter and Factory
public class DisneyFactory {
private IDisneyAdapter characterAdapter = null;
public IDisneyAdapter getDisneyAdapter(String character, String name){ if(character.equals(“ironman”)) {
characterAdapter = (IDisneyAdapter) new IronManAdapter(name); }else if(character.equals(“sloth”)) {
characterAdapter = (IDisneyAdapter) new SlothAdapter(name); }else if(character.equals(“trooper”)) {
} characterAdapter = (IDisneyAdapter) new TrooperAdapter(name);
} } return characterAdapter;
27
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Issues arising from Factory
Who creates the Factory and how is it accessed? o It may need to be called from various places
Oftentimes only one instance of this factory is needed.
How to get visibility to this single ServicesFactory instance?
makePayment
:Register
: SAPAccountingAdapter
…
SOAP over HTTP
postSale( sale )
xxx
the Adapter adapts to interfaces in other components
«actor»
: SAPSystem
28
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Issues arising from Factory
How is Factory accessed?
o It may need to be called from various places
How to get visibility to this single ServicesFactory instance?
Partial Answer:
Only one instance of the factory is needed
Where required, pass through to methods or
initialise objects with a ref? No.
Use Singleton pattern to provide a single access point through global visibility
29
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Singleton (GoF)
Problem:
Exactly one instance of a class is allowed—it is a “singleton.” Objects need a global and single point of access.
Solution (advice):
Define a static method of the class that returns the singleton.
30
SWEN30006 Software Modelling and Design Applying GoF Design Patterns Singleton Pattern in ServicesFactory Class
UML notation: in a class box, an underlined attribute or method indicates a static (class level) member, rather than an instance member
accountingAdapter : IAccountingAdapter inventoryAdapter : IInventoryAdapter taxCalculatorAdapter : ITaxCalculatorAdapter
getInstance() : ServicesFactory
singleton static attribute
singleton static method
// static method
public static synchronized ServicesFactory getInstance() {
if ( instance == null )
instance = new ServicesFactory() return instance
}
31
UML notation: this ‘1’ can optionally be used to indicate that only one instance will be created (a singleton)
ServicesFactory instance : ServicesFactory
1
getAccountingAdapter() : IAccountingAdapter getInventoryAdapter() : IInventoryAdapter getTaxCalculatorAdapter() : ITaxCalculatorAdapter …
Lazy Initialization
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Accessing the Singleton Factory
public class Register
{
public void initialize()
{… do some work …
// accessing the singleton Factory via the
getInstance call
accountingAdapter =
ServicesFactory.getInstance().getAccountingAdapter();
… do some work …
}// other methods… } // end of class
SingletonClass.getInstance()
is globally visible 32
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Implicit getInstance Singleton Pattern Message
:Register
1 :ServicesFactory
initialize
aa = getAccountingAdapter
…
the ‘1’ indicates that visibility to this instance was achieved via the Singleton pattern
aa = ServicesFactory.getInstance().getAccountingAdapter(); 33
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Static: why some and not all?
Why aren’t all Singleton service methods static?
E.g. static getAccountingAdapter(): …
May want subclasses: static methods are not polymorphic (virtual); no overriding in most languages
Most remote communication mechanisms (e.g. Java’s RMI) don’t support remote-enabling of static methods.
A class is not always a singleton in all application contexts.
34
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Problem 1 Revisited:
External Services with Varying Interfaces
Possible solution:
“To handle this problem, let’s use Adapters
generated from a Singleton Factory.”
Design reasoning based on: o Controller
o Creator
o ProtectedVariations o LowCoupling
o HighCohesion
o Indirection
o Polymorphism o Adaptor
o Factory
o Singleton
35
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Adapter, Factory, and Singleton Patterns
:Store
1 :ServicesFactory
c re ate
c re ate
:Regis ter
accountingAdapter = getAccountingAdapter
c re ate
: SAPAccounting Adapter
:Regis ter
accountingAdapter: S A P A cc ou n ti ng A d a p te r
m a ke P a y m e n t
c re ate (cas hTe nd er ed ) postSale( sale )
xxx
:Payment
SOAP over HTTP
«a ct or »3 6 : SAPSystem
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
More examples, on YouTube
From LMS Design Pattern Resources:
New Think Tank Design Patterns Tutorials o AdaptorDesignPattern
o FactoryDesignPattern
Design Patterns in OO Programming: by C. Okhravi based on the textbook Head First Design Patterns
o FactoryDesignPattern
o Singleton Design Pattern
37
SWEN30006 Software Modelling and Design Applying GoF Design Patterns
Lecture Identification
Coordinator: Philip Dart 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.
41