Design Patterns - Kamills-12/2143-OOP GitHub Wiki
Design patterns are reusable solutions to common problems in software design. Think of them as templates, you don’t copy/paste them, you use the concept when you face similar problems.
They help you write:
- Clean code
- Stuff that’s easy to maintain or refactor
Type | Purpose |
---|---|
Creational | How objects are created |
Structural | How classes/objects fit together |
Behavioral | How objects interact and communicate |
Let a class decide which subclass to return.
class Enemy {
public:
virtual void attack() = 0;
};
class Goblin : public Enemy {
public:
void attack() override {
cout << "Goblin attacks!" << endl;
}
};
class Troll : public Enemy {
public:
void attack() override {
cout << "Troll smashes!" << endl;
}
};
class EnemyFactory {
public:
static Enemy* createEnemy(string type) {
if (type == "goblin") return new Goblin();
else return new Troll();
}
};
int main() {
Enemy* e = EnemyFactory::createEnemy("goblin");
e->attack(); // Goblin attacks!
delete e;
}
### Singleton:
class GameManager {
private:
static GameManager* instance;
GameManager() {} // private constructor
public:
static GameManager* getInstance() {
if (!instance)
instance = new GameManager();
return instance;
}
void run() {
cout << "Game running..." << endl;
}
};
GameManager* GameManager::instance = nullptr;
### Structural Patterns:
class LegacyPrinter {
public:
void printOld() {
cout << "Printing from old printer." << endl;
}
};
class NewPrinter {
public:
virtual void print() = 0;
};
class PrinterAdapter : public NewPrinter {
LegacyPrinter* legacy;
public:
PrinterAdapter(LegacyPrinter* lp) : legacy(lp) {}
void print() override {
legacy->printOld();
}
};
### Observer:
class Observer {
public:
virtual void update(string message) = 0;
};
class Logger : public Observer {
public:
void update(string message) override {
cout << "[LOG]: " << message << endl;
}
};
class Subject {
vector<Observer*> observers;
public:
void subscribe(Observer* obs) {
observers.push_back(obs);
}
void notify(string msg) {
for (auto obs : observers)
obs->update(msg);
}
};
### Strategy:
class AttackStrategy {
public:
virtual void attack() = 0;
};
class SwordAttack : public AttackStrategy {
public:
void attack() override {
cout << "Swinging sword!" << endl;
}
};
class BowAttack : public AttackStrategy {
public:
void attack() override {
cout << "Shooting arrow!" << endl;
}
};
class Character {
AttackStrategy* strategy;
public:
void setStrategy(AttackStrategy* s) {
strategy = s;
}
void performAttack() {
strategy->attack();
}
};