Module 45
Module 45
Iterator
Design Patterns
Command
Singleton
SE-06 1
Table of Contents
Module 45
Design
Pattern
1 Design Pattern
Iterator
Command
Singleton 2 Iterator
3 Command
4 Singleton
SE-06 2
Design Pattern
Module 45
A Design Pattern
describes a problem
Design
Pattern Occurring over and over again (in software engineering)
Iterator describes the solution
Command Sufficiently generic
Singleton Applicable in a wide variety of contexts
SE-06 3
Catalogue of Design Patterns (GoF)
Module 45
Design
Pattern
Iterator
Command
Singleton
SE-06 4
Relationships of Design Patterns (GoF)
Module 45
Design
Pattern
Iterator
Command
Singleton
SE-06 5
Describing a Design Pattern
Pattern Name and Classification Collaborations
Module 45
The pattern’s name conveys the essence of
the pattern succinctly How the participants collaborate to carry
Intent out their responsibilities?
Design What does the design pattern do? Consequences
Pattern What is its rationale and intent?
How does the pattern support its
What particular design issue or problem
objectives?
Iterator does it address?
What are the trade-offs and results of using
Also Known As the pattern?
Command
Other well-known names for the pattern
What aspect of system structure does can
Singleton
Motivation
be varied independently?
A scenario that illustrates a design problem
and how the class and object structures in Implementation
the pattern solve the problem What pitfalls, hints, or techniques should
Applicability you be aware of when implementing the
pattern?
What are the situations in which the design
Are there language-specific issues?
pattern can be applied?
What are examples of poor designs that Sample Code
the pattern can address? Code fragments to implement the pattern
How can you recognize these situations? in specific language (C++ or C# or Java)
Structure Known Uses
A graphical representation of the classes in Examples of the pattern found in real life
the pattern UML
Related Patterns
Participants What design patterns are closely related to
The classes and/or objects participating in this one?
the design pattern and their responsibilities What are the important differences?
SE-06 With which other patterns should this6 one
Describing a Design Pattern: Example of Iterator
Pattern Name and Classification: Iterator Participants
Module 45
Intent: Provide a way to access the elements of an Iterator defines an interface for accessing
aggregate object (container) sequentially without and traversing elements
exposing its underlying representation ConcreteIterator implements the Iterator,
keeps track of the current position
Design Also Known As: Cursor
Aggregate defines interface for Iterator
Pattern Motivation ConcreteAggregate implements the Iterator
An aggregate object (list) should have a to return an instance of ConcreteIterator
Iterator
way to access its elements without Collaborations: A ConcreteIterator keeps track of
Command exposing its internal structure the current object in the aggregate and can
There is a need to traverse the list in compute the succeeding object in the traversal
Singleton different ways, depending on a specific task
Multiple traversals may be pending on the Consequences
same list Variety of the traversals of an aggregate
The key idea in this pattern is to take the Iterators simplify the Aggregate interface
responsibility for access and traversal out of Multiple traversal on an aggregate
the list object and put it into an iterator Implementation
object
Who controls the iteration?
Applicability Who defines the traversal algorithm?
to access an aggregate object’s contents How robust is the iterator? (insert / delete)
without exposing its internal representation Additional Iterator functionality including
to support multiple traversals of aggregate more operations, polymorphic iterators in
objects C++, optional privileged access, Iterators
to provide a uniform interface for traversing for composites & Null iterators
different aggregate structures (that is, to Sample Code: Given in Iterator section
support polymorphic iteration)
Known Uses: Iterators are common in OOP
Structure: Given in Iterator section
Related Patterns: Composite, Factory Method,
and Memento
SE-06 7
Pros & Cons of Design Pattern
Pros
Module 45
Help capture and disseminate expert knowledge
Promotes reuse and avoid mistakes
Provide a common vocabulary
Design Help improve communication among the developers
Pattern
Reduce the number of design iterations:
Iterator
Help improve the design quality and designer productivity
Command Patterns solve software structural problems attributable to:
Singleton Abstraction,
Encapsulation
Information hiding
Separation of concerns
Coupling and cohesion
Separation of interface and implementation
Single point of reference
Divide and conquer
Cons
Design patterns do not directly lead to code reuse
To help select the right design pattern at the right point during a
design exercise
At present no methodology exists
SE-06 8
Example Design Patterns
Module 45
Iterator
Design
Singleton
Pattern
Factory Method
Iterator
Command
Abstract Factory
Singleton Visitor
SE-06 9
Iterator Pattern
Module 45
Pattern Name: Iterator
Design
Problem: How to serve Patients at a Doctor’s Clinic?
Pattern
Solution: Front-desk manages the order for patients to be
Iterator
called
Command
By Appointment
Singleton
By Order of Arrival
By Extending Gratitude
By Exception
Consequences:
Patient Satisfaction
Clinic’s Efficiency
Doctor’s Productivity
SE-06 10
Iterator Pattern: Intent
Module 45
Design
Pattern
Iterator
Command
Singleton
SE-06 11
Iterator Pattern: Sample Code
template <class Item>
Module 45 class List { public: List(long size = DEFAULT_LIST_CAPACITY);
long Count() const;
Item& Get(long index) const; // ...
};
template <class Item>
Design class Iterator { public:
Pattern virtual void First() = 0;
virtual void Next() = 0;
Iterator virtual bool IsDone() const = 0;
virtual Item CurrentItem() const = 0;
Command protected: Iterator();
Singleton };
template <class Item>
class ListIterator : public Iterator<Item> { public:
ListIterator(const List<Item>* aList);
virtual void First();
virtual void Next();
virtual bool IsDone() const;
virtual Item CurrentItem() const;
private: const List<Item>* _list; long _current;
};
template <class Item>
ListIterator<Item>::ListIterator (const List<Item>* aList) : _list(aList), _current(0) { }
template <class Item> void ListIterator<Item>::First() { current = 0; }
template <class Item> void ListIterator<Item>::Next() { current++; }
template <class Item> bool ListIterator<Item>::IsDone() const { return _current >= _list->Count();
}
template <class Item> Item ListIterator<Item>::CurrentItem () const {
if (IsDone()) { throw IteratorOutOfBounds; } return _list->Get(_current);
}
SE-06 12
Iterator Pattern: Sample Code
ReverseListIterator<Employee*> backward(employees);
PrintEmployees(forward);
PrintEmployees(backward);
SE-06 13
Iterator Pattern: Sample Code (STL list)
Command // the iterator constructor can also be used to construct from arrays:
int myints[] = {16,2,77,29};
Singleton std::list<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );
return 0;
}
-----
Normal Constructor (2 Params): (1, 1)
The contents of fifth are: 16 2 77 29
SE-06 14
Iterator Pattern: Sample Code (STL map)
return 0;
}
-----
Normal Constructor (2 Params): (1, 1)
a => 200
b => 100
c => 300
SE-06 15
“Check @ Diner” – A Command Pattern
Module 45
Customer places an Order with Waitress
Design
Waitress writes Order on check
Pattern
Order is queued to Cook
Iterator
Command
Singleton
SE-06 16
Command
Design
Pattern
Iterator
Command
Singleton
The pattern’s main piece is the Command class itself. Its most important purpose is to reduce the
dependency between two parts of a system: the invoker and the receiver
A typical sequence of actions is as follows:
The application (Client) creates a ConcreteCommand object (The dotted line), passing it
enough information to carry on a task.
The application passes the Command interface of the ConcreteCommand object to the
Invoker. The Invoker stores this interface.
Later, the Invoker decides it’s time to execute the action and fires Command’s Execute
virtual member function. The virtual call mechanism dispatches the call to the
ConcreteCommand object. ConcreteCommand reaches the Receiver object (the one that is to
do the job) and uses that object to perform the actual processing, such as calling its Action
member function
Alternatively, the ConcreteCommand object might carry the processing all by itself. In this
case, the receiver disappears
SE-06 17
Command
The invoker can invoke Execute at its leisure
Module 45 Most important, at runtime you can plug various actions into the invoker by replacing the Command object
that the invoker holds. Two things are worth noting here
Interface Separation: The invoker is isolated from the receiver. The invoker is not aware of how the
work is done
Design The invoker only calls for Execute for the Command interface it holds when certain
Pattern circumstances occur
On the other side, the receiver itself is not necessarily aware that its Action member function
Iterator was called by an invoker or otherwise
The invoker and receiver may be completely invisible to each other, yet communicate via
Command
Commands
Singleton Usually, an Application object decides the wiring between invokers and receivers
We can use different invokers for a given set of receivers, and we can plug different receivers
into a given invoker – all without their knowing anything about each other
Time Separation: Command stores a ready-to-go processing request to be started later
In usual programming tasks, when we want to perform an action, we assemble an object, a
member function of it, and the arguments to that member function into a call. For example:
window.Resize(0, 0, 200, 100); // Resize the window
The moment of initiating such a call is conceptually indistinguishable from the moment of
gathering the elements of that call (the object, the procedure, and the arguments)
In the Command pattern, however, the invoker has the elements of the call, yet postpones the
call itself indefinitely. The Command pattern enables delayed calls as in the following example:
Command resizeCmd( // GATHERING THE COMMAND (TASK)
window, // Object
&Window::Resize, // Member function
0, 0, 200, 100); // Arguments
// Later on...
resizeCmd.Execute(); // Resize the window // PERFORMING THE COMMAND
SE-06 18
Command: Implementation
Module 45 From an implementation standpoint, two kinds of concrete Command classes can be identified.
Forwarding Commands: Some simply delegate the work to the receiver. All they do is call a
member function for a Receiver object. They are called forwarding commands
Active Commands: Others do tasks that are more complex. They might call member
functions of other objects, but they also embed logic that’s beyond simple forwarding. They
Design are called active commands
Pattern
Separating commands into active and forwarding is important for establishing the scope of a generic
Iterator implementation
Command Active commands cannot be canned – the code they contain is by definition application specific, but
we can develop helpers for forwarding commands.
Singleton Forwarding commands act much like pointers to functions and their C++ colleagues, functors, we
call them Generalized Functors (Refer to Functor module for details.
SE-06 19
What is a Singleton?
Ensure a class only has one instance, and provides a global point of access to it (GoF Book)
Module 45
We should use Singleton when we model types that conceptually have a unique instance in the
application, such as Keyboard, Display, PrintManager, and SystemClock
Being able to instantiate these types more than once is unnatural at best, and often
dangerous
Design
Pattern A singleton is an improved global variable
The improvement that Singleton brings is that we cannot create a secondary object of the
Iterator singleton’s type
The Singleton object owns itself
Command
There is no special client step for creating the singleton – the Singleton object is responsible
Singleton for creating and destroying itself
Managing a singleton’s lifetime causes the most implementation headaches
The Singleton design pattern is queer in that it’s a strange combination:
Its description is simple, yet its implementation issues are complicated
There is no best implementation of the Singleton design pattern
Various Singleton implementations, including non-portable ones, are most appropriate depending on
the problem at hand
SE-06 20
Static Data + Static Functions != Singleton
Can a Singleton be implemented by using static member functions and static member variables?
Module 45
class Font { ... };
class PrinterPort { ... };
class PrintJob { ... };
PrintJob somePrintJob("MyDocument.txt");
MyOnlyPrinter::AddPrintJob(somePrintJob);
All the constructors are private, user code cannot create Singletons
Singleton’s own member functions, Instance() in particular, are allowed to create objects
The uniqueness of the Singleton object is enforced at compile time
This is the essence of implementing the Singleton design pattern in C++
If it’s never used (no call to Instance() occurs), the Singleton object is not created
The cost of this optimization is the (usually negligible) test incurred at the beginning of
Instance()
The advantage of the build-on-first-request solution becomes significant if Singleton is
expensive to create and seldom used
SE-06 22