추상 팩토리 패턴 (Abstract Factory Pattern)
Gof Design Pattern2014. 1. 25. 01:47
Abstract Factory Pattern - 추상 팩토리 패턴
- 객체를 생성해주는 팩토리 관점은 동일하다.
- 다양한 구성 요소 별로 '객체의 집합'을 생성해야 할 때 유용하다, 즉 서로 다른 객체들을 하나의 팩토리에서 생성 관리한다고 보면 된다.
- 하나의 인터페이스에서 객체의 생성을 처리하고, 다양한 성격의 객체를 하나의 군으로 형성 그것을 객체단위로 취급하여 생성을 해야할 때 유용한 패턴이다
샘플 코드)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | //------------------------------------------------------------------ // ProductA 인터페이스 클래스 class AbstractProductA { public: virtual void print() = 0; }; //------------------------------------------------------------------ // ProductB 인터페이스 클래스 class AbstractProductB { public: virtual void print() = 0; }; //------------------------------------------------------------------ // ConcreteProductA1 클래스 class ConcreteProductA1 : public AbstractProductA { public: void print() override { cout << "ConcreteProductA1" << endl; } }; //------------------------------------------------------------------ // ConcreteProductA2 클래스 class ConcreteProductA2 : public AbstractProductA { public: void print() override { cout << "ConcreteProductA2" << endl; } }; //------------------------------------------------------------------ // ConcreteProductB1 클래스 class ConcreteProductB1 : public AbstractProductB { public: void print() override { cout << "ConcreteProductB1" << endl; } }; //------------------------------------------------------------------ // ConcreteProductB2 클래스 class ConcreteProductB2 : public AbstractProductB { public: void print() override { cout << "ConcreteProductB2" << endl; } }; //------------------------------------------------------------------ // Factory 인터페이스 클래스 class AbstractFactory { public: virtual AbstractProductA* createProductA() = 0; virtual AbstractProductB* createProductB() = 0; }; //------------------------------------------------------------------ // ConcreteFactory1 클래스 class ConcreteFactory1 : public AbstractFactory { public: AbstractProductA* createProductA() override { return new ConcreteProductA1; } AbstractProductB* createProductB() override { return new ConcreteProductB1; } }; //------------------------------------------------------------------ // ConcreteFactory2 클래스 class ConcreteFactory2 : public AbstractFactory { public: AbstractProductA* createProductA() override { return new ConcreteProductA2; } AbstractProductB* createProductB() override { return new ConcreteProductB2; } }; //------------------------------------------------------------------ // Main int _tmain(int argc, _TCHAR* argv[]) { ConcreteFactory1 pFactory1; ConcreteFactory2 pFactory2; AbstractProductA* pA1 = pFactory1.createProductA(); pA1->print(); AbstractProductB* pB1 = pFactory1.createProductB(); pB1->print(); AbstractProductA* pA2 = pFactory2.createProductA(); pA2->print(); AbstractProductB* pB2 = pFactory2.createProductB(); pB2->print(); delete pA1; delete pB1; delete pA2; delete pB2; return 0; } |
예제를 통한 추상 팩토리 패턴(Abstract Factory Pattern) 알아보기
예제) UI 구성 예제
UI를 구성하는 버튼, 스크롤이 있고, 그 객체를 전담 생성해주는 추상 팩토리가 있다. 추상 팩토리 인터페이스에서는 서로 다른 클래스들을 생성할 수 있도록 각각의 클래스 생성 메소드를 제공하고, 실제 생성 코드는 하위에서 생성하도록 한다.
예제코드)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | //------------------------------------------------------------------ // 버튼 인터페이스 class IButton { public: virtual void print() = 0; }; //------------------------------------------------------------------ // 스크롤 인터페이스 class IScroll { public: virtual void print() = 0; }; //------------------------------------------------------------------ // 사각 버튼 클래스 class CButtonRectangle : public IButton { public: void print() override { cout << "CButton Rectangle" << endl; } }; //------------------------------------------------------------------ // 사각 스크롤 클래스 class CScrollRectangle : public IScroll { public: void print() override { cout << "CScroll Rectangle" << endl; } }; //------------------------------------------------------------------ // 둥근 버튼 클래스 class CButtonCircle : public IButton { public: void print() override { cout << "CButton Circle" << endl; } }; //------------------------------------------------------------------ // 둥근 스크롤 클래스 class CScrollCircle : public IScroll { public: void print() override { cout << "CScroll Circle" << endl; } }; //------------------------------------------------------------------ // 팩토리 인터페이스 class IUIFactory { public: virtual IButton* createButton() = 0; virtual IScroll* createScroll() = 0; }; //------------------------------------------------------------------ // 사각형 팩토리 클래스 class CUIFactory_Rectangle : public IUIFactory { public: IButton* createButton() override { return new CButtonRectangle; } IScroll* createScroll() override { return new CScrollRectangle; } }; //------------------------------------------------------------------ // 동그라미 팩토리 클래스 class CUIFactory_Circle : public IUIFactory { public: IButton* createButton() override { return new CButtonCircle; } IScroll* createScroll() override { return new CScrollCircle; } }; //------------------------------------------------------------------ // Main int _tmain(int argc, _TCHAR* argv[]) { CUIFactory_Rectangle mRectangleFactory; IButton* pRectangleButton = mRectangleFactory.createButton(); IScroll* pRectangleScroll = mRectangleFactory.createScroll(); pRectangleButton->print(); pRectangleScroll->print(); delete pRectangleButton; delete pRectangleScroll; return 0; } |
예제 결과)
템플릿(template)을 활용한 확장 구조 설계
- 생성해야 할 객체의 종류가 늘어날 때마다 이를 생성하기 위한 클래스를 계속 추가해주어야 하는 문제점 발생!!
- C++의 Template를 활용하여 객체 생성 클래스를 설계해야 된다
확장 설계 예제) 템플릿을 활용한 확장 설계
확장 설계 소스 코드)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | //------------------------------------------------------------------ // 버튼 인터페이스 class IButton { public: virtual void print() = 0; }; //------------------------------------------------------------------ // 스크롤 인터페이스 class IScroll { public: virtual void print() = 0; }; //------------------------------------------------------------------ // 사각 버튼 클래스 class CButtonRectangle : public IButton { public: void print() override { cout << "CButton Rectangle" << endl; } }; //------------------------------------------------------------------ // 사각 스크롤 클래스 class CScrollRectangle : public IScroll { public: void print() override { cout << "CScroll Rectangle" << endl; } }; //------------------------------------------------------------------ // 둥근 버튼 클래스 class CButtonCircle : public IButton { public: void print() override { cout << "CButton Circle" << endl; } }; //------------------------------------------------------------------ // 둥근 스크롤 클래스 class CScrollCircle : public IScroll { public: void print() override { cout << "CScroll Circle" << endl; } }; //------------------------------------------------------------------ // 추상 팩토리 템플릿 인터페이스 (템플릿 메소드 패턴 적용) template<typename T> class AbstractFactory { public: T* Create() { return createProduct(); } protected: virtual T* createProduct() = 0; }; //------------------------------------------------------------------ // 팩토리 템플릿 클래스 (세부 객체 생성 전담) template<typename T1, typename T2> class ConcreteFactory : public AbstractFactory<T1> { private: T1* createProduct() override { return new T2; } }; //------------------------------------------------------------------ // Main int _tmain(int argc, _TCHAR* argv[]) { ConcreteFactory<IButton, CButtonCircle> mCircleFactory; ConcreteFactory<IScroll, CScrollRectangle> mRectangleFactory; IButton* pCircleButton = mCircleFactory.Create(); IScroll* pRectangleScroll = mRectangleFactory.Create(); pCircleButton->print(); pRectangleScroll->print(); delete pCircleButton; delete pRectangleScroll; return 0; } |
확장 설계 예제 결과)
'Gof Design Pattern' 카테고리의 다른 글
아답터 패턴 (Adapter Pattern) (0) | 2014.01.27 |
---|---|
빌더 패턴 (Builder Pattern) (0) | 2014.01.26 |
팩토리 메서드 패턴 (Factory Method Pattern) (4) | 2014.01.24 |
상태 패턴 (State Pattern) (0) | 2014.01.23 |
원형 패턴 (Prototype Pattern) (0) | 2014.01.23 |