0% found this document useful (0 votes)
6 views17 pages

Behavioral Design Patterns

The document outlines various behavioral design patterns in programming, including Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, and Strategy. Each pattern is described with its purpose, implementation details, and example code in C++. The document provides a concise overview of how these patterns facilitate object interaction and state management in software design.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views17 pages

Behavioral Design Patterns

The document outlines various behavioral design patterns in programming, including Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, and Strategy. Each pattern is described with its purpose, implementation details, and example code in C++. The document provides a concise overview of how these patterns facilitate object interaction and state management in software design.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

DESIGN PATTERNS :

3. BECHAVIORAL PATTERNS:
1. Chain of Responsibility
- Passes a request along a chain of potential handlers.
- Each handler either processes the request or forwards it to the next
handler.
#include <iostream>
using namespace std;

// Abstract Handler — holds the next handler in the chain


class Handler {
protected:
Handler* next = nullptr; // Pointer to the next handler
public:
void setNext(Handler* n) { next = n; } // Method to link handlers
virtual void handle(int req) { // Default handle method
if (next) next->handle(req); // If there's a next handler,
forward the request
}
};

// Concrete Handler 1 — handles request “1”


class Level1 : public Handler {
public:
void handle(int req) override {
if (req == 1) cout << "Level 1 handled\n";
else Handler::handle(req); // Call base class method to
forward
}
};

// Concrete Handler 2 — handles request “2”


class Level2 : public Handler {
public:
void handle(int req) override {
if (req == 2) cout << "Level 2 handled\n";
else Handler::handle(req); // Forward if not handled
}
};

int main() {
Level1 h1; Level2 h2;
[Link](&h2); // Build the chain: h1 → h2
[Link](1); // “Level 1 handled”
[Link](2); // “Level 2 handled”
return 0;
}

 `Handler` class: abstract base that holds a `next` pointer to the


next handler and a `setNext` method to link handlers. The virtual
`handle(int req)` method forwards the request if `next` exists.
 `Level1` & `Level2`: concrete handlers overriding `handle`. They
check if `req` matches their responsibility; if not, they call the base
`Handler::handle(req)` to forward it.
 `main()`: Instantiates two concrete handlers, links them into a
chain (`[Link](&h2)`), then sends requests to the first handler
— the appropriate level prints the message.
2. Command
- Encapsulates a request as an object, allowing parameterization and
queuing of requests.
- Decouples the invoker (who issues the command) from the receiver
(who performs the action).
#include <iostream>
using namespace std;

// Receiver — the actual object that performs the action


class Light {
public:
void on() { cout << "Light ON\n"; }
void off() { cout << "Light OFF\n"; }
};
// Abstract Command — declares the execute method
class Command {
public:
virtual void execute() = 0;
};

// Concrete Command — turns light on


class OnCommand : public Command {
Light& light; // Reference to the receiver
public:
OnCommand(Light& l) : light(l) {}
void execute() override { [Link](); } // Calls receiver’s on()
};

// Concrete Command — turns light off


class OffCommand : public Command {
Light& light;
public:
OffCommand(Light& l) : light(l) {}
void execute() override { [Link](); } // Calls receiver’s off()
};

// Invoker — triggers the command


class Remote {
Command* cmd; // Holds a command object
public:
void setCommand(Command* c) { cmd = c; } // Sets the command to
execute
void press() { cmd->execute(); } // Executes the command
};

int main() {
Light lamp; // Create the receiver
Remote remote; // Create the invoker

[Link](new OnCommand(lamp)); // Set “on”


command
[Link](); // “Light ON”
[Link](new OffCommand(lamp)); // Set “off”
command
[Link](); // “Light OFF”
return 0;
}

 `Light` (Receiver): contains the actual operations (`on`, `off`).


 `Command` (Abstract Command): declares a pure virtual
`execute()` method.
 `OnCommand` & `OffCommand` (Concrete Commands): store a
reference to the `Light` receiver and implement `execute()` by
calling the appropriate receiver method.
 `Remote` (Invoker): holds a `Command*` pointer, `setCommand`
assigns a command, `press` calls `execute` on the stored
command.
 `main()`: Instantiates `Light` and `Remote`, creates concrete
commands, assigns them to the remote, and simulates button
presses.
3. Interpreter
- Defines a simple grammar and interprets sentences using a tree of
expression objects.
#include <iostream>
using namespace std;

// Abstract Expression — declares the interpret method


class Expression {
public:
virtual int interpret() = 0;
};

// Terminal Expression — a number


class Number : public Expression {
int value;
public:
Number(int v) : value(v) {}
int interpret() override { return value; } // Returns the number itself
};

// Non-terminal Expression — addition of two expressions


class Add : public Expression {
Expression *left, *right; // Child expressions
public:
Add(Expression* l, Expression* r) : left(l), right(r) {}
int interpret() override {
return left->interpret() + right->interpret(); // Recursively interpret
children
}
};

int main() {
Expression* expr = new Add(new Number(5), new Number(3)); //
Build expression tree “5 + 3”
cout << "Result: " << expr->interpret() << endl; // “Result: 8”
return 0;
}

 `Expression` – abstract class; pure virtual `interpret()`.


 `Number` – terminal; stores `int value`; `interpret()` returns value.
 `Add` – non-terminal; holds two `Expression*`; `interpret()` returns sum
of child `interpret()`.
 `main()` – builds tree `Add(Number(5), Number(3))`; calls `interpret()` →
prints “Result: 8”.

[Link]
#include <iostream>
#include <vector>
using namespace std;

// Iterator interface
class Iterator {
public:
virtual int next() = 0;
virtual bool hasNext() = 0;
};

// Concrete Iterator for vector<int>


class NumberIterator : public Iterator {
vector<int> nums;
int pos = 0;
public:
NumberIterator(vector<int> n) : nums(n) {}
int next() override { return nums[pos++]; }
bool hasNext() override { return pos < [Link](); }
};

// Client usage
int main() {
vector<int> numbers = {1, 2, 3};
Iterator* it = new NumberIterator(numbers);
while (it->hasNext()) cout << it->next() << " ";
cout << endl;
delete it;
return 0;
}
 `Iterator` — a basic “interface” that says “you can ask if there’s a next
item (`hasNext`) and get the next item (`next`).”
 `NumberIterator` — the actual “iterator” that knows about the
`vector<int>` and keeps track of which item comes next.
 `main()` — creates a list of numbers, makes a `NumberIterator` for it,
then loops: while `hasNext()` is true, calls `next()` to get each number
and prints it.
5. Mediator
- Defines an object (the mediator) that encapsulates how a set of objects
(colleagues) interact.
- Colleagues communicate only through the mediator, reducing direct
dependencies.
#include <iostream>
#include <string>
using namespace std;
// Abstract Mediator — declares a send method
class Mediator {
public:
virtual void send(string msg, class Colleague* sender) = 0;
};

// Abstract Colleague — holds a reference to the mediator


class Colleague {
protected:
Mediator* mediator;
public:
Colleague(Mediator* m) : mediator(m) {}
virtual void send(string msg) = 0;
virtual void receive(string msg) = 0;
};

// Concrete Mediator — implements communication logic


class ConcreteMediator : public Mediator {
Colleague *c1, *c2; // The two colleagues it mediates
public:
void set(Colleague* a, Colleague* b) { c1 = a; c2 = b; }
void send(string msg, Colleague* sender) override {
if (sender == c1) c2->receive(msg);
else c1->receive(msg);
}
};

// Concrete Colleague — a person who can send/receive messages


class Person : public Colleague {
string name;
public:
Person(Mediator* m, string n) : Colleague(m), name(n) {}
void send(string msg) override { mediator->send(msg, this); }
void receive(string msg) override { cout << name << " got: " << msg <<
endl; }
};
int main() {
ConcreteMediator m;
Person p1(&m, "Alice"), p2(&m, "Bob");
[Link](&p1, &p2); // Register colleagues with the
mediator
[Link]("Hi Bob!"); // “Bob got: Hi Bob!”
[Link]("Hello Alice!"); // “Alice got: Hello Alice!”
return 0;
}

 `Mediator` abstract class declares `send(string, Colleague*)`.


 `Colleague` base class stores a `Mediator*` and declares
`send`/`receive` methods.
 `ConcreteMediator` implements `send`: it forwards the message
from the sender to the other colleague.
 `Person` (Concrete Colleague) implements `send` (calls mediator’s
`send`) and `receive` (prints the message).
 `main()` creates a mediator, two `Person` objects, registers them
with the mediator, and demonstrates message exchange without
direct coupling.
6. Memento
- Captures an object’s internal state without exposing its
implementation, allowing later restoration.
#include <iostream>
using namespace std;

// Memento — stores the originator’s internal state


class Memento {
public:
int state;
Memento(int s) : state(s) {}
};

// Originator — creates and restores mementos


class Originator {
int state; // Internal state
public:
void set(int s) { state = s; }
Memento save() { return Memento(state); }// Create memento with
current state
void restore(Memento m) { state = [Link]; } // Restore from
memento
int getState() { return state; }
};

int main() {
Originator o;
[Link](10);
Memento m = [Link](); // Save state “10”
[Link](20);
[Link](m); // Restore to “10”
cout << [Link]() << endl; // “10”
return 0;
}

 `Memento` is a simple storage class holding the `state` of the


originator.
 `Originator` has an internal `state`, `save()` returns a `Memento` with
the current state, `restore(Memento)` sets the state from a
memento.
 `main()` demonstrates setting a state, saving it, changing the state,
then restoring the saved state — output “10”.
7. Observer
- Defines a one-to-many dependency so that when one object changes
state, all dependents are notified.
#include <iostream>
#include <vector>
using namespace std;

// Observer interface — declares update method


class Observer {
public:
virtual void update(string news) = 0;
};
// Subject — maintains a list of observers and notifies them
class Subject {
vector<Observer*> obs;
string news;
public:
void attach(Observer* o) { obs.push_back(o); } // Add observer
void setNews(string n) { news = n; notify(); } // Change state & notify
void notify() {
for (auto o : obs) o->update(news); // Notify all observers
}
};

// Concrete Observer — a reader


class Reader : public Observer {
string name;
public:
Reader(string n) : name(n) {}
void update(string news) override { cout << name << " reads: " <<
news << endl; }
};

int main() {
Subject agency;
Reader r1("Alice"), r2("Bob");
[Link](&r1); [Link](&r2); // Register observers
[Link]("New Pattern!"); // “Alice reads: New Pattern!”
“Bob reads: New Pattern!”
return 0;
}

 `Observer` abstract class declares `update(string)`.


 `Subject` holds a `vector<Observer*>`, `attach` adds observers,
`setNews` changes state and calls `notify` which calls `update` on
each observer.
 `Reader` (Concrete Observer) implements `update` to print the
news.
 `main()` creates a `Subject` (news agency), attaches two `Reader`
observers, then changes news — both readers receive the update.
8. State
- Allows an object to alter its behavior when its internal state changes;
appears to change its class.
#include <iostream>
using namespace std;

// Abstract State — declares a handle method


class State {
public:
virtual void handle() = 0;
};

// Concrete States — Red and Green


class Red : public State {
public:
void handle() override { cout << "Red\n"; }
};
class Green : public State {
public:
void handle() override { cout << "Green\n"; }
};

// Context — maintains a current state


class Context {
State* state;
public:
Context() : state(new Red()) {} // Initial state
void setState(State* s) { state = s; } // Change state
void request() { state->handle(); } // Delegate to current state
};

int main() {
Context traffic;
[Link](); // “Red”
[Link](new Green());
[Link](); // “Green”
return 0;
}

 `State` abstract class declares `handle()`.


 `Red` & `Green` concrete states implement `handle()` to print the
light color.
 `Context` holds a `State*` pointer, `request()` delegates the call to
the current state’s `handle()`. `setState` changes the internal
state.
 `main()` creates a `Context` (initially Red), calls `request` to display
“Red”, changes state to `Green` and calls `request` again — now
“Green”.
9. Strategy
- Encapsulates interchangeable algorithms; lets the client choose the
algorithm at runtime.
#include <iostream>
using namespace std;

// Abstract Strategy — declares a calculation method


class Strategy {
public:
virtual int calc(int a, int b) = 0;
};

// Concrete Strategies — Addition and Multiplication


class Add : public Strategy {
public:
int calc(int a, int b) override { return a + b; }
};
class Multiply : public Strategy {
public:
int calc(int a, int b) override { return a * b; }
};

// Context — uses a strategy to perform calculation


class Context {
Strategy* strategy;
public:
void setStrategy(Strategy* s) { strategy = s; } // Set the strategy
int execute(int a, int b) { return strategy->calc(a, b); } // Call strategy’s
calc
};

int main() {
Context c;
[Link](new Add());
cout << [Link](3, 4) << endl; // “7”
[Link](new Multiply());
cout << [Link](3, 4) << endl; // “12”
return 0;
}
 `class Strategy` — abstract “Strategy” base class; declares pure virtual
`virtual int calc(int a, int b) = 0`.
 `class Add : public Strategy` — concrete strategy; implements `calc()` to
return `a + b`.
 `class Multiply : public Strategy` — concrete strategy; implements `calc()` to
return `a * b`.

 `class Context` — context class that holds a `Strategy*`.


 `void setStrategy(Strategy* s)` — sets the current strategy object.
 `int execute(int a, int b)` — delegates the calculation to the current
strategy’s `calc()` method.

 `int main()` — client code:


 Creates a `Context` object `c`.
 Sets `Add` strategy, calls `execute(3, 4)` → outputs `7`.
 Sets `Multiply` strategy, calls `execute(3, 4)` → outputs `12`.
10. Template Method
- Defines the skeleton of an algorithm in a base class, letting subclasses
override specific steps without changing the overall structure.
- The “template” method calls primitive operations that can be
overridden by derived classes.
#include <iostream>
using namespace std;

// Abstract Class — defines the template method


class Game {
public:
// Template method — the overall algorithm skeleton
void play() {
initialize(); // Step 1 (abstract)
startPlay(); // Step 2 (abstract)
endPlay(); // Step 3 (concrete)
}
protected:
virtual void initialize() = 0; // Primitive operation — must be
overridden
virtual void startPlay() = 0; // Primitive operation — must be
overridden
void endPlay() { // Concrete operation — common to all
games
cout << "Game Over\n";
}
};

// Concrete Class — implements the abstract steps


class Football : public Game {
protected:
void initialize() override { cout << "Football init\n"; }
void startPlay() override { cout << "Football started\n"; }
};

int main() {
Game* game = new Football(); // Pointer to abstract base
game->play(); // Calls the template method
// Output:
// Football init
// Football started
// Game Over
delete game;
return 0;
}
 `Game` (abstract class) defines the `play()` template method that calls three
steps: `initialize()`, `startPlay()`, and `endPlay()`.
 `initialize()` and `startPlay()` are pure virtual — subclasses must implement
them.
 `endPlay()` is a concrete method provided by the base class; it’s the same
for all games.
 `Football` (concrete class) implements the two abstract steps.
 In `main()`, a `Football` object is treated as a `Game*`; calling `play()`
executes the fixed algorithm while using the subclass-specific steps.
11. Visitor
- Separates an algorithm from the object structure it operates on.
- Allows adding new operations to existing classes without modifying
them — “double-dispatch” achieved via `accept(Visitor*)` in elements.
#include <iostream>
#include <vector>
using namespace std;

// Forward declaration — needed because Element depends on Visitor


class Visitor;

// Abstract Element — declares accept method


class Animal {
public:
virtual void accept(Visitor* v) = 0; // Accepts a visitor
};

// Concrete Elements
class Dog : public Animal {
public:
void accept(Visitor* v) override; // Definition after Visitor defined
string sound() { return "Woof"; }
};
class Cat : public Animal {
public:
void accept(Visitor* v) override; // Definition after Visitor defined
string sound() { return "Meow"; }
};

// Abstract Visitor — declares visit methods for each element type


class Visitor {
public:
virtual void visit(Dog* d) = 0;
virtual void visit(Cat* c) = 0;
};

// Concrete Visitor — prints the animal sound


class SoundPrinter : public Visitor {
public:
void visit(Dog* d) override { cout << d->sound() << endl; }
void visit(Cat* c) override { cout << c->sound() << endl; }
};

// Define accept methods now that Visitor is fully declared


void Dog::accept(Visitor* v) { v->visit(this); }
void Cat::accept(Visitor* v) { v->visit(this); }

int main() {
vector<Animal*> animals = { new Dog(), new Cat() };
SoundPrinter printer;

for (Animal* a : animals) {


a->accept(&printer); // “Woof” then “Meow”
}

for (auto a : animals) delete a;


return 0;
}
 `Animal` (abstract element) declares `accept(Visitor*)`.
 `Dog` and `Cat` (concrete elements) implement `accept` by calling the
appropriate `visit` method on the `Visitor` — this is the “double-dispatch”
mechanism.
 `Visitor` abstract class declares `visit` methods for each concrete element
type.
 `SoundPrinter` (concrete visitor) implements `visit(Dog*)` and `visit(Cat*)`
to print each animal’s sound.
 In `main()`, a collection of `Animal*` is iterated; each element calls `accept`
on the `SoundPrinter` visitor, which internally calls the correct `visit`
method — printing “Woof” and “Meow” without modifying the animal
classes.

You might also like