3. 팩토리 메서드 패턴(Factory Method Pattern)
3.1 개요
프로그래밍하다 보면 같은 방법으로 사용할 수 있는 여러 종류의 개체를 일반화하여 기반 클래스를 정의하고 이를 기반으로 파생 클래스로 정의하는 것은 매우 흔합니다. 이 경우에 사용하는 곳에서 구체적으로 어떠한 개체를 생성해서 사용할 지에 대하여 개발 초기 단계에서 결정할 수 없다면 어떻게 하면 좋을까요? 팩토리 메서드 패턴을 이용하면 이러한 고민을 해결할 수 있습니다.
추상 팩토리 클래스에서는 사용할 개체(추상 클래스)를 생성하는 것에 대해 약속만 합니다. 대신 파생 팩토리 클래스에서 구체적으로 어떠한 개체를 생성할 것인지 구현합니다. 이처럼 구체적인 개체를 생성하는 부분을 분리하면 추상 팩토리 클래스에서는 어떠한 개체를 생성할 것인지에 대한 고민은 뒤로 미루고 개체를 사용하는 부분을 구현할 수 있습니다. 팩토리 메서드란 추상 팩토리 클래스에 약속된 개체를 생성하는 메서드입니다.
팩토리 메서드 패턴은 자주 사용하게 되는 프로그램의 뼈대를 만들 때 사용되기도 합니다. 예를 들어 프로그램의 주요 뼈대로 응용 클래스와 사용자와 상호작용하는 뷰 클래스를 기본적으로 제공한다고 가정합시다. 응용 클래스에서는 초기에 메인 뷰 개체를 생성하고 실행에서는 메인 뷰 개체를 활성화하고 해제화를 통해 뷰 개체를 소멸하게 만들어 봅시다. 이 경우에 추상 응용 클래스에는 추상 뷰 개체를 생성하는 메서드를 약속합니다. 추상 응용 클래스의 초기화에서는 추상 뷰 개체를 생성하는 메서드를 이용하여 개체를 생성합니다. 그리고 다른 메서드에서는 해당 뷰 개체를 사용합니다. 이처럼 뼈대를 구성하면 실제 프로그램을 작성할 때에는 추상 응용 클래스에서 파생된 응용 클래스에서 자신에 맞는 뷰 개체를 생성하는 메서드를 구현하는 것으로 기본적인 코드는 완성되게 됩니다.
행위 패턴중에 템플릿 메서드 패턴과 팩토리 메서드 패턴을 함께 사용하면 좀 더 효과적으로 프로그램의 뼈대를 정의할 수 있습니다.
3. 2 시나리오
지난번에 혁재와 EHCamera 회사를 방문한 후로 혁재는 사진에 관한 관심이 깊어졌습니다. 그리고 디지털 카메라의 많은 부분이 소프트웨어 기술을 사용하는 것을 알고는 프로그래밍에도 관심을 갖게 되었습니다.
"아빠, 프로그래밍을 하다 보니 같은 로직을 작성하는 부분이 너무 많은 것 같아요. 아빠가 작성할 때는 어렵지 않게 만드는 것 같던데 무슨 비결이라도 있나요?"
"음, 프로그램도 건물을 짓는 것처럼 설계하고 구현한단다. 그리고 자주 설계하다 보면 비슷한 형태를 띠는 것을 발견하곤 하지. 이렇게 설계에서 자주 나타나는 형태를 디자인 패턴이라고 해."
"디자인 패턴? 그럼 나도 디자인 패턴을 공부하면 쉽게 프로그래밍할 수 있어?"
"물론 디자인 패턴만 익힌다고 쉽게 프로그래밍할 수 있는 것은 아니지만 좀 더 효과적으로 견고한 프로그램을 작성할 수 있지."
아들과 프로그래밍에 관한 대화를 마치고 서점에 가서 [Escort GoF의 디자인 패턴]을 하나 샀어요. 그리고 팩토리 메서드 패턴을 이용하여 간단한 콘솔 응용 프로그램의 뼈대를 만들었습니다. 뼈대는 추상 응용 클래스와 추상 뷰 클래스로 구성했어요. 추상 응용 클래스에는 초기화, 런, 해제화로 진행하게 하였고 뷰 개체를 생성하는 메서드를 약속했어요. 초기화에서는 뷰 개체를 생성하는 메서드를 호출하는 부분을 작성하고 런 부분에서는 사용자가 선택한 메뉴에 따라 세부 기능을 수행하고 해제화 부분에서는 뷰 개체를 소멸하게 했어요. 이렇게 뼈대를 만들고 나서 이를 통해 특정 응용 프로그램을 만들 때 목적에 맞는 뷰 개체를 만들고 응용 클래스의 필요한 부분만 재정의하면 된다는 것을 보여주는 예제 프로그램을 만들었지요.
//common.h
#pragma once
#include <string>
#include <iostream>
#include <vector>
using namespace std;
//EHView.h
#pragma once
class EHView
{
public:
virtual ~EHView(){}
virtual void Show()=0;
};
//MyView.h
#pragma once
#include "EHView.h"
#include "common.h"
class MyView :
public EHView
{
public:
MyView();
~MyView();
void Show();
};
//MyView.cpp
#include "MyView.h"
MyView::MyView()
{
cout<<"MyView 생성"<<endl;
}
MyView::~MyView()
{
cout<<"MyView 소멸"<<endl;
}
void MyView::Show()
{
cout<<"MyView::Show"<<endl;
}
//EHApp.h
#pragma once
#include "EHView.h"
class EHApp
{
EHView *view;
public:
virtual void InitInstance();
virtual void Run();
virtual void ExitInstance();
protected:
virtual EHView *MakeView()=0;
};
//EHApp.cpp
#include "EHApp.h"
void EHApp::InitInstance()
{
view = MakeView();
}
void EHApp::Run()
{
view->Show();
}
void EHApp::ExitInstance()
{
delete view;
}
//MyApp.h
#pragma once
#include "ehapp.h"
#include "MyView.h"
class MyApp :
public EHApp
{
public:
void InitInstance();
virtual EHView *MakeView();
};
//MyApp.cpp
#include "MyApp.h"
void MyApp::InitInstance()
{
cout<<"MyApp 초기화"<<endl;
EHApp::InitInstance();
}
EHView *MyApp::MakeView()
{
return new MyView();
}
//Demo.cpp
#include "MyApp.h"
int main()
{
MyApp *app = new MyApp();
app->InitInstance();
app->Run();
app->ExitInstance();
delete app;
return 0;
}
|
'프로그래밍 기술 > Escort GoF의 디자인 패턴' 카테고리의 다른 글
11. 플라이급 패턴(Flyweight Pattern) [Escort GoF의 디자인 패턴] (0) | 2016.04.04 |
---|---|
10. 퍼샤드 패턴(Facade Pattern) [Escort GoF의 디자인 패턴] (0) | 2016.04.04 |
9. 장식자 패턴(Decorator Pattern) [Escort GoF의 디자인 패턴] (0) | 2016.04.04 |
8. 복합체 패턴(Composite Pattern) [Escort GoF의 디자인 패턴] (0) | 2016.04.04 |
7. 가교 패턴(Bridge Pattern) [Escort GoF의 디자인 패턴] (0) | 2016.04.04 |
6. 적응자 패턴(Adapter Pattern) [Escort GoF의 디자인 패턴] (0) | 2016.04.04 |
5. 단일체 패턴(Singleton Pattern) [Escort GoF의 디자인 패턴] (0) | 2016.04.04 |
4. 원형 패턴(Prototype Pattern) [Escort GoF의 디자인 패턴] (0) | 2016.04.04 |
2. 빌더 패턴(Builder Pattern) [Escort GoF의 디자인 패턴] (0) | 2016.04.04 |
1. 추상 팩토리 패턴 (Abstract Factory Pattern) [Escort GoF의 디자인 패턴] (0) | 2016.04.04 |