Lesson 6 - Design Patterns (1)
Lesson 6 - Design Patterns (1)
Design Patterns
What is a Design Pattern?
• Is it an algorithm?
• Is it a design?
9
Ingredients
Pattern
Context
a design situation giving rise to a design problem
Problem
a set of forces occuring in that context
Solution
a form or rule that can be applied to resolve these forces
Example – Context: placing windows in a house
forces
• he wants to sit down and be comfortable
• he is drawn toward the light
solution
• in every room, make at least one window considering light
direction
Pattern description (Pattern template)
Context:
• The general situation in which the pattern applies
Problem:
• A short sentence or two raising the main difficulty.
Forces:
• The issues or concerns to consider when solving the problem
Solution:
• The recommended way to solve the problem in the given context.
—‘to balance the forces’
Antipatterns: (Optional)
• Solutions that are inferior or do not work in this context.
Related patterns: (Optional)
• Patterns that are similar to this pattern.
References:
• Who developed or inspired the pattern.
Types of software patterns
design patterns (software design)
[Buschmann-POSA]
• architectural (systems design)
• design (micro-architectures) [Gamma-GoF]
• idioms (low level)
getInstance
private Singleton() { }
public static Singleton getInstance() {
return theInstance;
}
}
The Abstraction-Occurrence Pattern
• Context:
• Often in a domain model you find a set of related objects (occurrences).
• The members of such a set share common information
• but also differ from each other in important ways.
• Problem:
• What is the best way to represent such sets of occurrences in a
class diagram?
• Forces:
• You want to represent the members of each set of occurrences
without duplicating the common information
Abstraction-Occurrence
• Solution: «Abstraction» * «Occurrence»
TVSeries Episode
*
seriesName number
producer title
storySynopsis
Title LibraryItem
*
name barCodeNumber
author
isbn
publicationDate
libOfCongress
Abstraction-Occurrence
Antipatterns:
LibraryItem Title
LibraryItem
name name
name author author
author isbn isbn
isbn publicationDate publicationDate
publicationDate libOfCongress libOfCongress
libOfCongress barCodeNumber
barCodeNumber
LibraryItem
GulliversTravels MobyDick barCodeNumber
Abstraction-Occurrence
Abstraction-Occurrence Square variant
ScheduledTrain SpecificTrain
*
number date
* *
ScheduledLeg SpecificLeg
*
scheduledDepTime actualDepTime
scheduledArrTime actualArrTime
* *
origin destination
Station
The General Hierarchy Pattern
• Context:
• Objects in a hierarchy can have one or more objects above
them (superiors),
• and one or more objects below them (subordinates).
• Some objects cannot have any subordinates
• Problem:
• How do you represent a hierarchy of objects, in which some
objects cannot have subordinates?
• Forces:
• You want a flexible way of representing the hierarchy
• that prevents certain objects from having subordinates
• All the objects have many common properties and
operations
General Hierarchy
• Solution: «Node» *
«subordinate»
0..1
«NonSuperiorNode» «SuperiorNode»
FileSystemItem * contains
Employee * supervises
0..1 0..1
VideoRecoding AudioRecording
«Role1» «Role2»
Player-Role
Example 1:
Animal 0..2 HabitatRole
typeOfFood habitat
attendance level
«ConcreteObservable» «ConcreteObserver»
* * «interface»
Observable
Observer
Observers are
notified when a new
Forecaster prediction is ready WeatherViewer
Observer
Antipatterns:
• Connect an observer directly to an observable so
that they both have references to each other.
• Make the observers subclasses of the observable.
The Delegation Pattern
• Context:
• You are designing a method in a class
• You realize that another class has a method which
provides the required service
• Inheritance is not appropriate
• E.g. because the isa rule does not apply
• Problem:
• How can you most effectively make use of a method
that already exists in the other class?
• Forces:
• You want to minimize development cost by reusing
methods
Delegation
• Solution:
delegatingMethod()
«Delegator» «Delegate» {
delegate.method();
delegatingMethod method }
push()
Stack LinkedList {
list.addFirst();
push addFirst }
pop addLast
isEmpty addAfter
removeFirst
removeLast
delete
isEmpty
Delegation
Example: two levels of delegation
flightNumber() flightNumber()
{ {
return return
specificFlight.flightNumber(); regularFlight.flightNumber();
} }
Delegation
Antipatterns
• Overuse generalization and inherit the method that is
to be reused
• Instead of creating a single method in the «Delegator»
that does nothing other than call a method in the
«Delegate
• consider having many different methods in the «Delegator»
call the delegate’s method
• Access non-neighboring classes
return specificFlight.regularFlight.flightNumber();
return getRegularFlight().flightNumber();
The Adapter Pattern
• Context:
• You are building an inheritance hierarchy and want to
incorporate it into an existing class.
• The reused class is also often already part of its own
inheritance hierarchy.
• Problem:
• How to obtain the power of polymorphism when reusing a
class whose methods
• have the same function
• but not the same signature
as the other methods in the hierarchy?
• Forces:
• You do not have access to multiple inheritance or you do not
want to use it.
Adapter Pattern - Usage
Adapter Pattern - Adapter
Cannot Connect
Can Connect
The adapter acts as a middleman by receiving requests
from the client and converting them into requests that
make sense to the vendor classes.
Adapter Pattern - Usage
«Adapter» «Adaptee»
adaptedMethod
Adapter
Example: volume()
ThreeDShape {
return
volume TimsTorus.calcVolume();
}
«PackageClass2»
«PackageClass3»
* RegularFlight
Airline
findFlight
makeBooking *
deleteBooking Reservation
The Immutable
Pattern
• Context:
• An immutable object is an object that has a
state that never changes after creation
• Problem:
• How do you create a class whose instances are
immutable?
• Forces:
• There must be no loopholes that would allow
‘illegal’ modification of an immutable object
The Immutable Pattern
• Solution:
• Ensure that the constructor of the immutable
class is the only place where the values of
instance variables are set or modified.
• Instance methods which access properties
must not have side effects.
• If a method that would otherwise modify an
instance variable is required, then it has to
return a new instance of the class.
The Read-only Interface
Pattern
• Context:
• You sometimes want certain privileged classes to be able to
modify attributes of objects that are otherwise immutable
• Problem:
• How do you create a situation where some classes see a class
as read-only whereas others are able to make modifications?
• Forces:
• Restricting access by using the public, protected and
private keywords is not adequately selective.
• Making access public makes it public for both reading and
writing
Read-only Interface
• Solution:
«interface»
«ReadOnlyInterface» * «UnprivilegedClass»
getAttribute
«Mutable»
* «Mutator»
attribute «private»
getAttribute
setAttribute
Read-only Interface
Example:
«interface»
Person
getName
Mutableperson
firstName
lastName
setFirstName
setLastName
getName
The Proxy Pattern
• Context:
• Often, it is time-consuming and complicated to create instances of a
class (heavyweight classes).
• There is a time delay and a complex mechanism involved in creating
the object in memory
• Problem:
• How to reduce the need to create instances of a heavyweight class?
• Forces:
• We want all the objects in a domain model to be available for
programs to use when they execute a system’s various
responsibilities.
• It is also important for many objects to persist from run to run of the
same program
Proxy
• Solution:
«interface»
«ClassIF»
* * «Proxy» «HeavyWeight»
«Client»
Proxy
Example: «interface»
ListIF
The list elements will
be loaded into local
memory only when
needed.
ListProxy PersistentList
«interface»
Student
StudentProxy PersistentStudent
Factory Method
Case 1
• A button class has different
variations,(ImageButton, InputButton and
FlashButton).
• Depending on the request, it creates different
buttons.
Case 2
• There is a programme which draws a circle,
rectangle or square depending on the user input
• Problem
How do we encapsulate the object creational procedure that
may span different classes into one single function?
Forces
• Define an interface for creating an object and let the
subclasses to decide which class instantiates.
• Remember there isn't necessary to define factory
method if the class that's instantiated never changes,
or instantiation takes place in an operation that
subclasses can easily override scenarios.
Solution
• It encapsulates the knowledge of which product
subclass to create and moves this knowledge
out of the framework.
Factory Method Pattern
• http://en.wikipedia.org/wiki/Factory_method
_pattern
Difficulties and Risks When Creating Class
Diagrams
• Patterns are not a panacea:
• Whenever you see an indication that a pattern should
be applied, you might be tempted to blindly apply the
pattern. However this can lead to unwise design
decisions .
• Resolution:
• Always understand in depth the forces that need to be
balanced, and when other patterns better balance the
forces.
• Make sure you justify each design decision carefully.
Difficulties and Risks When Creating Class
Diagrams
• Developing patterns is hard
• Writing a good pattern takes considerable work.
• A poor pattern can be hard to apply correctly
• Resolution:
• Do not write patterns for others to use until you have considerable
experience both in software design and in the use of patterns.
• Take an in-depth course on patterns.
• Iteratively refine your patterns, and have them peer
• reviewed at each iteration.