원형패턴..(개인적 정리 ebook!)
원형 패턴은 미리 만들어진 개체를 복사하여 개체를 생성하는 패턴을 말합니다.
(이때 미리 만들어진 개체를 원형 개체라 부릅니다.)
일반화 관계(상속)으로 표현할 때 파생 클래스의 개수가 과도히 많아지고 클래스의 메서드에서 수행하는 알고리즘에 차이가 없으면서
생성 시에 개체의 속성 값만 다르다면 원형 패턴을 사용하는 것이 효과적입니다.
#include<iostream>
#include<conio.h>
#include<string>
#include<vector>
using namespace std;
//기본중의 기본렌즈 생성 즉, 모형 줌렌즈(원형개체)
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)
: min_zoomlevel(min_zoomlevel), max_zoomlevel(max_zoomlevel), min_focus(min_focus), max_focus(max_focus)
{
zoomlevel=min_zoomlevel;
focus=min_focus;
}
void Take()
{
cout <<"줌 레벨 가능 범위"<<min_zoomlevel << "~" << max_zoomlevel << endl;
cout << "현재 줌레벨: " <<min_focus << "~"<< max_focus << endl;
cout <<"현재 포커스 : "<<focus << endl;
}
int ZoomIn()
{
if(zoomlevel<max_zoomlevel)
{
zoomlevel++;
}
return zoomlevel;
}
int ZoomOut()
{
if(zoomlevel>min_zoomlevel)
{
zoomlevel--;
}
return zoomlevel;
}
int NearFocus()
{
if(focus>min_focus)
{
focus--;
}
return focus;
}
int FarFocus()
{
if(focus<max_focus)
{
focus++;
}
return focus;
}
//자신을 복제하는 메소드
ZoomLens* Clone()
{
return new ZoomLens(min_zoomlevel, max_zoomlevel,min_focus, max_focus);
}
};
//지금부터는 설비라인임
enum TypeZoomLens
{
NM_NM,
NM_NF,
NF_NF,
MF_NF,
MF_MF
};
//라인중에서(NM NF MF이런것..) 렌즈의 개수를 알기위해 벡터사용
typedef vector<ZoomLens*>Lenses;
typedef vector<ZoomLens*>::iterator LIter;
//모형 줌 렌즈를 갖고 소비자 요청에 맞게 복제된 렌즈를 생산하는 클래스
//
class ProLine
{
ZoomLens *prototype;
Lenses soldlenses;
public:
ProLine(TypeZoomLens typezoomlens)
{
switch(typezoomlens)
{
case NM_NM: prototype=new ZoomLens(20,70,1,100);
break;
case NM_NF: prototype=new ZoomLens(20,70,1,200);
break;
case NF_NF: prototype=new ZoomLens(20,300,1,200);
break;
case MF_NF: prototype=new ZoomLens(70,300,1,200);
break;
case MF_MF: prototype=new ZoomLens(70,300,10,200);
break;
}
}
~ProLine()
{
DisposeLens();
delete prototype;
}
//렌즈 주문 메서드(원형 렌즈를 복제한 렌즈 반환)
//이떄 반환하는것은 생성자에서 인자로 받아 다양하게? 생성된 렌즈를 반환!
//제품 생산요청이 들어오면 이 메서드를 활용 모형을 복제한 줌 렌즈를 반환한다!
ZoomLens* MakeLens()
{
ZoomLens *product=prototype->Clone();
soldlenses.push_back(product);
return product;
}
private:
//백터 삭제 관련함수..
void DisposeLens()
{
LIter iter=soldlenses.begin();
LIter end=soldlenses.end();
ZoomLens *lens=0;
for(;iter!=end;++iter)
{
lens=*iter;
delete lens;
}
}
};
//여러 라인들을 넣기 위해..그러니까..위의NM NF MF이런 라인들..
typedef vector<ProLine*>ProLines;
typedef vector<ProLine*>::iterator PIter;
//렌즈 공장인데..여러 종류의 생산 설비(proline)들로 구성되어 있기 때문에..vector 활용
//이것은 원형패턴을 확장한것이지 없다고 해서 원형패턴이 아님..없어도 원형패턴임!
class LensFactory
{
//실제 렌즈를 생성하는 설비를 보관한 컬렉션
ProLines lines;
public:
LensFactory()
{
InitLines();
}
~LensFactory()
{
PIter iter=lines.begin();
PIter end=lines.end();
ProLine *proline=0;
for(;iter!=end;++iter)
{
proline=*iter;
delete proline;
}
}
//각 라인의 수..확인, 지금은 5개
int GetMaxLines() const
{
return lines.size();
}
//주문한 렌즈를 생산하여 반환하는 메서드
//주문은 근데 5개 이므로 5개를 넘기면 안됨
ZoomLens *Order(int index)
{
if((index>=0) && (index<GetMaxLines()))
{
ProLine *pline=lines[index];
return pline->MakeLens();
}
return 0;
}
private:
//proline에 lines을 생성해서 넣기 5개..
void 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));
}
};
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;
getch();
return 0;
}