You are on page 1of 18

/* *************** https://sourcemaking.

com/design_patterns ************* */
A design pattern is a general solution to a commonly occurring problem in softwa
re design.
Creational design patterns
-------------------------These design patterns are all about class instantiation. This pattern can be fur
ther divided into class-creation
patterns and object-creational patterns. While class-creation patterns use inher
itance effectively in the
instantiation process, object-creation patterns use delegation effectively to ge
t the job done.
* Abstract Factory------Creates an instance of several families of classes
* Builder----------Separates object construction from its representation
* Factory Method
Creates an instance of several derived classes
* Object Pool
Avoid expensive acquisition and release of resources by recyclin
g objects that are no longer in use
* Prototype-------A fully initialized instance to be copied or cloned
* Singleton-------A class of which only a single instance can exist
Structural design patterns
-------------------------These design patterns are all about Class and Object composition. Structural cla
ss-creation patterns use inheritance
to compose interfaces. Structural object-patterns define ways to compose objects
to obtain new functionality.
* Adapter--------Match interfaces of different classes
* Bridge
Separates an object s interface from its implementation
* Composite
A tree structure of simple and composite objects
* Decorator
Add responsibilities to objects dynamically
* Facade
A single class that represents an entire subsystem
* Flyweight
A fine-grained instance used for efficient sharing
* Private Class Data
Restricts accessor/mutator access
* Proxy
An object representing another object
Behavioral design patterns
-------------------------These design patterns are all about Class's objects communication. Behavioral pa
tterns are those patterns that
are most specifically concerned with communication between objects.
* Chain of responsibility
A way of passing a request between a chain of objects

* Command
Encapsulate a command request as an object
* Interpreter
A way to include language elements in a program
* Iterator------Sequentially access the elements of a collection
* Mediator
Defines simplified communication between classes
* Memento
Capture and restore an object's internal state
* Null Object
Designed to act as a default value of an object
* Observer--------A way of notifying change to a number of classes
* State
Alter an object's behavior when its state changes
* Strategy
Encapsulates an algorithm inside a class
* Template method
Defer the exact steps of an algorithm to a subclass
* Visitor--------Defines a new operation to a class without change
================================================================================
====================================
-------------------------------------------------Singleton--------------------------------------------------------================================================================================
====================================
The singleton pattern ensures a class has only one instance, and provides a glob
al point of access to it.
It makes use of private constructor, static/ class method and private static var
iable.
* Singleton class manages single instance itself. It prevents other class from c
reating a new instance by declaring
its constructor private.To get an instance class method needs to be called.
* It provides global point of access to instance by providing a class method get
Instance() to get the instance.This
method is the only way to get singleton class instnce.
* This method also provides lazy instantiation of singleton.
* The advantage of Singleton over global variables is that you are absolutely su
re of the number of instances when
you use Singleton, and, you can change your mind and manage any number of inst
ances. Also lazy instantiation
can be done in singleton.
example :
class singleton
{
private :
static singleton *uniqueInstance;
singleton(){}
public :
static singleton* getInstance()
{
// Lazy instantiation : creating an object when it is required t
o be used, not up-front.
if(uniqueInstance == NULL)

uniqueInstance = new singleton();


return uniqueInstance;
}
};
Dealing with multi threading
---------------------------1. Using mutex :
* Locking is costly opertation thus solution is in-effective if getInsance me
thod is called frequently.
........
std::mutex mt
public static singleton getInstance()
{
//std::lock_guard<std::mutex> lock(mt);
mt.lock();
if(uniqueInstance == NULL)
uniqueInstance = new singleton();
mt.unlock();
return uniqueInstance;
}
........
2. Move to eager instantiation (creating objects up-front, even before they are
required or might be used)
from lazy instantiation.
* Effective only when application always creates and uses the singleton insta
nce.
* Not to be used if application never creates singleton class instance and si
ngleton is a memory hogging class.
example :
Call MySingleton::GetInstance() during program start-up, like in main()
3. Double checked locking :
* Enters in critical section only once when intance is created.
..............
std::mutex mt
public static singleton getInstance()
{
if(uniqueInstance == NULL)
{
mt.lock();
if(uniqueInstance == NULL)
uniqueInstance = new singleton();
mt.unlock();
}
return uniqueInstance;
}
.........
================================================================================
====================================
-------------------------------------------------Iterator---------------------------------------------------------================================================================================
====================================
* Provide a way to access the elements(Polymorphically) of an aggregate object s
equentially without exposing its
underlying representation.
* It places task of traversal on iterator object rather than aggregate which sim

plifies aggregate implementation and


responsibility.
* Polymorphically provides a uniform interface for traversing many types of aggr
egate objects
* Abstraction makes it possible to decouple collection classes and algorithms.
* Need to "abstract" the traversal of wildly different data structures so that a
lgorithms can be defined that are
capable of interfacing with each transparently.
* The Iterator abstraction is fundamental to "generic programming". This seeks e
xplicitly to separate the notion of
"algorithm" from that of "data structure". The motivation is to promote compon
ent-based development, boost
productivity, and reduce configuration management.
Example :
Files are aggregate objects. In office settings where access to files is made th
rough administrative or secretarial
staff, the Iterator pattern is demonstrated with the secretary acting as the Ite
rator. To the executive, the filing
system is confusing and illogical, but the secretary is able to access files qui
ckly and efficiently.
* The abstract syntax tree of Interpreter is a Composite (therefore Iterator and
Visitor are also applicable).
* Iterator can traverse a Composite. Visitor can apply an operation over a Compo
site.
* Polymorphic Iterators rely on Factory Methods to instantiate the appropriate I
terator subclass.
* Memento is often used in conjunction with Iterator. An Iterator can use a Meme
nto to capture the state of an iteration. The Iterator stores the Memento intern
ally.
Inetrnal and External Iterators :
* In external iterator client controls the iteration by calling next() to get th
e next element.
* An internal iterator is controlled by itself. User have to tell iterator what
to do with those elements as it goes
through them. This means user needs a way to pass operation to iterator.
* External iterators are more flexible than internal iterators because user has
control over the iterator.
Single Responsibility :
* Aggregate class can manage it's data structure as well as the traversal or ite
ration which means a class have
two resposibility.
* Every responsibility of a class is an area of potential change. More than one
responsibility means more than one
change, that creates dependency which can cause problems when the class grows.
* Design principle : A class should have only one reason to change.
* Cohesion : is how closely a class or module supports single purpose of respons
ibility
class Stack
{
int items[10];
int sp;
public:
friend class StackIter;
StackIter *createIterator()const; // 2. Add a createIterator() member
};

class StackIter
{
// 1. Design an "iterator" class
const Stack *stk;
int index;
public:
StackIter(const Stack *s)
{
stk = s;
}
void first()
{
index = 0;
}
void next()
{
index++;
}
bool isDone()
{
return index == stk->sp + 1;
}
int currentItem()
{
return stk->items[index];
}
};
StackIter *Stack::createIterator()const
{
return new StackIter(this);
}
================================================================================
====================================
-------------------------------------------------Composite--------------------------------------------------------================================================================================
====================================
* Compose objects into tree structures to represent whole-part hierarchies. Comp
osite lets clients treat individual
objects and compositions of objects uniformly.
* It allows us to build tree structure of objects that contains both composition
of objects and objects as node.
* Using this we can apply same operations over both.
* Manipulate a hierarchical collection of "primitive" and "composite" objects. P
rocessing of a primitive object is
handled one way, and processing of a composite object is handled differently
Example :
* Menus that contain menu items, each of which could be a menu.
* Directories that contain files, each of which could be a directory.
Implementation :
* Define an abstract base class (Component) that specifies the behavior that nee
ds to be exercised uniformly across
all primitive and composite objects. Subclass the Primitive and Composite clas
ses off of the Component class.
Each Composite object "couples" itself only to the abstract type Component as

it manages its "children".


* Use this pattern whenever you have "composites that contain components, each o
f which could be a composite".
* Child management methods [addChild(), removeChild()] should normally be define
d in the Composite class.
Unfortunately, the desire to treat Primitives and Composites uniformly require
s that these methods be moved to
the abstract Component class.
* Being able to treat a heterogeneous collection of objects atomically (or trans
parently) requires that the
"child management" interface be defined at the root of the Composite class hie
rarchy (the abstract Component class).
However, this choice costs you safety, because clients may try to do meaningle
ss things like add and remove
objects from leaf objects. On the other hand, if you "design for safety", the
child management interface is
declared in the Composite class, and you lose transparency because leaves and
Composites now have different interfaces.
Relation with other patterns :
* Composite and Decorator have similar structure diagrams, reflecting the fact t
hat both rely on recursive
composition to organize an open-ended number of objects.
* Composite can be traversed with Iterator. Visitor can apply an operation over
a Composite. Composite could use
Chain of Responsibility to let components access global properties through the
ir parent. It could also use
Decorator to override these properties on parts of the composition. It could u
se Observer to tie one object
structure to another and State to let a component change its behavior as its s
tate changes.
* Composite can let you compose a Mediator out of smaller pieces through recursi
ve composition.
* Decorator is designed to let you add responsibilities to objects without subcl
assing. Composite's focus is
not on embellishment but on representation. These intents are distinct but com
plementary. Consequently,
Composite and Decorator are often used in concert.
* Flyweight is often combined with Composite to implement shared leaf nodes.
================================================================================
====================================
-------------------------------------------------Adapter----------------------------------------------------------================================================================================
====================================
* Convert the interface of a class into another interface clients expect. Adapte
r lets classes work together that
couldn't otherwise because of incompatible interfaces.
* Wrap an existing class with a new interface.
* Adapter is about creating an intermediary abstraction that translates, or maps
, the old component to the new system.

Clients call methods on the Adapter object which redirects them into calls to
the legacy component. This strategy
can be implemented either with inheritance or with aggregation.
* Adapter functions as a wrapper or modifier of an existing class. It provides a
different or translated view of that
class.
Relation with other patterns :
* Adapter makes things work after they're designed; Bridge makes them work befor
e they are.
* Bridge is designed up-front to let the abstraction and the implementation vary
independently. Adapter is
retrofitted to make unrelated classes work together.
* Adapter provides a different interface to its subject. Proxy provides the same
interface. Decorator provides
an enhanced interface.
* Adapter is meant to change the interface of an existing object. Decorator enha
nces another object without changing
its interface. Decorator is thus more transparent to the application than an a
dapter is. As a consequence, Decorator
supports recursive composition, which isn't possible with pure Adapters.
* Facade defines a new interface, whereas Adapter reuses an old interface. Remem
ber that Adapter makes two existing
interfaces work together as opposed to defining an entirely new one.
Class Adaptors and Object Adapters :
--------------------------------* Class adapter uses inheritance, can also override behavior of adaptee. Object
adapter uses composition, also
adopts all the subclasses of adaptee
// Desired interface (Target)
class Rectangle
{
public:
virtual void draw() = 0;
};
// Legacy component (Adaptee)
class LegacyRectangle
{
public:
LegacyRectangle(int x1, int y1, int x2, int y2) {
std::cout << "LegacyRectangle(x1,y1,x2,y2)\n";
}
void oldDraw() {
std::cout << "LegacyRectangle: oldDraw(). \n";
}
};
// Adapter wrapper
class RectangleAdapter: public Rectangle, private LegacyRectangle
{
public:
RectangleAdapter(int x, int y, int w, int h):
LegacyRectangle(x, y, x + w, y + h) {
std::cout << "RectangleAdapter(x,y,x+w,x+h)\n";
}

void draw() {
std::cout << "RectangleAdapter: draw().\n";
oldDraw();
}
};
================================================================================
====================================
-------------------------------------------------Factory Method---------------------------------------------------================================================================================
====================================
* Define an interface for creating an object, but let subclasses decide which cl
ass to instantiate. Factory Method
lets a class defer instantiation to subclasses.
* Factory Method is to creating objects as Template Method is to implementing an
algorithm. A superclass specifies
all standard and generic behavior (using pure virtual "placeholders" for creat
ion steps), and then delegates the
creation details to subclasses that are supplied by the client.
* Factory Methods are routinely specified by an architectural framework, and the
n implemented by the user of the
framework.
* As with every factory, Factory method pattern gives us a way to encapsulate th
e instantiation of concrete types.
* An increasingly popular definition of factory method is: a static method of a
class that returns an object of that
class' type. But unlike a constructor, the actual object it returns might be a
n instance of a subclass. Unlike a
constructor, an existing object might be reused, instead of a new object creat
ed. Unlike a constructor, factory
methods can have different and more descriptive names
* The client is totally decoupled from the implementation details of derived cla
sses. Polymorphic creation is
now possible.
* If you have an inheritance hierarchy that exercises polymorphism, consider add
ing a polymorphic creation capability
by defining a static factory method in the base class.
* Design the arguments to the factory method. What qualities or characteristics
are necessary and sufficient to identify
the correct derived class to instantiate?
* Consider designing an internal "object pool" that will allow objects to be reu
sed instead of created from scratch.
* Consider making all constructors private or protected.
* Abstract Factory classes are often implemented with Factory Methods, but they
can be implemented using Prototype.
* Factory Methods are usually called within Template Methods.
* Factory Method: creation through inheritance. Prototype: creation through dele
gation.
* Often, designs start out using Factory Method (less complicated, more customiz
able, subclasses proliferate) and
evolve toward Abstract Factory, Prototype, or Builder (more flexible, more com
plex) as the designer discovers
where more flexibility is needed.
* The advantage of a Factory Method is that it can return the same instance mult
iple times, or can return a subclass
rather than an object of that exact type.

* The new operator considered harmful. There is a difference between requesting


an object and creating one. The new
operator always creates an object, and fails to encapsulate object creation. A
Factory Method enforces that
encapsulation, and allows an object to be requested without inextricable coupl
ing to the act of creation.
Benefits :
* Avoid duplication of code.
* Provide one place to perform maintenance.
* Clients depends upon interfaces rather than concrete classes, decoupling code
from implementation.
Dependency inversion principle :
* Depend upon abstraction. Do not depend upon concrete classes
* High level components should not depend on low level components rather they sh
ould both depend on abstraction.
* A high level component is a class with behavior defined in terms of other low
level components.
* Avoid violation of this principle by :
1) No variable should hold reference to concrete class.
2) No class should derive from concrete class.
3) No method should override an implemented method of any of its base class.(els
e base class won;t be an abstraction)
================================================================================
====================================
-------------------------------------------------Abstract Factory-------------------------------------------------================================================================================
====================================
* Provide an interface for creating families of related or dependent objects wit
hout specifying their concrete
classes.
* A hierarchy that encapsulates: many possible "platforms", and the construction
of a suite of "products"
* Provide a level of indirection that abstracts the creation of families of rela
ted or dependent objects without
directly specifying their concrete classes. The "factory" object has the respo
nsibility for providing creation
services for the entire platform family. Clients never create platform objects
directly, they ask the factory to do
that for them.
* Abstract Factory classes are often implemented with Factory Methods, but they
can also be implemented using Prototype.
* This mechanism makes exchanging product families easy because the specific cla
ss of the factory object appears only
once in the application - where it is instantiated. The application can wholes
ale replace the entire family of
products simply by instantiating a different concrete instance of the abstract
factory.
* Abstract Factory, Builder, and Prototype can use Singleton in their implementa
tion.
* Abstract Factory, Builder, and Prototype define a factory object that's respon
sible for knowing and creating the
class of product objects, and make it a parameter of the system. Abstract Fact
ory has the factory object producing

objects of several classes. Builder has the factory object building a complex
product incrementally using a
correspondingly complex protocol. Prototype has the factory object (aka protot
ype) building a product by copying
a prototype object.
* Factory method is used to implement concrete factories.
Problem
* If an application is to be portable, it needs to encapsulate platform dependen
cies. These "platforms" might include:
windowing system, operating system, database, etc.
Difference between factory and abstract factory :
---------------------------------------------* Both decouples implementation(creating object) from application. Decouples cli
ent from concrete classes
* Factory method uses inheritance(to override factory method) while abstract fac
tory uses object composition to
create objects.
================================================================================
====================================
-------------------------------------------------Visitor Design Pattern-------------------------------------------================================================================================
====================================
* Represent an operation to be performed on the elements of an object structure.
Visitor lets you define a new
operation without changing the classes of the elements on which it operates.
* The classic technique for recovering lost type information.
* Do the right thing based on the type of two objects.
* Double dispatch
* Visitor's primary purpose is to abstract functionality that can be applied to
an aggregate hierarchy of "element"6
objects. The approach encourages designing lightweight Element classes - becau
se processing functionality is removed
from their list of responsibilities. New functionality can easily be added to
the original inheritance hierarchy by
creating a new Visitor subclass.
* Visitor implements "double dispatch". OO messages routinely manifest "single d
ispatch" - the operation that is
executed depends on: the name of the request, and the type of the receiver.
In "double dispatch", the operation executed depends on: the name of the reque
st, and the type of TWO
receivers (the type of the Visitor and the type of the element it visits).
Implementation :
-------------* Create a Visitor class hierarchy that defines a pure virtual visit() method in
the abstract base class for each
concrete derived class in the aggregate node hierarchy. Each visit() method ac
cepts a single argument - a pointer
or reference to an original Element derived class.
* Each operation to be supported is modelled with a concrete derived class of th
e Visitor hierarchy. The visit() methods
declared in the Visitor base class are now defined in each derived subclass by
allocating the "type query and cast"
code in the original implementation to the appropriate overloaded visit() meth

od.
* Add a single pure virtual accept() method to the base class of the Element hie
rarchy. accept() is defined to receive
a single argument - a pointer or reference to the abstract base class of the V
isitor hierarchy.
* Each concrete derived class of the Element hierarchy implements the accept() m
ethod by simply calling the visit()
method on the concrete derived instance of the Visitor hierarchy that it was p
assed, passing its "this" pointer as
the sole argument.
* When the client needs an operation to be performed, (s)he creates an instance
of the Vistor object, calls the
accept() method on each Element object, and passes the Visitor object.
* The accept() method causes flow of control to find the correct Element subclas
s. Then when the visit() method is
invoked, flow of control is vectored to the correct Visitor subclass. accept()
dispatch plus visit() dispatch equals
double dispatch.
* The Visitor pattern makes adding new operations (or utilities) easy - simply a
dd a new Visitor derived class. But,
if the subclasses in the aggregate node hierarchy are not stable, keeping the
Visitor subclasses in sync requires
a prohibitive amount of effort.
Check list :
----------* Confirm that the current hierarchy (known as the Element hierarchy) will be fa
irly stable and that the public
interface of these classes is sufficient for the access the Visitor classes wi
ll require. If these conditions are
not met, then the Visitor pattern is not a good match.
* Create a Visitor base class with a visit(ElementXxx) method for each Element d
erived type.
* Add an accept(Visitor) method to the Element hierarchy. The implementation in
each Element derived class is always
accept( Visitor v ) { v.visit( this ); }. Because of cyclic dependencie
the same
s, the declaration of the Element
and Visitor classes will need to be interleaved.
* The Element hierarchy is coupled only to the Visitor base class, but the Visit
or hierarchy is coupled to each Element
derived class. If the stability of the Element hierarchy is low, and the stabi
lity of the Visitor hierarchy is high;
consider swapping the 'roles' of the two hierarchies.
* Create a Visitor derived class for each "operation" to be performed on Element
objects. visit() implementations
will rely on the Element's public interface.
* The client creates Visitor objects and passes each to Element objects by calli
ng accept().
* The abstract syntax tree of Interpreter is a Composite (therefore Iterator and
Visitor are also applicable).
* Iterator can traverse a Composite. Visitor can apply an operation over a Compo
site.
* The Visitor pattern is like a more powerful Command pattern because the visito
r may initiate whatever is appropriate
for the kind of object it encounters.
* The Visitor pattern is the classic technique for recovering lost type informat
ion without resorting to dynamic casts.

==========================================================
Strategy Pattern
==========================================================
The strategy pattern is intended to provide a means to define a family of algori
thms, encapsulate each one as an object,
and make them interchangeable. The strategy pattern lets the algorithms vary ind
ependently from clients that use them.
class SortBehavior
{
public:
virtual void sort() const = 0;
};
class Merge: public SortBehavior
{
public:
virtual void sort() const {
cout << "Merge sort()\n";
}
};
class Quick: public SortBehavior {
public:
virtual void sort() const {
cout << "Quick sort()\n";
}
};
class Heap: public SortBehavior
{
public:
virtual void sort() const {
cout << "Heap sort()\n";
}
};
class SearchBehavior
{
public:
virtual void search() const = 0;
};
class Sequential: public SearchBehavior
{
public:
virtual void search() const {
cout << "Sequential search()\n";
}
};
class BinaryTree: public SearchBehavior
{
public:
virtual void search() const {
cout << "BinaryTree search()\n";
}

};
class HashTable: public SearchBehavior
{
public:
virtual void search() const {
cout << "HashTable search()\n";
}
};
// Context
class Collection
{
private:
SortBehavior* m_sort;
SearchBehavior* m_search;
public:
Collection(){}
void set_sort(SortBehavior* s){
m_sort = s;
}
void set_search(SearchBehavior* s){
m_search = s;
}
void sort() const {
m_sort->sort();
}
void search() const {
m_search->search();
}
};

=====================================================================
Decorator Pattern
=====================================================================
Attach additional responsibilities to an object dynamically.
Decorators provide flexible alternatives to subclassing for extending functional
ity.
Let's take a look at code with the class diagram.
Each component (Window) can be used on its own, or wrapped by decorator.
The ConcreteComponent (SimpleWindow) is the object we're going to dynamically ad
d new behavior (vertical/horizontal scrollbars) to. It inherits Component.
class SimpleWindow : public Window
Each decorator has-a (wraps) a component, which means the decorator has an insta
nce variable that holds a pointer to a component.
class WindowDecorator : public Window
{
protected:
Window *m_decoratedWindow;
...
Decorators implement the same interface or abstract class as the component they
are going to decorate.
The ConcreteDecorator has an instance variable for the thing it decorate (the Co
mponent the Decorator wraps).

class VerticalScrollBarDecorator : public WindowDecorator


{
public:
VerticalScrollBarDecorator (Window *decoratedWindow):
WindowDecorator(decoratedWindow) {}
void draw() {
drawVerticalScrollBar();
m_decoratedWindow->draw();
}
string getDescription() {
return m_decoratedWindow->getDescription() + "with vertical scrollbars\n
";
}
};
#include <iostream>
using namespace std;
// 1. "lowest common denominator"
class Widget
{
public:
virtual void draw() = 0;
};
class TextField: public Widget
{
// 3. "Core" class & "is a"
int width, height;
public:
TextField(int w, int h)
{
width = w;
height = h;
}
/*virtual*/
void draw()
{
cout << "TextField: " << width << ", " << height << '\n';
}
};
// 2. 2nd level base class
class Decorator: public Widget // 4. "is a" relationship
{
Widget *wid; // 4. "has a" relationship
public:
Decorator(Widget *w)
{
wid = w;
}
void draw()
{
wid->draw(); // 5. Delegation
}

};
class BorderDecorator: public Decorator
{
public:
// 6. Optional embellishment
BorderDecorator(Widget *w): Decorator(w){}
/*virtual*/
void draw()
{
// 7. Delegate to base class and add extra stuff
Decorator::draw();
cout << " BorderDecorator" << '\n';
}
};
int main()
{
// 8. Client has the responsibility to compose desired configurations
Widget *aWidget = new BorderDecorator(new BorderDecorator(new ScrollDecorator
(new TextField(80, 24))));
aWidget->draw();
}

===========================================================================
Observer Pattern
===========================================================================
Observer Pattern's intent is to define a one-to-many dependency between objects
so that when one object changes state,
all its dependants are notified and updated automatically.
The subject and observers define the one-to-many relationship. The observers are
dependent on the subject
such that when the subject's state changes, the observers get notified. Dependin
g on the notification,
the observers may also be updated with new values.
class Subject;
class Observer
{
public:
Observer() {};
~Observer() {};
virtual void Update(Subject* theChangeSubject) = 0;
};
class Subject
{
public:
Subject() {};
virtual ~Subject() {};
virtual void Attach(Observer*);
virtual void Detach(Observer*);
virtual void Notify();
private:
vector<Observer*> _observers;
};

void Subject::Attach (Observer* o)


{
_observers.push_back(o);
}
void Subject::Detach (Observer* o)
{
int count = _observers.size();
int i;
for (i = 0; i < count; i++) {
if(_observers[i] == o)
break;
}
if(i < count)
_observers.erase(_observers.begin() + i);
}
void Subject::Notify ()
{
int count = _observers.size();
for (int i = 0; i < count; i++)
(_observers[i])->Update(this);
}
class ClockTimer : public Subject
{
public:
ClockTimer() { _strtime( tmpbuf ); };
int GetHour();
int GetMinute();
int GetSecond();
void Tick();
private:
char tmpbuf[128];
};
/* Set time zone from TZ environment variable. If TZ is not set,
* the operating system is queried to obtain the default value
* for the variable.
*/
void ClockTimer::Tick()
{
Notify();
}
int ClockTimer::GetHour()
{
}
int ClockTimer::GetMinute()
{
}
int ClockTimer::GetSecond()
{
}
class DigitalClock: public Observer
{
public:

DigitalClock(ClockTimer *);
~DigitalClock();
void Update(Subject *);
void Draw();
private:
ClockTimer *_subject;
};
DigitalClock::DigitalClock (ClockTimer *s)
{
_subject = s;
_subject->Attach(this);
}
void DigitalClock::Update (Subject *theChangedSubject)
{
if(theChangedSubject == _subject)
Draw();
}
void
{
int
int
int

DigitalClock::Draw ()
hour = _subject->GetHour();
minute = _subject->GetMinute();
second = _subject->GetSecond();

cout << "Digital time is " << hour << ":"


<< minute << ":"
<< second << endl;
}

OO Principles :
------------* Encapsulate what varies.
* Favor compostion over inheritance.
* Program to interface not implementation.
* Strive for loosely coupled designs between objects that interact.
* Classes should be close for modification open for extension.
* Depend on abstraction. Do not depend on concrete classes.
* A class should have only one reason to change.
* Identify the aspects that vary and seperate them from what stays same.
* Depend upon abstraction do not depend on concrete classes.((Abstract)Factory m
ethods)
Association, Aggregation, and Composition :
---------------------------------------* The IS A relationship : Inheritance
Example : Manager is an employee of XYZ limited corporation.
The sentence above specifies that Manager is a type of employee
* The Using relationship: Association
Example : Manager uses a swipe card to enter XYZ premises.
The manager object and the swipe card object use each other but they hav
e their own object life time.
In other words, they can exist without each other. There is no single owner
in this relationship.

* The Using relationship with


Example : Manager has workers
Denotes the same type
ence that one of them is an
owner. But the Worker
ely disconnected from the
Manager object.

Parent: Aggregation
who work under him.
of relationship like association but with a differ
object can have its own life time which is complet

* The Death relationship: Composition


OO Principles :
------------* Encapsulate what varies.
* Favor compostion over inheritance.
* Program to interface not implementation.
* Strive for loosely coupled designs between objects that interact.
* Classes should be close for modification open for extension.
* Depend on abstraction. Do not depend on concrete classes.
* A class should have only one reason to change.
* Identify the aspects that vary and seperate them from what stays same.
Association, Aggregation, and Composition :
---------------------------------------* The IS A relationship : Inheritance
Example : Manager is an employee of XYZ limited corporation.
The sentence above specifies that Manager is a type of employee
* The Using relationship: Association
Example : Manager uses a swipe card to enter XYZ premises.
The manager object and the swipe card object use each other but they hav
e their own object life time.
In other words, they can exist without each other. There is no single owner
in this relationship.
* The Using relationship with
Example : Manager has workers
Denotes the same type
ence that one of them is an
owner. But the Worker
ely disconnected from the
Manager object.

Parent: Aggregation
who work under him.
of relationship like association but with a differ
object can have its own life time which is complet

* The Death relationship: Composition


Example : Manager has the responsibility of ensuring that the project is success
ful.
Manager's salary will be judged based on project success.
1) Manager and the project objects are dependent on each other.
2) The lifetimes of both the objects are the same. In other words, the p
roject will not be successful
if the manager is not good, and the manager will not get good increme
nts if the project has issues.
Basics :
Abstraction
Encapsulation
Polymorphism
Inheritance.

You might also like