4. 원형 패턴(Prototype Pattern)
4.1 개요
원형 패턴은 미리 만들어진 개체를 복사하여 개체를 생성하는 패턴을 말합니다. 그리고 이때 미리 만들어진 개체를 원형 개체라 부릅니다. 일반화 관계로 표현할 때 파생 클래스의 개수가 과도히 많아지고 각 클래스의 메서드에서 수행하는 알고리즘에 차이가 없으면서 생성 시에 개체의 속성 값만 다르다면 원형 패턴을 사용하는 것이 효과적입니다.
4. 2 시나리오
다음 주에는 거제도와 통영으로 2박 3일 여행을 가기로 하였습니다. 이번 기회에 괜찮은 줌 렌즈를 하나 구매하려고 EHLand 쇼핑몰을 검색해 보았습니다.
EHLand 쇼핑몰에는 다양한 형태의 줌 렌즈들이 있는데 이들 중에 무엇을 사는 것이 좋은지 생각하다 보니 어떠한 원리로 만들어져 있는지 궁금해 졌습니다. EHLand의 매핑 씨한테 물어보면 궁금증이 풀릴 것 같아 이메일을 보냈어요.
안녕하세요, 매핑 씨. 지난번에 EhLand 사의 렌즈 개발 과정을 친절히 소개해 주셔서 감사드립니다. 이번에 남해안에 여행을 가게 되어 줌 렌즈를 하나 구매하려고 합니다. '어떤 렌즈를 구입을 할까?' 고민을 하다 보니 어떻게 렌즈가 만들어지는지 궁금해졌어요. |
이메일을 보내고 난 다음 날 바로 매핑 씨의 답변 메일을 받았습니다.
혁재 아버지, 안녕하세요. 가족끼리 남해에 여행을 간다고 하니 부럽네요. 혁재가 많이 좋아할 거 같군요. 이번에는 줌 렌즈를 만드는 공정이 궁금하신가 보네요. 줌 렌즈를 만드는 생산 설비는 복사기와 비슷한 원리로 만들어집니다. EHLand의 모든 줌 렌즈는 모두 같은 구조로 되어있고 들어가는 모듈도 크게 다르지 않습니다. 각 생산 설비마다 모형 줌 렌즈가 있는데 이들의 기본 구조는 동일하게 제작되어 있습니다. 물론, 각 모형 줌 렌즈들은 서로 거리 조절링에 설정되어 있는 최소 거리와 최대 거리나 조리개 조절링에 설정된 최소치와 최대치가 다릅니다. 생산 설비의 기계는 원본 줌 렌즈의 이들 속성을 확인하여 똑같게 설정된 렌즈를 생산하고 있지요. |
//common.h
#pragma once
#include <iostream>
using std::cout;
using std::endl;
#include <vector>
using std::vector;
#include <string>
using std::string;
//ZoomLens.h
#pragma once
class ZoomLens
{
const int min_zoomlevel;
const int max_zoomlevel;
int zoomlevel;
const int min_focus;
const int max_focus;
int focus;
public:
ZoomLens(int min_zoomlevel, int max_zoomlevel, int min_focus, int max_focus);
void Take();
int ZoomIn();
int ZoomOut();
int NearFocus();
int FarFocus();
ZoomLens *Clone();
};
//ZoomLens.cpp
#include "ZoomLens.h"
#include "common.h"
void ZoomLens::Take()
{
cout<<"줌 레벨 가능 범위:"<<min_zoomlevel<<"~"<<max_zoomlevel<<endl;
cout<<"현재 줌레벨:"<<zoomlevel<<endl;
cout<<"포커스 조절 범위"<<min_focus<<"~"<<max_focus<<endl;
cout<<"현재 포커스:"<<focus<<endl;
}
int ZoomLens::ZoomIn()
{
if(zoomlevel<max_zoomlevel)
{
zoomlevel++;
}
return zoomlevel;
}
int ZoomLens::ZoomOut()
{
if(zoomlevel>min_zoomlevel)
{
zoomlevel--;
}
return zoomlevel;
}
int ZoomLens::NearFocus()
{
if(focus>min_focus)
{
focus--;
}
return focus;
}
int ZoomLens::FarFocus()
{
if(focus<max_focus)
{
focus++;
}
return focus;
}
ZoomLens::ZoomLens(int min_zoomlevel, int max_zoomlevel, int min_focus, int max_focus):
min_zoomlevel(min_zoomlevel),max_zoomlevel(max_zoomlevel),min_focus(min_focus),max_focus(max_focus)
{
zoomlevel = min_zoomlevel;
focus = min_focus;
}
ZoomLens *ZoomLens::Clone()
{
return new ZoomLens(min_zoomlevel,max_zoomlevel,min_focus,max_focus);
}
//ProLine.h
#pragma once
#include "ZoomLens.h"
#include "common.h"
enum TypeZoomLens
{
NM_NM,
NM_NF,
NF_NF,
MF_NF,
MF_MF
};
typedef vector<ZoomLens *> Lenses;
typedef vector<ZoomLens *>::iterator LIter;
class ProLine
{
ZoomLens *prototype;
Lenses soldlenses;
public:
ProLine(TypeZoomLens typezoomlens);
~ProLine(void);
ZoomLens *MakeLens();
private:
void DisposeLens();
};
//ProLine.cpp
#include "ProLine.h"
ProLine::ProLine(TypeZoomLens typezoomlens)
{
switch(typezoomlens)
{
case NM_NM: prototype = new ZoomLens(20,70,1,3); break;
case NM_NF: prototype = new ZoomLens(20,70,1,5); break;
case NF_NF: prototype = new ZoomLens(20,300,1,8); break;
case MF_NF: prototype = new ZoomLens(70,300,2,8); break;
case MF_MF: prototype = new ZoomLens(70,300,3,7); break;
}
}
ProLine::~ProLine(void)
{
DisposeLens();
delete prototype;
}
void ProLine::DisposeLens()
{
LIter iter = soldlenses.begin();
LIter end = soldlenses.end();
ZoomLens *lens=0;
for( ; iter != end; ++iter)
{
lens = *iter;
delete lens;
}
}
ZoomLens *ProLine::MakeLens()
{
ZoomLens * product = prototype->Clone();
soldlenses.push_back(product);
return product;
}
//LensFactory.h
#pragma once
#include "ProLine.h"
typedef vector<ProLine *> ProLines;
typedef vector<ProLine *>::iterator PIter;
class LensFactory
{
ProLines lines;
public:
LensFactory(void);
~LensFactory(void);
int GetMaxLines()const;
ZoomLens *Order(int n);
private:
void InitLines();
};
//LensFactory.cpp
#include "LensFactory.h"
LensFactory::LensFactory(void)
{
InitLines();
}
LensFactory::~LensFactory(void)
{
PIter iter = lines.begin();
PIter end = lines.end();
ProLine *proline=0;
for( ; iter != end; ++iter)
{
proline = *iter;
delete proline;
}
}
int LensFactory::GetMaxLines()const
{
return lines.size();
}
ZoomLens *LensFactory::Order(int index)
{
if( (index>=0)&&(index<GetMaxLines()))
{
ProLine *pline = lines[index];
return pline->MakeLens();
}
return 0;
}
void LensFactory::InitLines()
{
lines.push_back(new ProLine(NM_NM));
lines.push_back(new ProLine(NM_NF));
lines.push_back(new ProLine(NF_NF));
lines.push_back(new ProLine(MF_NF));
lines.push_back(new ProLine(MF_MF));
}
//Demo.cpp
#include "LensFactory.h"
int main()
{
LensFactory *factory = new LensFactory();
int lcnt = factory->GetMaxLines();
ZoomLens *lens = 0;
for(int i = 0; i<lcnt; i++)
{
lens = factory->Order(i);
if(lens)
{
lens->Take();
cout<<endl;
}
}
delete factory;
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 |
3. 팩토리 메서드 패턴(Factory Method 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 |