factory는 공장을 의미한다. 공장패턴? 이 패턴은 공장의 작동방식을 생각해보면 어렵잖게 이해할 수 있는 패턴이다. 소프트웨어 개발이 아닌 영역에도 널리 쓰이는 패턴이다.
공장은 필요한 자원과 설비를 갖추고 있으며, 이들 자원과 설비를 이용해서 특정한 객체를 생산할 수 있는 시설이다. 만약에 오토바이를 만드는 공장이라고 하면, 이 공장은 단일 브랜드의 오토바이만 생산해내지는 않을 것이다. 그렇게 공장을 설계할리도 없을 것이다. 분명히 다양한 다양한 용도의 오토바이를 생산해낼 수 있게끔 설계할 것이다
이렇게 해서 얻을 수 있는 잇점은 여러개의 비슷한 공정을 가지는 시설을 여러개 가지고 있을 필요가 없다는 점이 될 것이다. 스위치만을 이용해서 비교적 간단하게 다양한 제품을 생산할 수 있다. 이를 소프트웨어에 그대로 응용한게 factory:::method:::pattern(:12)이다.
상황극
문 : 그래요. 알았으니 factory pattern의 현실적 예를 좀 들어주세요. 아무래도 이해가 좀.
답 : 어떤 제품을 만든다고 하면, 파생되는 제품이 있을거에요. 이 제품이 공장에서 만들어진다면, 파생되는 제품까지를 하나의 공장에서 생산해낼 수 있도록 해야 겠죠 ?
문 : 그런가요 ?
답 : 그렇죠. 파생 제품이라는게 동일한 자원과 설비를 필요로 할거잖아요. 공정만 약간 다른 식이죠. 그렇다면, 하나의 공장에서 여러개의 공정을 수행할 수 있도록 범용가능하게 만드는게 훨씬 이익이죠. 비슷한 공장을 2-3개씩 만들면 엄청난 낭비 아니겠어요 ?
문 : 음 그렇겠군요. 오토바이 공장이라면, 오토바이에서 파생되는게 제품이 스쿠터, 소형, 중형, 중대형 그리고 목적에 따라 여러가지가 만들어진다고 했을 때 스위치 조작정도로 여러개의 제품을 생산해낼 수 있도록 한다 뭐 그런거네요 ?
답 : 네 맞아요.
문 : 음. 객체지향 프로그래밍으로 보자면 class motocycle 가 만들어지고, 여기에서 상속되어서 cycle200cc, cycle300cc, batcar, roadrunner 클래스가 생성되는 형태겠군요.
답 : 네. 아주 좋은 예인거 같네요. 더불어 엔진,프레임,조립등의 메서드들을 가상함수로 만들어서 상속된 클래스에서 구현하도록 할 수 있겠죠. 또한 병렬처리하는데에도 유용하겠죠 ? 한라인에서는 cycle200cc를 만들고 다른 라인에서는 cycle300cc를 만드는 등으로 말이죠.
문 : (약간 우쭐해졌음) factory fattern 이라는 것도 그리 어려운건 아니군요.
답 : 네. 일상생활에서 흔히 경험할 수 있는 것들이에요. 이름을 붙이고 붙이지 않는게 그래서 중요하죠. 체계적으로 정리하고, 효율적으로 소통할 수 있도록 도와주니까요.
문 : 그렇겠네요. factory fattern을 위해서 구구절절하게 설명하는 것보다. 패턴의 의미를 알고 있다면, 훨씬 간단하게 의사소통이 가능하겠군요.
활용
팩토리 패턴은 툴킷이나 프레임워크의 라이브러리에서, 주어지는 인자에 따라서 다른 객체를 생성해서 넘겨주고자 할때 사용할 수 있다.
사용예
Image Reader를 위한 클래스를 만드는 경우를 생각해보자. 이 클래스는 여러가지 이미지를 읽을 수 있어야 할 것이다. 그렇다면, 이미지 타입을 인자로 받아들이고 해당 이미지를 처리할 수 있는 객체를 생성해서 리턴할 수 있을 것이다.
#include <iostream>
#include <stdio.h>
#define GIF 1
#define JPG 2
#define PNG 3
using namespace std;
class ImageReader
{
public:
virtual void decode() = 0;
};
class GIFReader: public ImageReader
{
public :
void decode() {cout << "GifReader RUN" << endl;}
};
class JPGReader: public ImageReader
{
public :
void decode() {cout << "JPGReader RUN" << endl;}
};
class PNGReader: public ImageReader
{
public :
void decode() {cout << "PNGReader RUN" << endl;}
};
class ImageReaderFactory
{
private:
int ImageType;
public:
void setImageType(int type)
{
ImageType = type;
}
ImageReader* getImageReader(int type)
{
setImageType(type);
switch(type)
{
case GIF:
return new GIFReader();
case JPG:
return new JPGReader();
case PNG:
return new JPGReader();
default:
break;
}
}
};
// 테스트용 Main 코드
int main(int argc, char **argv)
{
ImageReaderFactory * myReaderFactory;
ImageReader *myReader;
myReaderFactory = new ImageReaderFactory;
myReader = myReaderFactory->getImageReader(PNG);
myReader->decode();
}
Factory Method Pattern
일반적인 상황
상황극
활용
사용예
Recent Posts
Archive Posts
Tags