상태 패턴(State Pattern) vs 전략 패턴(Strategy Pattern)

jelly·2025년 3월 4일
  1. 상태 패턴 (State Pattern)
    객체의 상태에 따라 동작이 변경되는 경우 사용
    객체가 현재 상태를 저장하고 있으며, 상태가 바뀌면 해당 상태에 맞는 동작을 수행
    예제: 몬스터 AI에서 공격, 도망, 순찰 등의 상태를 갖고 있고, 상태에 따라 행동이 변함
  2. 전략 패턴 (Strategy Pattern)
    행동(알고리즘)을 변경 가능하도록 캡슐화하여 동적으로 교체할 수 있도록 하는 패턴
    같은 동작을 다양한 방식으로 수행해야 할 때 유용
    예제: 몬스터 AI가 근접 공격, 원거리 공격, 마법 공격 등 다양한 공격 방식을 가질 때 사용
    예제 코드 (C++)
  3. 상태 패턴 예제 (Monster AI)
#include <iostream>
#include <memory>

// 상태 인터페이스
class MonsterState {
public:
    virtual ~MonsterState() = default;
    virtual void Handle() = 0;
};

// 상태 구현: 공격 상태
class AttackState : public MonsterState {
public:
    void Handle() override {
        std::cout << "몬스터가 공격한다!\n";
    }
};

// 상태 구현: 도망 상태
class FleeState : public MonsterState {
public:
    void Handle() override {
        std::cout << "몬스터가 도망친다!\n";
    }
};

// 몬스터 클래스 (현재 상태를 저장)
class Monster {
private:
    std::unique_ptr<MonsterState> state;
public:
    void SetState(std::unique_ptr<MonsterState> newState) {
        state = std::move(newState);
    }
    
    void Act() {
        if (state) state->Handle();
    }
};

// 실행 예제
int main() {
    Monster monster;
    
    monster.SetState(std::make_unique<AttackState>());
    monster.Act(); // "몬스터가 공격한다!"
    
    monster.SetState(std::make_unique<FleeState>());
    monster.Act(); // "몬스터가 도망친다!"
    
    return 0;
}

✅ 설명
MonsterState 인터페이스를 만들고, AttackState, FleeState 등 다양한 상태를 구현
Monster 객체는 현재 상태를 저장하고 있으며 SetState() 로 상태를 변경 가능
Act()를 호출하면 현재 상태의 Handle() 함수가 실행됨

  1. 전략 패턴 예제 (공격 방식 선택)
#include <iostream>
#include <memory>

// 공격 전략 인터페이스
class AttackStrategy {
public:
    virtual ~AttackStrategy() = default;
    virtual void Attack() = 0;
};

// 전략 구현: 근접 공격
class MeleeAttack : public AttackStrategy {
public:
    void Attack() override {
        std::cout << "근접 공격을 한다!\n";
    }
};

// 전략 구현: 원거리 공격
class RangedAttack : public AttackStrategy {
public:
    void Attack() override {
        std::cout << "원거리 공격을 한다!\n";
    }
};

// 전략 구현: 마법 공격
class MagicAttack : public AttackStrategy {
public:
    void Attack() override {
        std::cout << "마법 공격을 시전한다!\n";
    }
};

// 몬스터 클래스 (공격 전략을 가짐)
class Monster {
private:
    std::unique_ptr<AttackStrategy> attackStrategy;
public:
    void SetAttackStrategy(std::unique_ptr<AttackStrategy> strategy) {
        attackStrategy = std::move(strategy);
    }
    
    void PerformAttack() {
        if (attackStrategy) attackStrategy->Attack();
    }
};

// 실행 예제
int main() {
    Monster monster;
    
    monster.SetAttackStrategy(std::make_unique<MeleeAttack>());
    monster.PerformAttack(); // "근접 공격을 한다!"

    monster.SetAttackStrategy(std::make_unique<RangedAttack>());
    monster.PerformAttack(); // "원거리 공격을 한다!"

    monster.SetAttackStrategy(std::make_unique<MagicAttack>());
    monster.PerformAttack(); // "마법 공격을 시전한다!"

    return 0;
}

✅ 설명
AttackStrategy 인터페이스를 만들고, MeleeAttack, RangedAttack, MagicAttack 등의 전략을 구현
Monster 클래스는 특정 공격 전략을 가지며 SetAttackStrategy() 를 사용해 동적으로 전략을 변경 가능
PerformAttack()을 호출하면 현재 설정된 전략의 Attack() 함수가 실행됨

profile
jelly

0개의 댓글