추상 팩토리 패턴(Abstract Factory Pattern)
연관성이 있는 제품군(객체 집합)이 여러개 있을 경우 이들을 묶어 추상화하고, 팩토리 클래스에서 집합으로 묶인 제품군을 생성하는 생성 패턴의 일종
ㅡ> 복잡하게 분류되는 제품군들을 관리하고 확장하는데 용이
ex) 갤럭시 스마트폰 + 갤럭시 탭 + 갤럭시 워치 vs. 아이폰 + 아이패드 + 애플 워치 와 같은 제품군을 생성 가능
추상 팩토리 패턴 구조
- AbstractFactory : 최상위 공장 클래스. 인터페이스에 해당하며 여러개의 제품들을 생성하는 여러 메소드들을 추상화
- ConcreteFactory : 서브 공장 클래스. 타입에 맞는 제품을 반환하도록 메소드들을 재정의
- AbstractProduct : 각 타입의 제품들을 추상화한 인터페이스
- ConcreteProduct (ProductA,B) : 각 타입의 제품 구현체. 팩토리 객체로부터 생성
- Client : 추상화된 AbstractFactory 클래스만을 이용 ㅡ> 제품(구현체)에 대해 상세히 알지 못함
코드 예제
using namespace std;
class AbstractProductA{ // A 제품군 인터페이스
public:
virtual ~ AbstractProductA(){};
virtual string SomeFunctionA() const=0;
};
class ConcreteProductA1 : public: AbstractProductA { // A제품군의 제품 1
public:
string SomeFunctionA() const override{
return "product A1";
}
};
class ConcreteProductA2 : public: AbstractProductA { // A제품군의 제품 2
public:
string SomeFunctionA() const override{
return "product A2";
}
};
class AbstractProductB{ // B 제품군 인터페이스
public:
virtual ~ AbstractProductB(){};
virtual string SomeFunctionB() const=0;
};
class ConcreteProductB1 : public: AbstractProductB { // B제품군의 제품 1
public:
string SomeFunctionA() const override{
return "product B1";
}
};
class ConcreteProductB2 : public: AbstractProductB { // B제품군의 제품 1
public:
string SomeFunctionA() const override{
return "product B2";
}
};
class AbstractFactory{ // 공장 클래스 인터페이스
public:
virtual ProductA* createProductA() const = 0;
virtual ProductB* createProductB() const = 0;
};
class ConcreteFactory1 : public AbstractFactory{ // 제품 1의 공장
public:
AstractProductA* CreateProductA() const override {
return new ConcreteProductA1();
}
AstractProductB* CreateProductB() const override {
return new ConcreteProductB1();
}
};
class ConcreteFactory2 : public AbstractFactory{ // 제품 2의 공장
public:
AstractProductA* CreateProductA() const override {
return new ConcreteProductA2();
}
AstractProductB* CreateProductB() const override {
return new ConcreteProductB2();
}
};
추상 팩토리 패턴이 적용된 코드입니다. 코드를 살펴보면 A, B 제품군에 따라 인터페이스를 각기 구현해 주었고, 해당 제품군에서 제품 1, 2에 해당하는 구현체 클래스들도 구현되어 있습니다.
최상위 공장 클래스를 인터페이스화하여 A, B 제품군을 생산할 함수들을 추상화하였고, 이를 상속 받은 서브 공장 클래스들이 추상화된 생산 함수들을 재정의하여 제품군에 맞는 제품을 생산하여 반환하는 형태입니다.
void Processing(const AbstractFactory & factory){
AbstractProductA* productA = factory.CreateProductA();
AbstractProductB* productB = factory.CreateProductB();
cout<<procutA->SomeFunctionA<<endl;
cout<<procutB->SomeFunctionB<<endl;
delete productA;
delete productB;
}
int main(){
ConcreteFactory1 * f1 = new ConcreteFactory1();
Processing(f1);
delete f1;
ConcreteFactory2 * f2 = new ConcreteFactory2();
Processing(f2);
delete f2;
}
//결과1
//product A1
//product B1
//결과2
//product A2
//product B2
추상 팩토리 패턴이 적용된 코드에 위 코드를 덧붙여 실행해보면 주석으로 추가된 것과 같은 결과가 출력됩니다.
추상 팩토리 패턴 특징
패턴 사용 시기
- 관련된 제품군의 다양한 제품들과 작동해야 하지만 해당 제품들의 구현체 클래스에 의존하고 싶지 않을 경우
ㅡ> 추후 확장이 쉬움 - 여러 제품 유형을 다루어야 할 경우 ㅡ> 팩토리 메서드의 기본 책임이 뚜렷하지 않을 때
패턴 장점
- 팩토리에서 생성되는 제품들의 상호 호환 보장
- 인터페이스를 사용해 구현체 클래스와 생성자(공장 클래스)의 결합도를 낮출 수 있음
- 제품 생성 코드를 한 곳으로 몰아 코드를 더 쉽게 유지보수 가능 ㅡ> SRP
- 기존 클라이언트 코드를 훼손하지 않고 제품의 새로운 변형 생성 가능 ㅡ> 확장이 쉽다 ㅡ> OCP
패턴 장점
- 각 구현체마다 팩토리 객체들을 모두 구현해 줘야 함 ㅡ> 객체가 늘어나면 클래스 폭증 ㅡ> 코드의 복잡성 증가
- 기존 추상 팩토리 세부사항 변경 ㅡ> 모든 팩토리 수정 필요
* 팩토리 메서드 vs 추상 팩토리
팩토리 메서드 | 추상 팩토리 | |
공통점 | 객체 생성 과정을 추상화하여 인터페이스 제공 객체 생성을 캡슐화하여 구체적인 타입을 감추고 느슨한 결합 구조 표방 |
|
차이점 | 구체적인 객체 생성 과정을 하위 클래스로 옮기는 것이 목적 | 관련 있는 여러 객체를 구체적인 클래스에 의존하지 않고 만들게 하는 것이 목적 |
한 Factory에서 한 종류의 객체 생성 | 한 Factory에서 연관된 여러 종류의 객체 생성 지원 | |
메서드 레벨에 포커스 객체 생성 이후 해야 할 일의 공통점을 정의하는데 초점 |
클래스 레벨에 포커스 생성해야 할 객체 집합군의 공통점에 초점 |
참고자료
💠 팩토리 메서드(Factory Method) 패턴 - 완벽 마스터하기
Factory Method Pattern 팩토리 메소드 패턴은 객체 생성을 공장(Factory) 클래스로 캡슐화 처리하여 대신 생성하게 하는 생성 디자인 패턴이다. 즉, 클라이언트에서 직접 new 연산자를 통해 제품 객체를
inpa.tistory.com
https://refactoring.guru/ko/design-patterns/abstract-factory
추상 팩토리 패턴
/ 디자인 패턴들 / 생성 패턴 추상 팩토리 패턴 다음 이름으로도 불립니다: Abstract Factory 의도 추상 팩토리는 관련 객체들의 구상 클래스들을 지정하지 않고도 관련 객체들의 모음을 생성할 수 있
refactoring.guru
'OOP' 카테고리의 다른 글
[OOP] 팩토리 메서드 패턴(Factory Method Pattern) (0) | 2025.01.20 |
---|---|
[OOP] 싱글톤 패턴(Singleton Pattern) (0) | 2025.01.16 |
[OOP] 디자인 패턴(Design Pattern) (0) | 2025.01.14 |
[OOP] 객체 지향 설계 5원칙(SOLID) : DIP(Dependency Inversion Principle)-의존 역전 원칙 (0) | 2025.01.13 |
[OOP] 객체 지향 설계 5원칙(SOLID) : ISP(Interface Segregation Principle)-인터페이스 분리 원칙 (1) | 2025.01.10 |