Understanding Design Patterns in Software
Understanding Design Patterns in Software
Software techniques
Content
• Design Patterns
> Definition
> Overview
> Classification
> What is the advantage of using design patterns?
> Detailing the most important patterns
a x y z
p 11 33 44
q 3 4 5
5
r 10 20 30 4
3
Update
U
Up e
pd
te
C
g
ha
da
an
at
e
ng
Ch
e
x=3
y=4
z=5
Model (subject)
Describing design patterns
• There are four basic elements to describe a design
pattern
> Pattern name
– The name of the pattern. Identifies the pattern.
– It is important because of the communication: developers just
have to name the pattern and the role of the object in the
pattern to identify its responsibility.
> Problem
– The problem and its context, a usually a concrete example
helps understanding
> Solution
– Describes the elements (classes) of the solution, the roles,
responsibilities and the co-operation of the elements. This is
not a concrete implementation but an abstract solution.
> Consequences
– The consequences of using the pattern. Lists some practical
experiences and helps to choose the correct pattern.
Classifying the patterns based on their
scope
• The level of the software system where the pattern is
used (architecture -> subsystem-> … -> coding in a given
programming language)
• Three groups
Scope
I. Architectural patterns
II. Design patterns
Scope III. Idioms
Classifying the patterns based on their
scope
• I. Architectural patterns – discussed on the previous
lecture
> Introduces the basic structure for the whole system. The
basic structure of the software system. Defines the
subsystems, their responsibilities and the connections
between them.
> E.g.:
– Layers
– Model-View-Controller architecture
• Document-based windowing systems
– Document-view architecture
• Document-based windowing systems
– Pipes
• Processing streams
– ...
Classifying patterns based on their
scope
• II. Design patterns
> This is what we usually mean by design patterns (many times
architectural patterns and idioms are not explicitly called
design patterns).
> They are used inside a subsystem or component
– Scope-wise they are situated in the middle
– They have no effect on the basic structure (architecture) of the
application
– They are programming language independent
Textual description
Pattern catalog
• The format of pattern description in the catalog (don’t need to know)
> Name: the name of the pattern
> Intent: the purpose of the pattern, what it is used/good for
> Also known as: alternative names
> Motivation: practical example, it shows how the pattern solves the concrete problem
> Applicability: context where the pattern can be used
> Structure: the class and object diagram for the pattern
> Participants: short description of the classes in the pattern
> Collaboration: describes the co-operation of the classes in the pattern
> Consequences: evaluation, how efficient does the pattern solve the problem
> Implementation: details about the implementation problems of the pattern, covers language-
dependent problems, short code examples
> Sample code: typical code example
> Known uses: references for existing systems that use the pattern.
> Related patterns: closely related patterns.
How do patterns help to solve
problems?
• They help in the designing phase
• They help in the following problems:
> I. Finding and defining the needed object
– Defining the number and the size of the object
– Defining the interfaces of the objects
– Implementing the objects
> II. Design for reuse
> III. Design for change
Details
How do patterns help to solve
problems?
• It is difficult to find the necessary objects
> When designing a system based on a natural language
specification collecting the nouns and verbs may help to find
the necessary objects and classes and their hierarchy.
> But systems usually have got classes that do not exist in the
real world but play important roles in the system:
– Certain low level classes (e.g. an array class)
– Control/manager classes
– ...
> Design patterns help to find the non-trivial classes.
Design for reuse
• Reusability is not trivial. We have to pay attention to it during system
design!
> an efficient way to reduce the costs of the development
> on the long term it may be worth developing a framework
• Framework definition
> In a certain domain (e.g. windowing systems, document handling systems,
mathematical systems, graphical systems, CAD systems, etc.):
– Defines the architecture of the application, and provides some basic building-
blocks (classes).
– In OO environment: pre-defined co-operative classes with pre-defined
responsibilities. How to use the built in classes?
• We have to derive from them
• We have to override the virtual/abstract methods of the base class
(E.g. ln Windows Forms the Form is the base class)
– Goal: as little coding as possible when developing using the framework.
– Gives a consistent structure to our applications.
– At the architectural level there is no need to design, as the architecture is
determined by the framework (design for reuse)
Design for change
• Design for change is not trivial. We have to pay attention to it during
system design!
• Why?
> It is difficult to design a system
> At the beginning we quite often don’t know the exact task
> Software products are usually iteratively improved after the release
• When we design the system we have to pay attention to the fact that
the system will be modified later (design for change)!
> We can preserve the existing code even when we have to modify the
application.
> When we have to change some part of the application,
– The modifications should be local
– As little change should be made on the existing code as possible (e.g. just
deriving from a base class is necessary)
– Development is faster, there won’t be so much new bugs!
> Don’t use it everywhere, as designing for change may also take a lot of
time (costs a lot). Use it where changes are expectable.
Principle
• Goal: reduce the dependency between the
subsystems or components
> A change should just effect one/a few number of component(s)
– Changeability
– Reusability
System of Patterns
• What does „system of patterns” mean?
MyApplication CreateDocument() {
MyDocument return new MyDocument();
Create }
+ CreateDocument()
Application
• When the user selects the „New” menu item, the framework calls the
Application::NewDocument() method.
• In this method „new MyDocument()” couldn’t have been written as the MyDocument
class did not event exist at that time.
• Solution: to instantiate the document the Application::NewDocument() calls the
Application::CreateDocument() abstract function, that should be overridden in the
derived class by the developer, to return a MyDocument –typed document instance.
Factory Method
Solution
Delegate the instantiation to the derived class (creating the
document instance)
Structure
<<abstract>> AnOperation() {
<<abstract>> Creator ...
Product product = FactoryMethod()
...
<<abstract>> + FactoryM ethod()
}
+ AnOperation()
ConcreteCreator FactoryMethod() {
ConcreteProduct return new ConcreteProduct()
Create
+ FactoryM ethod() }
Factory Method
• Use it when
> A class does not know in advance the exact type that it
should instantiate
> A class wants its derived classes to determine the exact types
that are instantiated.
Abstract Factory
Abstract factory - Example
• Example
> Windowing system, GUI controls (form, button, drop-down
list, etc.)
> The application should support user interfaces with multiple
different “look-and-feel”s
– E.g. Motif, Presentation Manager
> How to do it?
> Create a different version for each GUI element and each “look-
and-feel”
> Don’t hardwire the applied user interface elements into the
application (neither their creation nor their usage).
– Encapsulate the instantiation, delegate it to an other class
– In the application we should only refer to the certain classes
through interfaces (the implementation will be replaceable)
Abstract factory
Wi dgetFactory
Cli ent
<<abstract>> + CreateScrollBar()
<<abstract>> + CreateWi ndow()
Wi ndow
+ CreateScrollBar() + CreateScrollBar()
+ CreateWi ndow() + CreateWi ndow()
Create
Scrollbar
Moti fScroll
Create
bar
PMScrollBar
Create
Create
Abstract factory - Solution
• Create an abstract WidgetFactory class that supports the creation of all the
user interface elements.
• All the methods of the WidgetFactory class return a user interface element
instance (e.g. the returned type should be Window instead of MotifWindow)
• All the custom presentation managers have got their corresponding
WidgetFactory derived class (MotifWidgetFactory, PMWidgetFactory), that
methods return user interface elements being typical for the given
presentation (MotifWindow, PMWindow).
• The client uses a concrete WidgetFactory implementation (e.g.
PMWidgetFactory) through the general WidgetFactory interface to create a
particular user interface element. These particular user interface elements
are only referenced through their abstract base classes (e.g. Window
instead of PMWindow)
(In the client code there will be no concrete Factory for user interface
element classes. They may only occur during the configuration when the
MotifManager or the PresentationManager class is instantiated. Thus the
client is totally independent from the chosen particular presentation type.)
Abstract factory - Structure
<<abstract>>
AbstractFactory
Cli ent
<<abstract>> + CreateProductA()
<<abstract>> + CreateProductB()
<<abstract>>
AbstractProductA
Create
ProductA2
ProductA1
Create
Create
Practical example
Problem: Design a provider independent data access layer for multi-layer applications (e.g.
in [Link])
ICommand interface
– SqlCommand
– OracleCommand
– OleDbCommand
IConnection interface
– SqlConnection
– OracleConnection
– OleDbConnection
> ...
The solution (with abstract factory):
IDbFactory interface (CreateCommand, CreateConnection,
etc. operations).
– SqlDbFactory implementation This is a built-in
– OracleDbFactory implementation solution in .NET 2.0!
– OleDbDbFactory implementation
Abstract factory
• Use it when
> The system should be independent from the concrete elements that it creates
> The system should support multiple product families
> The system should co-operate with tightly-combined „product” families and it
should be forced in the system (e.g. a Motif scrollbar couldn’t be used with a
Presentation Manager Window)
Advantages Disadvantages
Concrete classes are separated It is difficult to introduce a new
Product families are easily product. The whole architecture of
replaceable the Abstract Factory should be
modified, as it is the interface that
Facilitates consistency between
records the creational operations.
product families
(We can get around this
sometimes using inheritance).
Singleton
Singleton
• Purpose
> Guarantees the creation of only one instance of a class
and provides a global access to that.
• This is a frequently used pattern
> A window manager object
> A file system manager object
> ...
• Solution
> Singleton
– It should be the responsibility of the class to provide the single
instance.
– Provide global access to the single instance
Singleton Instance() {
<<static>> - uniqueInstance return uniqueInstance;
- singletonData }
<<static>> + Instance()
+ SingletonOperation()
+ GetSingletonData()
The single instance can be created and queried by the help of the Instance class-
operation (static!).
The same object is returned for each call
In C++: Singleton::Instance()
Singleton* Singleton::_instance = 0;
Singleton* Singleton::Instance()
{
if (_instance == 0)
{
_instance = new Singleton;
}
return _instance;
}
protected Singleton() { }
public void Print() {…}
}
Singleton
Don’t need to know
public class Singleton
The previous solutions are {
not thread-safe private readonly static Singleton instance =
new Singleton();
protected Singleton() { }
The C# compiler generates
public void Print() {…}
thread-safe code for this
solution. }
Overview of creational design patterns
• The purpose of the creational design patterns: instantiate types
to support flexibility, extendibility and reusability.
> Factory method: delegates the instantiation to the derived class
> Abstract factory: factory hierarchy to instantiate elements of
different product families
> Singleton: only one instance exists, provides global access to the
single instance
> ...
• As an alternative to the factory-like creational patterns, most
modern languages support some kind of a reflection technique
> The type that we want to instantiate can be specified as a string.
> Disadvantage of reflection:
– much slower
– not strongly typed anymore, bigger chance to make a mistake
Structural patterns
Adapter
Composite
Facade
Proxy
Adapter
(Wrapper)
Adapter
• Purpose
> Converts the interface of a class to an other one that is expected by the
client. Facilitates the co-operation of classes even if they have got
incompatible interfaces.
• Example
> Graphical Editor
– Graphical shapes (line, polygon, text) – they derive from the Shape
class (line – LineShape, polygon – PoligonShape, text – TextShape,
etc.)
– The implementation of the TextShape class is difficult, but suppose
we have got a TextView class that knows everything that is needed
for the TextShape
– Problem: The TextView class can not directly be used as it hasn’t got
the required interface, e.g. it does not derive from the Shape class (it
does not support the Shape interface, so it can not be handled as a
Shape)
– Solution: use the Adapter design pattern
Adapter
<<abstract>>
Shape TextView
DrawingEditor
0..* <<abstract>> + BoundingBox()
<<abstract>> + CreateManipulator() +text
LineShape TextShape
CreateManipulator() {
Two types return new TextManipulator();
}
Class adapter
Object adapter
The above example is an „object”
adapter
Adapter
• Structure– class adapter (first version)
<<abstract>>
Cli ent T arget Adaptee
im pl ementation
Adapter Request() {
SpecificRequest();
}
+ Request()
Uses multiple inheritance
Participants
<<abstract>> Adaptee
Cli ent T arget
+ Speci ficRequest()
<<abstract>> + Request()
+adaptee
Adapter
+ Request() Request() {
adaptee->SpecificRequest();
}
50
Composite
Composite
• Purpose
> Arrange objects that are in whole-part relationships into a tree structure
> It hides from the client whether an object is a composite or a simple one. Thus, all the
objects can be handled uniformly.
• Example
> A graphical application that facilitates the creation/usage of compound graphic objects.
<<abstract>>
Graphic
<<abstract>> + Draw()
<<abstract>> + Add(g : Graphic) +graphi cs
<<abstract>> + Remove(g : Graphic)
<<abstract>> + GetChil d(int)
Draw() {
for each g in graphics
[Link]();
LineG RectangleG TextG PictureG }
<<abstract>>
Component
Client +children
<<abstract>> + Operation()
<<abstract>> + Add(Component)
0..*
<<abstract>> + Remove(Component)
<<abstract>> + GetChild(int)
Leaf
Composite
Operation() {
+ Operation()
+ Operation() for each g in children
+ Add(Component) [Link]();
+ Remove(Component) }
+ GetChild(int)
Composite
• Use it when
> You want to express the whole-part relationship
between objects
> You want to hide from the client whether an object is
an elementary or a composite one. You want to
handle them in a uniform way
Composite
Question: In which class should we implement the
logic for the composite operations (Add, Remove,
…), these operations can not be used in the leaf
objects (LineG, TextG, etc.)
– In the Component class (just like in the example):
Advantage: the objects are uniform, as both have got Add, Remove,
GetChild operations
Disadvantage: not safe, but we may throw an exception if an
operation shouldn’t be called on an object (e.g. Add on a leaf object)
– In the Composite class:
Disadvantage: the opposite of the previous solution
E.g. the Component base class may have an IsComposite: bool
virtual method that is overridden in the derived classes. For the leaf
classes it should return false otherwise it should return true.
Composite
• Question: Where does this pattern appear in
Windows Forms applications?
Component/Control hierarchy
Component
* Controls
Parent
ScrollableControl
* TabPages
0..1
Form UserControl FlowLayoutPanel TableLayoutPanel TabPage
Owner
OwnedForms *
64
Facade
Facade
• Purpose
> Introduces a uniform interface instead of the many interfaces of a subsystem.
> It defines a higher level interface that makes the use of the subsystem more
simple.
> Example
Facade
Presentation Layer
The Presentation
Business Logic Layer Layer just accesses
this thin Business
Logic Layer
Business Logic Components,
Business Logic Processed /
Workflows, Entities
• Remark
> Question: should we let the client access the internal
components of the subsystem?
– Introducing the Facade does not force the client to use it, the
client can still use the internal components
Proxy
Proxy
• Purpose
> Instead of the real object, a substitute is used that
controls access to the real one
• Examples
> Text-editor
– Many large images
– They don’t need to always be displayed, only when we
scroll there, that is when they are visible.
> Solution: Proxy
– Substitute the image with an object (proxy) that displays
the image if that is loaded otherwise it first loads that and
than displays that.
Proxy
<<abstract>>
Graphic
DocumentEditor
<<abstract>> + Draw()
0..* <<abstract>> + GetExtent()
<<abstract>> + Store()
<<abstract>> + Load()
Draw() {
i f (image==0) {
image = LoadImage( fi leName );
Im age Im ageProxy }
- imageImp +image - fi leNam e i mage->Draw();
- extent - extent }
+ Draw() + Draw()
Create
+ GetExtent() + GetExtent() GetExtent() {
+ Store() + Store() i f (image==0)
+ Load() + Load() return extent;
else
return image->GetExtent();
}
Proxy
<<abstract>>
Cli ent Subj ect
<<abstract>> + Request()
Subject: common interface for the Subject and the Proxy (this is the core
of the pattern!)
RealSubject: this is the real object that is hidden by the proxy
Proxy: the substitute object. Contains a reference for the real object. It
controls the access to the real object. It may also be responsible for
creating and deleting the object.
Proxy
• Remote Proxy
> A local representative of a remote object. The communication
with the remote object is transparent for the client. It doesn’t
even notice that it is communicating with a different process
/ an other computer.
• Virtual Proxy
> On-demand creation of resource intensive objects (e.g.
images)
• Protection Proxy
> The access control to the real object is based on permissions.
• Smart Pointer
> Encapsulating a pointer so that additional features can be
provided (e.g. reference counting, locking)
Behavioral patterns
Template method
Command
Memento
Observer
Iterator
State
Template method
Template method
• Purpose
> Defines the skeleton of an algorithm in the base class and delegates the implementation of some steps to
the derived class.
Framework
<<abstract>> Appl ication
Document
+docs + AddDocument()
+ Save() + OpenDocum ent()
+ Open() <<abstract>> # DoCreateDocument()
+ Close() <<abstract>> # CanOpenDocument()
<<abstract>> + DoRead() <<abstract>> # AboutT oOpenDocument()
Application
MyAppl iaction DoCreateDocument() {
MyDocument return new MyDocument();
# DoCreateDocument() }
+ DoRead() # CanOpenDocument()
# AboutT oOpenDocument()
Template method
The OpenDocument method is a so called template method in the example
Defines the order of the operations
class.
// Az Application class is a part of the framework
void Application::OpenDocument (const char* name) {
if (!CanOpenDocument(name)) {
// cannot handle this document
return;
}
// DoCreateDocument must be overwridden in the derived
// MyApplication class. This will contain
// the fully-fledged implementation
Document* doc = DoCreateDocument();
if (doc) {
_docs->AddDocument(doc);
AboutToOpenDocument(doc);
doc->Open();
doc->DoRead();
}
}
Template method
• Structure
TemplateMethod() {
AbstractClass ...
Pri mitivOperation1();
+ TemplateMethod() ...
<<abstract>> # Pri mitiveOperati on1() Pri mitivOperation2();
<<abstract>> # Pri mitiveOperati on2() ...
ConcreteCl ass
• Notes
> Typical in the case of frameworks
> In .NET presents a simpler solution: delegates. This pattern is usually used in C++
and Java.
> It has got nothing to do with C++ templates (those are generic types)
Command
Command
• Purpose
> Encapsulating an operation into an object. It facilitates the reuse, undo,
queue and easy modification of the operations. The operations are usually
responses to client interactions.
• Alternative name
> Action
• The concept and the implementation is quite language-dependent
(C++, .NET, etc.)
• Example: user commands
> Menu, button, toolbar button
> Participants e.g.: Application, Document, Menu, Submenu, Menu item, etc.
> Problem: the writers of the framework couldn’t have implemented the
handling of the menu item selection (what should happen when a menu
item is selected)
> How to react to the menu item click event?
– Callback function – not object-oriented (structural) solution
– Adapter-based solution – Java
– Delegate-based solution- .NET
– Command pattern
87
Command
Framework
Application Menu MenuItem Command
Document
Each action will have a class
Minden parancsnak egy Command
+ Open ( ) derived from Command
leszármazott.
+ Close ( ) representing it (shown on the next
+ Cut ( ) slide, missing from here).
+ Copy ( )
+ Paste ( )
88
Command
Example of custom implementation: Paste, Open
Framework
Application Menu MenuItem Command
- application
Document
+ Open ( )
+ Close ( ) PasteCommand OpenCommand
+ Cut ( )
+ Copy ( ) - document + Execute ( ) + Execute ( )
+ Paste ( ) + AskDocName ( )
document->Paste()
name = AskDocName()
doc = new Document(name)
application->Add(doc)
doc->Open()
Application
89
Command
Macro: sequence of commands
Document
+ Open ( )
+ Close ( ) PasteCommand MacroCommand
+ Cut ( )
+ Copy ( ) - document + Execute ( ) + Execute ( )
+ Paste ( )
for all c in commands
c->Execute()
90
Command
• Use it when
> If in a structured programming language you would use a
callback function (to achieve partial functionality), in OO
use a command instead.
> You would like to queue the operations (commands) that
can even be executed in separate threads/processes.
The parameters of the operations can be stored in the
command objects.
– A special case is when you would like to execute the
commands one-by-one in a thread. E.g. in the GUI thread, but
in this case the [Link]() is the good solution
91
Command - Structure
+ Execute ( )
Receiver ConcreteCommand
- receiver - state
+ Action ( )
Create
+ Execute ( )
receiver->Action()
92
Command
• The handling of the command is separated from the
invoker of the command
• Makes an extendable system. New commands can
be added by deriving from the Command base class
• Adding new commands does not effect the existing
ones.
• Complex commands are also supported
• A command can be assigned to multiple user
interface elements (menu item, toolbar button, etc.)
93
Command
• Command Processor
> A variation of the Command pattern
> Supports a basic undo out of the box
> The Command Processor is the key class
– Stores the Command objects
– Activates (executes) the Command objects and provides some other
services
- commandProcessor Receiver
ConcreteCommandB ConcreteCommandA uses
- stateForUndo - receiver
transfer commands
Creates + Do ( )
+ UnDo ( )
Creates
Controller
+ eventLoop ( )
94
Command Processor
1 : Request ( )
2 : \new\ cmd : Capitalize Command
Do()
3 : do_cmd ( )
4 : GetSelection ( )
5 : Capitalize ( )
6 : UndoRequest ( ) UnDo()
7 : undo_cmd ( )
8 : RestoreText ( )
9 : delete
95
CommandBinding in .NET
96
Memento
97
Memento
• Purpose
> Sharing and storing the internal state of an object so that it can be
restored later.
• Example: Undo operation for a Document
• Solution:
> Invertible operations in the Command pattern
– It is hard to be solved in many cases
– It is impossible in many cases
• The public interface of the object doesn’t have an operation for the undo.
Undo
> In these cases there is just one solution: we have to save the original state
of the object.
98
Memento
Originator Memento CareTaker
Create
- state - state - memento
state = m->GetState()
99
Memento
: CareTaker : Originator
1 : CreateMemento ( ) Save
2 : \new\
m : Memento
3 : SetState ( )
4 : SetMemento ( m )
5 : GetState ( )
Undo
100
Memento
• Use it when
> the state of an object needs to be restored and a
direct interface that support this would break OO
encapsulation.
Advantages: Disadvantages
It preserves the Using mementos is
concept of often resource-intensive
encapsulation It is hard to determine in
Makes the Originator advance the amout of
simpler memory required by the
Caretaker
101
Observer
Observer
• Purpose
> How can objects notify each other about the change of their state without having
dependencies to each other.
a x y z
p 11 33 44
q 3 4 5
Update 5
r 10 20 30 4
3
TableView Up
ColumnChartView
da
te
Pie chart
PieChartView
Observer
• The disadvantages of the direct method calls
between the views
- Dependency on the certain class. E.g. the TableView is
dependent on the ColumnChartView and the
PieChartView classes.
- If we want to add a new view the existing ones have to
be modified.
- The model (business logic) is not reusable as it is bound
to the presentation. It would be straightforward if the
business logic wouldn’t contain references to particular
views as in this case it could be reused
- It is difficult to maintain, reuse or develop as there is
strong dependency between the classes.
104
Observer
Solution
> MVC or the Document-View architecture is a solution for the previous problem
> Separate the data from the presentation. Let us put the data into a model class and the different
presentations to view classes.
> Multiple views (observers) can be registered to a model.
> If one of the views changes the model, the model will notify all the registered views about the
change.
> As a response for the notification the view queries the actual state of the model and refreshes
itself.
> The model just references the views through a general interface (observer)
Observers
a x y z
p 11 33 44
q 3 4 5
5
r 10 20 30 4
3
U Update
Up e
pd
te
C
g
ha
da
an
at
e
ng
Ch
e
x=3
y=4
z=5
Model (subject)
105
Observer
Advantages
The model just uses IView references in the view list, so the
model is independent from the concrete views. The model is
reusable!
This is a simple mechanism to keep all the views consistent.
106
Observer
Observer
• Participants
> Subject
– Stores the registered Observers
– Defines an interface for registering, unregistering and notifying views.
> Observer
– Defines an interface for objects that want to be notified about the
change of the Subject. (Update operation)
> ConcreteSubject
– Contains state information that are important for the observers.
– Notifies all the registered observers when its state changes.
> ConcreteObserver
– Stores a reference for the observed ConcreteSubject object.
– Stores a state information of the ConcreteSubject that needs to be
kept in a consistent state with the real state.
– Implements the Observer interface (Update operation). This is the
method that the Subject calls when the state of the ConcreteSubject
is changed. The state of the view is updated based on the actual
state of the ConcreteSubject.
Observer
Dynamic view (registration and notification)
cs: ob1 : ob2 :
ConcreteSubject ConcreteObserver ConcreteObserver
Attach()
Attach()
SetState( )
Notify( )
Update( )
GetState( )
Update( )
GetState( )
Observer
Advantages Disadvantages
Loose coupling between the Unnecessary updates
Subject and the Observer For an Update call all the state
Supports broadcasting information is refreshed (though in the
Update the Subject can specify the
changed field(s)).
In the previous example the view that
has initiated the Notify will also be
updated (that is unnecessary)
Observer
• Use it when
> the change of the state of an object causes the change of the state of some other objects
and the set of these objects is not known in advance.
• Purpose
> Provides an interator for a complex (e.g. list) object without revealing the internal
structure of the object.
• Example: List
> We would like to iterate through the list without having any information about the
internal structure of the list.
• Solution
> Remove the operations of the iteration from the interface of the list and put it into
a separate Iterator object.
ListIterator
List
- index
-l ist
+ Count() + First()
+ Append(El em ent) + Next()
+ Remove(El ement) + IsDone()
+ CurrentItem()
Iterator
• Structure
Cli ent
<<abstract>>
Iterator
<<abstract>>
Aggregate <<abstract>> + First()
<<abstract>> + Next()
<<abstract>> + CreateIterator() <<abstract>> + IsDone()
<<abstract>> + CurrentItem()
ConcreteIterato
ConcreteAggregate r
Create
+ CreateIterator() + First()
+ Next()
+ IsDone()
+ CurrentItem()
CreateIterator() {
return new ConcreteIterator();
}
Iterator
• Use it when
> We want to access the contained items of an object without revealing the internal structure
of the containing object.
> We want to allow access the items of the object in many ways.
> We want to allow parallel accesses to the same list at the same time.
> We want to access the items of multiple objects (e.g. lists) but we want to use a common
(the same) interface.
• Implementation
> In C++ it is worth using templates
> Example: the STL contains many container and iterator classes.
State
State
• Purpose
> Facilitates the change of the behavior of an object when the state of the object is changed.
The behavior of the object is state-dependent.
• Example 1
> The TCPConnection class represents a network connection
> There are three states: Listening, Established, Closed
> The requests are served based on the actual state.
> Solution
– Using if statements - state
TCPConnection TCPState
– State pattern
+ Open ( ) + Open ( )
+ Close ( ) + Close ( )
+ Acknowledge ( ) + Acknowledge ( )
state->Open()
TCPListen TCPEstablished TCPClosed
117
State
• Example 2
> Handling the tools of a graphical application. (There is always one selected tool.)
DrawingController Tool
- currenttool
+ MousePress ( ) + HandleMousePress ( )
+ ProcessKeyboard ( ) + HandleMouseRelease ( )
+ Initialize ( ) + HandleCharacter ( )
+ GetCursor ( )
+ Activate ( )
118
State
• General solution
Context - state State
+ Request ( ) + Handle ( )
state->Handle()
ConcreteStateA ConcreteStateB
+ Handle ( ) + Handle ( )
• Note
> It is a usual solution that the Context passes itself to the operations of the State as parameter
// C++ example
void TCPConnection::Close ()
{
state->Close(this);
}
> The pattern does not specify who is responsible for the state management
– Context
– The State-derived classes. This is a distributed solution. Can be useful, but in this case the State-derived
classes have to know each other.
119
State
Use it when
The behavior of the object is dependent on its state, and the behavior
has to be changed on the run-time as the state changes.
The operations would have huge conditional statements based on the
state of the object.
Advantages: Disadvantages:
Encapsulates the state- There will be more classes
dependent behavior of the (use the pattern only if it is
object. It is easy to introduce a really needed)
new state.
Nice code (no huge switch-
case statements)
The State objects can be
shared
120
References
• [1] Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides: DESIGN PATTERNS, Elements of Reusable
Object-oriented Software
• [2] Frank Buschmann, Regine Meunier, Hans Rohnert, Peter Sommerland, Michael Stal: A SYSTEM OF
PATTERNS, Pattern-Oriented Software Architecture
• [Link]