Docs
README
Design Patterns in C++
Table of Contents
Creational Patterns
- •Singleton - Ensure single instance
- •Factory Method - Create objects via interface
- •Abstract Factory - Families of related objects
- •Builder - Step-by-step construction
- •Prototype - Clone existing objects
Structural Patterns
- •Adapter - Convert interfaces
- •Decorator - Add behavior dynamically
- •Facade - Simplify complex systems
- •Composite - Tree structures
- •Proxy - Control access
Behavioral Patterns
- •Observer - Notify on state changes
- •Strategy - Interchangeable algorithms
- •Command - Encapsulate actions
- •State - State-dependent behavior
- •Template Method - Algorithm skeleton
Creational Patterns
Singleton
class Singleton {
static Singleton* instance;
Singleton() {} // Private constructor
public:
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
static Singleton* getInstance() {
if (!instance) {
instance = new Singleton();
}
return instance;
}
};
Singleton* Singleton::instance = nullptr;
// Thread-safe (C++11+)
class ThreadSafeSingleton {
public:
static ThreadSafeSingleton& getInstance() {
static ThreadSafeSingleton instance;
return instance;
}
private:
ThreadSafeSingleton() = default;
};
Factory Method
class Product {
public:
virtual void use() = 0;
virtual ~Product() = default;
};
class ConcreteProductA : public Product {
public:
void use() override { cout << "Using A" << endl; }
};
class ConcreteProductB : public Product {
public:
void use() override { cout << "Using B" << endl; }
};
class Creator {
public:
virtual unique_ptr<Product> create() = 0;
virtual ~Creator() = default;
};
class CreatorA : public Creator {
public:
unique_ptr<Product> create() override {
return make_unique<ConcreteProductA>();
}
};
Abstract Factory
// Abstract products
class Button { public: virtual void render() = 0; };
class Checkbox { public: virtual void render() = 0; };
// Concrete products
class WinButton : public Button {
void render() override { cout << "Windows Button" << endl; }
};
class MacButton : public Button {
void render() override { cout << "Mac Button" << endl; }
};
// Abstract factory
class GUIFactory {
public:
virtual unique_ptr<Button> createButton() = 0;
virtual unique_ptr<Checkbox> createCheckbox() = 0;
};
// Concrete factories
class WinFactory : public GUIFactory {
unique_ptr<Button> createButton() override {
return make_unique<WinButton>();
}
// ...
};
Builder
class Product {
public:
string partA, partB, partC;
};
class Builder {
protected:
Product product;
public:
virtual Builder& buildPartA() = 0;
virtual Builder& buildPartB() = 0;
virtual Builder& buildPartC() = 0;
Product getResult() { return product; }
};
class ConcreteBuilder : public Builder {
public:
Builder& buildPartA() override {
product.partA = "A";
return *this;
}
Builder& buildPartB() override {
product.partB = "B";
return *this;
}
Builder& buildPartC() override {
product.partC = "C";
return *this;
}
};
// Usage
ConcreteBuilder builder;
Product p = builder.buildPartA().buildPartB().getResult();
Prototype
class Prototype {
public:
virtual unique_ptr<Prototype> clone() const = 0;
virtual ~Prototype() = default;
};
class ConcretePrototype : public Prototype {
int value;
public:
ConcretePrototype(int v) : value(v) {}
unique_ptr<Prototype> clone() const override {
return make_unique<ConcretePrototype>(*this);
}
};
Structural Patterns
Adapter
// Old interface
class OldSystem {
public:
void specificRequest() { cout << "Old system" << endl; }
};
// Target interface
class Target {
public:
virtual void request() = 0;
};
// Adapter
class Adapter : public Target {
OldSystem old;
public:
void request() override { old.specificRequest(); }
};
Decorator
class Component {
public:
virtual string operation() = 0;
virtual ~Component() = default;
};
class ConcreteComponent : public Component {
public:
string operation() override { return "Component"; }
};
class Decorator : public Component {
protected:
unique_ptr<Component> component;
public:
Decorator(unique_ptr<Component> c) : component(move(c)) {}
string operation() override { return component->operation(); }
};
class ConcreteDecorator : public Decorator {
public:
using Decorator::Decorator;
string operation() override {
return "Decorated(" + Decorator::operation() + ")";
}
};
// Usage
auto c = make_unique<ConcreteComponent>();
auto d = make_unique<ConcreteDecorator>(move(c));
cout << d->operation(); // "Decorated(Component)"
Facade
class SubsystemA { public: void operationA() {} };
class SubsystemB { public: void operationB() {} };
class SubsystemC { public: void operationC() {} };
class Facade {
SubsystemA a;
SubsystemB b;
SubsystemC c;
public:
void simpleOperation() {
a.operationA();
b.operationB();
c.operationC();
}
};
Composite
class Component {
public:
virtual void operation() = 0;
virtual void add(shared_ptr<Component>) {}
virtual ~Component() = default;
};
class Leaf : public Component {
public:
void operation() override { cout << "Leaf" << endl; }
};
class Composite : public Component {
vector<shared_ptr<Component>> children;
public:
void add(shared_ptr<Component> c) override { children.push_back(c); }
void operation() override {
for (auto& child : children) child->operation();
}
};
Proxy
class Subject {
public:
virtual void request() = 0;
};
class RealSubject : public Subject {
public:
void request() override { cout << "RealSubject" << endl; }
};
class Proxy : public Subject {
unique_ptr<RealSubject> real;
public:
void request() override {
if (!real) real = make_unique<RealSubject>();
cout << "Proxy: ";
real->request();
}
};
Behavioral Patterns
Observer
class Observer {
public:
virtual void update(int state) = 0;
virtual ~Observer() = default;
};
class Subject {
vector<Observer*> observers;
int state;
public:
void attach(Observer* o) { observers.push_back(o); }
void setState(int s) {
state = s;
for (auto* o : observers) o->update(state);
}
};
class ConcreteObserver : public Observer {
public:
void update(int state) override {
cout << "State changed to: " << state << endl;
}
};
Strategy
class Strategy {
public:
virtual int execute(int a, int b) = 0;
virtual ~Strategy() = default;
};
class AddStrategy : public Strategy {
public:
int execute(int a, int b) override { return a + b; }
};
class MultiplyStrategy : public Strategy {
public:
int execute(int a, int b) override { return a * b; }
};
class Context {
unique_ptr<Strategy> strategy;
public:
void setStrategy(unique_ptr<Strategy> s) { strategy = move(s); }
int execute(int a, int b) { return strategy->execute(a, b); }
};
Command
class Command {
public:
virtual void execute() = 0;
virtual ~Command() = default;
};
class Receiver {
public:
void action() { cout << "Action performed" << endl; }
};
class ConcreteCommand : public Command {
Receiver& receiver;
public:
ConcreteCommand(Receiver& r) : receiver(r) {}
void execute() override { receiver.action(); }
};
class Invoker {
unique_ptr<Command> command;
public:
void setCommand(unique_ptr<Command> c) { command = move(c); }
void invoke() { command->execute(); }
};
State
class State {
public:
virtual void handle() = 0;
virtual ~State() = default;
};
class StateA : public State {
public:
void handle() override { cout << "State A" << endl; }
};
class StateB : public State {
public:
void handle() override { cout << "State B" << endl; }
};
class Context {
unique_ptr<State> state;
public:
void setState(unique_ptr<State> s) { state = move(s); }
void request() { state->handle(); }
};
Template Method
class AbstractClass {
public:
void templateMethod() {
step1();
step2();
step3();
}
protected:
virtual void step1() = 0;
virtual void step2() = 0;
void step3() { cout << "Step 3 (common)" << endl; }
};
class ConcreteClass : public AbstractClass {
protected:
void step1() override { cout << "Step 1" << endl; }
void step2() override { cout << "Step 2" << endl; }
};
Quick Reference
| Pattern | Purpose | Key Feature |
|---|---|---|
| Singleton | One instance only | Static instance |
| Factory | Create objects | Virtual creation |
| Builder | Complex construction | Step-by-step |
| Adapter | Interface conversion | Wrapper |
| Decorator | Add behavior | Wrapping chain |
| Observer | Event notification | Subject/observers |
| Strategy | Interchangeable algorithms | Runtime selection |
| Command | Encapsulate request | Action objects |
| State | State-dependent behavior | State objects |
Compile & Run
g++ -std=c++17 -Wall examples.cpp -o examples && ./examples