개념 : 실행 중에 알고리즘을 선택할 수 있는 패턴
특징 : 동일한 작업을 수행하는 여러 알고리즘을 캡슐화, 필요할 때 교체 가능
class Strategy {
public:
virtual void execute() = 0;
virtual ~Strategy() = default;
};
class ConcreteStrategyA : public Strategy {
public:
void execute() override { std::cout << "Strategy A 실행\n"; }
};
class ConcreteStrategyB : public Strategy {
public:
void execute() override { std::cout << "Strategy B 실행\n"; }
};
class Context {
private:
Strategy* strategy;
public:
Context(Strategy* s) : strategy(s) {}
void setStrategy(Strategy* s) { strategy = s; }
void executeStrategy() { strategy->execute(); }
};
// 사용 예
int main() {
ConcreteStrategyA a;
ConcreteStrategyB b;
Context context(&a);
context.executeStrategy(); // Strategy A 실행
context.setStrategy(&b);
context.executeStrategy(); // Strategy B 실행
}
개념 : 내부 구현을 알 필요 없이, 컬렉션(리스트, 배열)의 요소를 순자적으로 접근할 수 있게 하는 패턴
특징 : 자료구조의 순회 방식을 분리하여 독립적으로 관리 가능
std::vector::iteratorclass Iterator {
public:
virtual bool hasNext() = 0;
virtual int next() = 0;
virtual ~Iterator() = default;
};
class ConcreteIterator : public Iterator {
private:
std::vector<int> data;
size_t index;
public:
ConcreteIterator(const std::vector<int>& d) : data(d), index(0) {}
bool hasNext() override { return index < data.size(); }
int next() override { return data[index++]; }
};
// 사용 예
int main() {
std::vector<int> items = {1, 2, 3, 4, 5};
ConcreteIterator iter(items);
while (iter.hasNext()) {
std::cout << iter.next() << " ";
}
}
개념 : 복잡한 객체의 생성을 단계별로 나누고, 최종적으로 조립할 수 있도록 하는 패턴
특징 : 생성자의 매개변수가 많거나, 다양한 조합이 필요한 경우 유용
class Character {
public:
std::string name;
std::string job;
std::string weapon;
void show() {
std::cout << "Name: " << name << ", Job: " << job << ", Weapon: " << weapon << "\n";
}
};
class CharacterBuilder {
protected:
Character character;
public:
CharacterBuilder& setName(const std::string& n) { character.name = n; return *this; }
CharacterBuilder& setJob(const std::string& j) { character.job = j; return *this; }
CharacterBuilder& setWeapon(const std::string& w) { character.weapon = w; return *this; }
Character build() { return character; }
};
// 사용 예
int main() {
Character character = CharacterBuilder().setName("Arthur").setJob("Warrior").setWeapon("Sword").build();
character.show();
}
개념 : 상위 클래스에서알고리즘의 구조(뼈대)를 정의하고, 세부 사항은 하위 클래스에서 구현하는 패턴
특징 : 알고리즘의 순서를 변경하지 않으면서 일부 단계만 재정의 가능
class GameAI {
public:
void execute() {
move();
attack();
retreat();
}
virtual void move() = 0;
virtual void attack() = 0;
virtual void retreat() = 0;
virtual ~GameAI() = default;
};
class OrcAI : public GameAI {
public:
void move() override { std::cout << "오크가 이동한다.\n"; }
void attack() override { std::cout << "오크가 공격한다.\n"; }
void retreat() override { std::cout << "오크가 도망친다.\n"; }
};
// 사용 예
int main() {
OrcAI orc;
orc.execute();
}
개념 : 객체의 상태에 따라 행동이 달라지는 패턴
특징 : if~else 또는 switch~case를 대체하며, 상태를 객체로 캡슐화하여 확장성을 높임
class State {
public:
virtual void handle() = 0;
virtual ~State() = default;
};
class IdleState : public State {
public:
void handle() override { std::cout << "캐릭터가 대기 상태입니다.\n"; }
};
class AttackState : public State {
public:
void handle() override { std::cout << "캐릭터가 공격 중입니다!\n"; }
};
class Character {
private:
State* state;
public:
Character(State* s) : state(s) {}
void setState(State* s) { state = s; }
void act() { state->handle(); }
};
// 사용 예
int main() {
IdleState idle;
AttackState attack;
Character character(&idle);
character.act();
character.setState(&attack);
character.act();
}
개념 : 객체 생성을 캡슐화하는 패턴
특징 : 객체 생성을 클라이언트 코드에서 분리하여 유연성을 높임
class Monster {
public:
virtual void roar() = 0;
virtual ~Monster() = default;
};
class Orc : public Monster {
public:
void roar() override { std::cout << "오크가 으르렁거린다!\n"; }
};
class Goblin : public Monster {
public:
void roar() override { std::cout << "고블린이 비명을 지른다!\n"; }
};
class MonsterFactory {
public:
static Monster* createMonster(const std::string& type) {
if (type == "Orc") return new Orc();
if (type == "Goblin") return new Goblin();
return nullptr;
}
};
// 사용 예
int main() {
Monster* orc = MonsterFactory::createMonster("Orc");
Monster* goblin = MonsterFactory::createMonster("Goblin");
orc->roar();
goblin->roar();
delete orc;
delete goblin;
}