'팩토리 패턴(Factory Pattern)'은 객체 생성 로직을 별도의 '팩토리'(메서드·클래스·인터페이스 등)로 캡슐화하여, 클라이언트 코드가 특정 구체 클래스에 직접 의존하지 않도록 하는 생성(Creational) 디자인 패턴 계열을 가리킨다.
대표적인 종류
- Factory Method 패턴
- Abstract Factory 패턴
- (확장) Simple Factory(심플 팩토리) 라고 불리는 간단한 변형도 많이 사용됨.
'팩토리 메서드' 패턴은 추상 클래스(또는 인터페이스)가 객체 생성을 위한 추상 메서드(또는 오버라이드 가능한 메서드)를 정의하고, 이 메서드를 자식 클래스에서 오버라이드하여 구체 객체를 생성하도록 하는 구조이다.
즉, 어떤 객체를 생성할지는 하위 클래스에게 위임하므로, 클라이언트는 추상 팩토리 메서드만 알고 있으면 된다
TextApplication vs DrawingApplication), 게임 지역별 몬스터(ForestSpawner vs CaveSpawner) 등Creator)만 두고, 사용자가 커스텀 서브클래스에서 생성 방식을 확장/재정의예) 몬스터 스포너
//구상 Creator 클래스 사용될 인터페이스 & 구현 클래스
class IMonster
{
public:
virtual void Spawn() = 0;
virtual void Attack() = 0;
};
class Slime : public IMonster
{
public:
void Spawn() override
{
cout << "슬라임 스폰" << endl;
}
void Attack() override
{
cout << "질퍽" << endl;
}
};
class Goblin : public IMonster
{
public:
void Spawn() override
{
cout << "고블린 스폰" << endl;
}
void Attack() override
{
cout << "부웅" << endl;
}
};
//추상 Creator 클래스
class MonsterSpawner
{
protected:
virtual IMonster* CreateMonster() = 0; // 팩토리 메서드
public:
void SpawnMonster()
{
IMonster* monster = CreateMonster();
monster->Spawn();
monster->Attack();
}
};
// 구상 Creator 클래스
class ForestSpawner : public MonsterSpawner
{
protected:
virtual IMonster* CreateMonster() override
{
return new Slime();
}
};
class CaveSpawner : public MonsterSpawner
{
protected:
virtual IMonster* CreateMonster() override
{
return new Goblin();
}
};
// 사용
int main()
{
MonsterSpawner* forest = new ForestSpawner();
MonsterSpawner* cave = new CaveSpawner();
forest->SpawnMonster(); // 슬라임이 등장
cave->SpawnMonster(); // 고블린이 등장
}
추상 팩토리 패턴은 서로 연관된(또는 의존 관계가 있는) 복수의 객체를 한꺼번에 생성해야 할 때 사용하는 패턴이다.
예 : Windows UI 세트(WindowsButton + WindowsCheckbox), Mac UI 세트(MacButton + MacCheckbox)처럼서로 호환되는 객체들을 일관되게 만들고 싶을 때 사용
심플 팩토리는 정적 메서드 기반의 간단한 팩토리 기법을 가리킨다.
별도의 팩토리 클래스(또는 팩토리 메서드) 하나만 만들어놓고, CreateXXX() 같은 메서드 내부에서 if-else나 switch를 사용하여 구체 객체를 생성해 반환한다.
class IDocument
{
};
class WordDocument : public IDocument {};
class PdfDocument : public IDocument { };
class DocumentFactory
{
public:
static IDocument* CreateDocument(string type)
{
if (type == "Word")
return new WordDocument();
else if (type == "PDF")
return new PdfDocument();
else
throw exception("Unknown Document Type");
}
};
int main()
{
//사용 시
IDocument* doc1 = DocumentFactory::CreateDocument("Word");
IDocument* doc2 = DocumentFactory::CreateDocument("PDF");
}