내배캠/C++

디자인 패턴(Factory Pattern)

동그래님 2025. 1. 20. 20:12

Factory Pattern

  • 객체 생성 로직을 클라이언트 코드로부터 분리시켜 캡슐화 하는 데 초점을 맞춘 디자인 패턴이다.
  • 클라이언트는 생성 과정의 세부 사항을 몰라도 팩토리 메서드를 통해 객체를 생성할 수 있게 한다.

 

텍스트 RPG를 만드는 과정 중에 Enemy 객체를 생성하는 로직을 전투를 관리하는 BattleManager 클래스로부터 분리하고자 이 팩토리 패턴을 사용하였다.

 

// 인터페이스
class IMonsterFactory
{
public:
    virtual ~IMonsterFactory() = default;
    virtual unique_ptr<BaseMonster> CreateMonster(const int& PlayerLevel) const = 0;
};

// 고블린 팩토리
class GoblinFactory : public IMonsterFactory
{
public:
    std::unique_ptr<BaseMonster> CreateMonster(const int& PlayerLevel) const override
    {
        return make_unique<Goblin>("고블린", PlayerLevel);
    }
};

// 오크 팩토리
class OrcFactory : public IMonsterFactory
{
public:
    unique_ptr<BaseMonster> CreateMonster(const int& PlayerLevel) const override
    {
        return make_unique<Orc>("오크", PlayerLevel);
    }
};

// 슬라임 팩토리
class SlimeFactory : public IMonsterFactory
{
public:
    unique_ptr<BaseMonster> CreateMonster(const int& PlayerLevel) const override
    {
        return make_unique<Slime>("슬라임", PlayerLevel);
    }
};

// 트롤 팩토리
class TrollFactory : public IMonsterFactory
{
public:
    unique_ptr<BaseMonster> CreateMonster(const int& PlayerLevel) const override
    {
        return make_unique<Troll>("트롤", PlayerLevel);
    }
};

// 보스 몬스터 팩토리
class BossMonsterFactory : public IMonsterFactory
{
public:
    unique_ptr<BaseMonster> CreateMonster(const int& PlayerLevel) const override
    {
        return make_unique<BossMonster>("레드 드래곤", PlayerLevel);
    }
};

 

  • 모든 몬스터 팩토리 클래스가 구현해야 하는 공통 인터페이스를 정의
  • 각 몬스터의 생성 로직을 담당하는 팩토리 클래스를 정의했고, 만약 몬스터 타입이 증가하게 되면 새로운 팩토리 클래스를 정의하면 되도록 했다.

 

 

// 팩토리 매니저
class EnemyFactory
{
public:
    static std::unique_ptr<BaseMonster> CreateBasicMonster(const int& PlayerLevel)
    {
        MonsterType Type = GetRandomMonsterType();

        switch (Type)
        {
        case GOBLIN:
            return GoblinFactory().CreateMonster(PlayerLevel);
        case ORC:
            return OrcFactory().CreateMonster(PlayerLevel);
        case SLIME:
            return SlimeFactory().CreateMonster(PlayerLevel);
        case TROLL:
            return TrollFactory().CreateMonster(PlayerLevel);
        default:
            throw std::runtime_error("== 기본 몬스터 타입, 오류 발생 ==");
        }
    }

    static std::unique_ptr<BaseMonster> CreateBossMonster(const int& PlayerLevel)
    {
        return BossMonsterFactory().CreateMonster(PlayerLevel);
    }

private:
    static MonsterType GetRandomMonsterType()
    {
        int RandomValue = rand() % 4;
        return static_cast<MonsterType>(RandomValue);
    }
};
  • 인터페이스 기반으로 몬스터 객체를 생성
  • 팩토리 메서드는 특정 클래스의 객체를 생성하는 역할만 하므로 별도의 인스턴스 없이 호출할 수 있는 static 메서드로 정의하였다.
  • 이로 인해 불필요한 메모리 낭비 방지 및 호출이 간단해졌다.