팩토리 메서드 패턴 (Factory Method Pattern)
Gof Design Pattern2014. 1. 24. 03:31
Factory Method Pattern - 팩토리 메서드 패턴
- 객체를 생성하는 일을 전담하도록 한다
- 인터페이스를 바탕으로 유연성과 확장성이 뛰어난 코드 제작이 가능하다 (리펙토링에 유리)
- 인터페이스에서 객체 생성을 요청하지만, 어떤 클래스의 인스턴스를 만들지는 서브클래스에서 결정한다
- 이는 곧 템플릿 메소드 패턴(Template Method Pattern)을 활용한 패턴이라고 할 수 있다. 실제로 위 그림에서 오른쪽 Creator와 ConcreteCreator 클래스만 뜯어보면 템플릿 메소드 패턴(Template Method 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 | //------------------------------------------------------------------ // Product 인터페이스 클래스 class Product { public: virtual void print() = 0; }; //------------------------------------------------------------------ // Product 상속 클래스 class ConcreteProduct : public Product { public: void print() override { cout << "ConcreteProduct" << endl; } }; //------------------------------------------------------------------ // Creator 클래스 (구현 인터페이스 클래스) class Creator { public: Product* AnOperation() { return FactoryMethod(); } protected: virtual Product* FactoryMethod() = 0; }; //------------------------------------------------------------------ // Creator 상속 클래스 (실제 객체 생성 전담) class ConcreteCreator : public Creator { private: Product* FactoryMethod() { return new ConcreteProduct; } }; //------------------------------------------------------------------ // Main int _tmain(int argc, _TCHAR* argv[]) { ConcreteCreator pCreator; Product* pProduct = pCreator.AnOperation(); pProduct->print(); delete pProduct; return 0; } |
예제를 통한 팩토리 메서드 패턴(Factory Method 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 | //------------------------------------------------------------------ // 문서 인터페이스 클래스 class 문서_인터페이스 { public: virtual void print() = 0; }; //------------------------------------------------------------------ // 한글 문서 클래스 class 문서_한글 : public 문서_인터페이스 { public: void print() override { cout << "한글 파일" << endl; } }; //------------------------------------------------------------------ // 엑셀 문서 클래스 class 문서_엑셀 : public 문서_인터페이스 { public: void print() override { cout << "엑셀 파일" << endl; } }; //------------------------------------------------------------------ // 프로그램 인터페이스 클래스 class 프로그램_인터페이스 { public: 문서_인터페이스* 생성() { return 문서생성(); } protected: virtual 문서_인터페이스* 문서생성() = 0; }; //------------------------------------------------------------------ // 한글 프로그램 클래스 class 프로그램_한글 : public 프로그램_인터페이스 { private: 문서_인터페이스* 문서생성() { return new 문서_한글; } }; //------------------------------------------------------------------ // 엑셀 프로그램 클래스 class 프로그램_엑셀 : public 프로그램_인터페이스 { private: 문서_인터페이스* 문서생성() { return new 문서_엑셀; } }; //------------------------------------------------------------------ // Main int _tmain(int argc, _TCHAR* argv[]) { 프로그램_한글 pHwpCreator; 프로그램_엑셀 pXlsCreator; 문서_인터페이스* pHwp = pHwpCreator.생성(); pHwp->print(); 문서_인터페이스* pXls = pXlsCreator.생성(); pXls->print(); delete pXls; delete pHwp; return 0; } |
예제 결과)
템플릿(template)을 활용한 확장 구조 설계
- 생성해야 할 객체의 종류가 늘어날 때마다 이를 생성하기 위한 클래스를 계속 추가해주어야 하는 문제점 발생!!
- C++의 Template를 활용하여 객체 생성 클래스를 설계해야 된다
확장 설계 예제) 템플릿을 활용한 확장 설계
다이어그램과 같이 프로그램 인터페이스를 기반으로 하나의 프로그램 템플릿을 제작하고 T 인자로 문서 인터페이스를 전달하도록 하여 간소화 하였다. 소스코드를 보게 되면 쉽게 이해갈 것이라 생각한다. 위의 기본 팩토리 메서드 패턴과 비교하면서 보면 더 쉽게 이해갈 것이다. 결과는 위와 동일하다.
확장 설계 소스 코드)
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 | //------------------------------------------------------------------ // 문서 인터페이스 클래스 class 문서_인터페이스 { public: virtual void print() = 0; }; //------------------------------------------------------------------ // 한글 문서 클래스 class 문서_한글 : public 문서_인터페이스 { public: void print() override { cout << "한글 파일" << endl; } }; //------------------------------------------------------------------ // 엑셀 문서 클래스 class 문서_엑셀 : public 문서_인터페이스 { public: void print() override { cout << "엑셀 파일" << endl; } }; //------------------------------------------------------------------ // 프로그램 인터페이스 클래스 class 프로그램_인터페이스 { public: 문서_인터페이스* 생성() { return 문서생성(); } protected: virtual 문서_인터페이스* 문서생성() = 0; }; //------------------------------------------------------------------ // 프로그램 템플릿 클래스 template<typename T> class 프로그램_템플릿 : public 프로그램_인터페이스 { private: 문서_인터페이스* 문서생성() { return new T; } }; //------------------------------------------------------------------ // Main int _tmain(int argc, _TCHAR* argv[]) { 프로그램_템플릿<문서_한글> pHwpCreator; 프로그램_템플릿<문서_엑셀> pXlsCreator; 문서_인터페이스* pHwp = pHwpCreator.생성(); pHwp->print(); 문서_인터페이스* pXls = pXlsCreator.생성(); pXls->print(); delete pXls; delete pHwp; return 0; } |
'Gof Design Pattern' 카테고리의 다른 글
빌더 패턴 (Builder Pattern) (0) | 2014.01.26 |
---|---|
추상 팩토리 패턴 (Abstract Factory Pattern) (0) | 2014.01.25 |
상태 패턴 (State Pattern) (0) | 2014.01.23 |
원형 패턴 (Prototype Pattern) (0) | 2014.01.23 |
UML 및 디자인 패턴 배우기 좋은 추천 사이트 (1) | 2014.01.22 |