0% found this document useful (0 votes)
10 views108 pages

Understanding Design Patterns in Software

The document discusses design patterns in software engineering, defining them as solutions to common design problems and categorizing them into architectural patterns, design patterns, and idioms. It outlines key elements for describing design patterns, their classification based on scope and purpose, and emphasizes the importance of design patterns in facilitating object creation, promoting reuse, and accommodating changes in software design. Additionally, it provides examples of common design patterns, such as Factory Method and Abstract Factory, and their applications in creating flexible and maintainable software systems.

Uploaded by

ibrakhim1908
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views108 pages

Understanding Design Patterns in Software

The document discusses design patterns in software engineering, defining them as solutions to common design problems and categorizing them into architectural patterns, design patterns, and idioms. It outlines key elements for describing design patterns, their classification based on scope and purpose, and emphasizes the importance of design patterns in facilitating object creation, promoting reuse, and accommodating changes in software design. Additionally, it provides examples of common design patterns, such as Factory Method and Abstract Factory, and their applications in creating flexible and maintainable software systems.

Uploaded by

ibrakhim1908
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Design Patterns

Software techniques
Content
• Design Patterns
> Definition
> Overview
> Classification
> What is the advantage of using design patterns?
> Detailing the most important patterns

• You should be familiar with some of them from Java


> We’ll now take an application-centric view
Definition
• Design patterns describe and detail the solution
of frequent problems. They can be used to
efficiently solve frequent designing problems.

• Example: MVC architecture


Example- Model-View-Controller (MVC) architecture

• Creating user interfaces with Smalltalk-80


• There are three roles/participants
> Model – application object
> View – presentation
> Controller – handling user interactions

• The relationship between the Model and the Views


Observers

Table chart Column chart Pie chart

a x y z
p 11 33 44
q 3 4 5
5
r 10 20 30 4
3

TableView ColumnChartView PieChartView


Change

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

> Source: E. Gamma R. Helm R. Johnson J. Vlissides:


Design Patterns
Classifying the patterns based on their
scope
• III. Idioms
> Low level design patterns. They are usually tied to a programming language.
> Solving problems that frequently occur in a given programming language.
> E.g. in C++: Smart Pointer
– Environment
• An object is used from multiple classes
– Problem
• A reference to the shared object must be present in all classes that use it.
Question: whose responsibility is it to free up the memory when the object is
not used any more (i.e. how to avoid memory leaks)?
– Solution
• Define a smart pointer class. It can be used just like an ordinary pointer but it
also provides some additional features mainly reference counting.
The concrete object can just be accessed through the smart pointer. The
smart pointer counts the active references and it will free up the memory
when the counter is decreased to zero.
– Implementation
• In C++, using templates. Better yet, use the implementation from STL 
Classifying the patterns based on their
scope
• Idioms– smart pointer example(don’t memorize)
int main(int argc, char* argv[])
{
MyClass* p = new MyClass;
a, without the delete we will p->DoSomething();
delete p;
have a memory leak }
// FRAGMENT of smart pointer template class
b, the auto_ptr smart // (reference counting is missing)
pointer class is responsible template <class T>
class auto_ptr {
for the reference counting T* ptr; // pointer to the object
and in case of need it will public:
explicit auto_ptr(T* p = 0) : ptr(p) {}
call the delete ~auto_ptr() { delete ptr; }
T& operator*() { return *ptr; }
T* operator->() { return ptr; }
// ...
};

int main(int argc, char* argv[])


{
auto_ptr<MyClass> p(new MyClass);
p->DoSomething();
}
Classifying the patterns based on their
scope
• From now on we will just deal with the middle
layer (design patterns)
• We will not be string with our categorization.
Many design pattern can be used as an
architectural patterns or as idioms.
Categories
• We can classify design patterns based on
different criteria
• Criteria
> Purpose
– Creational – concerns the creation of the objects
– Structural – concerns the composition of the objects
– Behavioral – concerns the cooperation of the objects
> Scope
– Class – emphasizes classes and inheritance
– Object – emphasizes objects and associations between
objects
Design pattern categories (don’t memorize) based
on the aforementioned book
Purpose

Creational Structural Behavioral

Class Factory Method Adapter Interpreter


Template Method

Object Abstract Factory Adapter Chain of Responsibility


Builder Bridge Command
Scope
Prototype Composite Iterator
Singleton Decorator Mediator
Facade Memento
Proxy Flyweight
Observer
State
Strategy
Visitor
Describing design patterns
 Design patterns do not have a specific description
language
 OMT or UML is used
 Class diagram
 Sequence diagram

 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?

During the system design we use multiple


design patterns. We usually use one
architectural pattern. This will provide the
basic structure. During the detailed design we
may use multiple design patterns that are
combined with each other.
Some important and frequent patterns
• Creational
> Factory method
> Abstract factory
> Singleton
> Prototype
• Structural What do you need to know?
> Adapter Be able to present a pattern either
> Bridge generally or using an example (in
> Proxy
which context, for what problem, how
> Composite
> Facade it works). Draw the class diagram for
the pattern (in come cases a
• Behavioral sequence diagram is also needed)
> Template method
> Iterator
> Observer
> Mediator
> Strategy
> Command
Creational patterns
Factory method
Abstract factory
Singleton
Factory method
Factory Method
• Purpose
> It defines an interface to create objects, but the particular instantiation is delegated
to the derived class (the derived class will determine the exact type of the
instantiated class). The Factory Method facilitates the delegation of the
instantiation to the derived class.
• It is often called „virtual constructor”
• Example
> Framework that supports multiple documents (e.g. Visual Studio)
> Two key classes of the framework
– Application
– Document
> Both of them are abstract classes, the programmer has to derive from them to
implement a custom classes. (let’s call them MyApplication and MyDocument)
> The Application class of the framework doesn’t exactly know what kind of
Document class should be created (as the MyDocument class did not even exist
when the framework was created), it only knows when it should be created.
Factory Method
Framework
<<abstract>> <<abstract>> NewDocument() {
Document Application Document* doc = CreateDocument();
+docs [Link](doc);
doc->Open();
<<abstract>> + Open() 0..* <<abstract>> + CreateDocument()
}
<<abstract>> + Close() + NewDocument()
<<abstract>> + Save() + OpenDocumnt()

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

Moti fWi ndow PMWi ndow


PMWi dgetFactory Moti fWi dgetFactory

+ 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()

ConcreteFactory1 ConcreteFactory2 <<abstract>>


AbstractProductB
+ CreateProductA() + CreateProductA()
+ CreateProductB() + CreateProductB()

Create ProductB2 ProductB1

<<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

> It requires programming language support


Singleton
In this case it is not the structure but the code that is important.

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

We can write it anywhere in the code:

 In C++: Singleton::Instance()

In Java: [Link]()

In C# a property should be used: [Link]

  global access to the instance


Singleton C++ class Singleton
{
C++ implementation public:
static Singleton* Instance();
The constructor of the Singleton protected:
class is protected! It guarantees Singleton() {; }
private:
that only the static Instance can static Singleton* _instance;
create an instance of it. };

Singleton* Singleton::_instance = 0;

Singleton* Singleton::Instance()
{
if (_instance == 0)
{
_instance = new Singleton;
}
return _instance;
}

int main(int argc, char* argv[])


{
Singleton* s1 = Singleton::Instance();
}
Singleton C#/Java
C#/Java implementation
public class Singleton
{
The constructor of the private static Singleton instance = null;
Singleton class is protected! public static Singleton Instance
It guarantees that only the {
static Instance can create an get
instance of it. {
if (instance == null)
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();

In the previous examples


public static Singleton Instance
the initialization of the static
{
member variables takes
place when they are first get { return instance; }
used. }

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

+ BoundingBox() + BoundingBox() BoundingBox() {


+ CreateManipulator() + CreateManipulator() return text->GetExtent();
}

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

<<abstract>> + Request() + Speci fi cRequest()

im pl ementation

Adapter Request() {
SpecificRequest();
}
+ Request()
Uses multiple inheritance
Participants

 Adaptee (TextView): interface that is adapted (this is the one


that needs to be converted)
 Adapter (TextShape) : this is the converter, converts interface
Adaptee to interface Target
 Target (Shape): the interface that the client expects
Adapter
 Structure – object adapter (second version)

<<abstract>> Adaptee
Cli ent T arget
+ Speci ficRequest()
<<abstract>> + Request()
+adaptee

Adapter

+ Request() Request() {
adaptee->SpecificRequest();
}

Uses object composition, uses delegation


Participants: just like in the Class Adapter

The Adapter contains a reference of the Adaptee

The Adapter delegates the operations to the Adaptee

The Adapter can contain multiple Adaptees.


Adapter
• Implementation
> In C++ in case of using a class adapters
– Private inheritance from the Adaptee class (implementation
inheritance)
– Public inheritance from the Target class (interface inheritance)
Adapter
• Use it when
> We want to use a class that doesn’t implement the required
interface
> We want to create a reusable class but we don’t know the
required interface for that in advance (pluggable adapters)

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 }

+ Draw() + Draw() + Draw() + Draw() Add() {


+ Add(g : Graphics) add g to li st of graphics;
+ Remove(g : Graphic) }
+ GetChil d() : Graphic
Composite - structure

<<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

Timer SerialPort Control Button


+Handle 0..1
+Location ButtonBase CheckBox
+Size
+Enabled Label RadioButton
+Visible

ScrollableControl

ContainerControl Panel GroupBox TabControl

* 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

Alrendszer (subsystem) Alrendszer (subsystem)


Facade
• Example 1
> Compiler
– Command line compiler: [Link], this has got many parameters
– We can not access to the internal of the compiler (parser, tokenizer, etc.)
• Example 2
> Multi-layer (usually enterprise) applications

Presentation Layer
The Presentation
Business Logic Layer Layer just accesses
this thin Business
Logic Layer
Business Logic Components,
Business Logic Processed /
Workflows, Entities

Data Access Layer


Facade
• Use it when
> We need a simple interface above a complex system
> There are many dependencies between the components
of the client and the subsystem. Introducing a Facade
reduces the dependency between them and it supports
portability, too.
> In case of layers

• 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()

Real Subj ect Proxy Request() {


+realSubject
...
+ Request() + Request() real Subject->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.

• Example: Opening a document in a framework


> Let us have two classes in the framework: Application and Document. The programmer has to derive
from them to implement the application-specific custom behavior.

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

 Calls some abstract methods that need to be implemented in the derived

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

# Pri mitiveOperati on1()


# Pri mitiveOperati on2()
Template method
• Consequences
> The common parts of an algorithm can be placed into the base class while
the derived class contains the custom implementation.
> We can avoid code duplication. The base class defines and calls some abstract
methods that need to be overridden in the derived classes. The overridden
abstract methods of the derived classes contain the custom implementations.
> We can define so called hook methods: these are the extension points in the code.

• 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

+ Add ( [in] doc : Document ) + Add ( [in] m : MenuItem ) + Clicked ( ) + Execute ( )

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 ( )

 Encapsulate user actions (and the corresponding operations) into


classes that derive from the Command base class and assign
them to the menu items!

88
Command
Example of custom implementation: Paste, Open
Framework
Application Menu MenuItem Command

+ Add ( [in] doc : Document ) + Add ( [in] m : MenuItem ) + Clicked ( ) + Execute ( )

- 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

Application Menu MenuItem Command *


- commands
+ Add ( [in] doc : Document ) + Add ( [in] m : MenuItem ) + Clicked ( ) + Execute ( )

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

> Supporting undo of the command – the state before the


command can be saved

91
Command - Structure

Client Invoker Command

+ 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

Command Processor stores, performs Command


- commandStack - commands *
+ Do ( )
+ do_cmd ( [in] cmd : Command ) + Undo ( )
+ undo_cmd ( )

- commandProcessor Receiver
ConcreteCommandB ConcreteCommandA uses

- stateForUndo - receiver
transfer commands
Creates + Do ( )
+ UnDo ( )
Creates
Controller

+ eventLoop ( )

94
Command Processor

System : Actor1 : Controller : Command Processor : Receiver

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

+ SetMemento ( [in] m : Memento ) + GetState ( )


+ CreateMemento ( ) : Memento + SetState ( )

return new Memento(state)

state = m->GetState()

> Originator: this is the object of which state we want to restore.


– The CreateMemento() creates a Memento that holds the actual state of
the object
– The SetMemento() restores the state of the object based on a previously
saved Memento.
> Memento: stores the state of the Originator. Theoretically only the
Originator should be able to read its content. E.g.: using the „friend”
declaration in C++
> CareTaker: Contains and maintains the memento objects.

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.

• Example: MVC or Document-View architecture


> The user changes the data through one of the views, how can the rest of them be
notified about the change?
Table chart Column chart

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

Table chart Column chart Pie chart

a x y z
p 11 33 44
q 3 4 5
5
r 10 20 30 4
3

TableView ColumnChartView PieChartView


Change

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.

 The system can easily be extended with new view classes.


Neither the model nor the existing view classes need to be
modified.

 Generally, apart from the model-view case


 The above model facilitates the notification of some observer
objects when the state of the observed object is changed
without having any specific internal information about the
observers.
 This is the point of the observer pattern

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.

• Note: the Observer is one of the most commonly used patterns


Iterator
Iterator

• 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

+ Open ( ) + Open ( ) + Open ( )


+ Close ( ) + Close ( ) + Close ( )
+ Acknowledge ( ) + Acknowledge ( ) + Acknowledge ( )

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 ( )

CreationTool SelectionTool TextTool

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

• Java design patterns:


> [Link]
> Pdf-ben letölthető!

• [Link]

You might also like