반응형
Template method 기법
- 모든 도형에 공통적으로 변하지 않는 전체적인 흐름을 기반 클래스에서 제공하고
- 각 도형 별로 변해야 하는 부분을 가상 함수로 제공해서 파생 클래스가 재정의 할 수 있게 한다.
#include <iostream>
#include <vector>
using namespace std;
class Shape
{
public:
// [문제] 가상의 멀티스래드 세이프에 대한 고려
virtual void Draw() final
{
// 변하는 것을 가상함수로 뽑아낸다.
// -> Lock, Unlock 은 변화하지 않는 코드
// -> 실재 그리기 로직만 변화가 있는 코드이다. -> 이것을 함수로 빼냄 -> DrawImp()
cout << "Mutex Lock" << endl;
DrawImp();
cout << "Mutex Unlcok" << endl;
}
// Shape를 상속 받는 클래스는 이제 Draw()가 아닌 DrawImp()를 재정의 하여 각자에 맞는 구현을 하면 되겠다.
// -> 이제는 더이상 파생클래스에서 Draw()를 재정의하는 일은 없어야한다. -> final
// -> 사용자는 외부에서 DrawImp()를 호출할 수 없어야 한다. -> private 또는 protected
virtual Shape* Clone() { return new Shape(*this); }
protected:
virtual void DrawImp()
{
cout << "Draw Shape" << endl;
}
};
class Rect : public Shape
{
public:
virtual void DrawImp() { cout << "Draw Rect" << endl; }
virtual Shape* Clone() { return new Rect(*this); }
};
class Circle : public Shape
{
public:
virtual void DrawImp() { cout << "Draw Circle" << endl; }
virtual Shape* Clone() { return new Circle(*this); }
};
int main() {
vector<Shape*> v;
while(1)
{
int i = 0;
cin >> i;
// Add New Rect
if(i == 1) v.push_back(new Rect);
// Add New Circle
else if(i == 2) v.push_back(new Circle);
// Copy
else if(i == 8)
{
// 복사할 인덱스 입력 받기
int index = 0;
cout << "Input index to copy : ";
cin >> index;
v.push_back(v[index]->Clone());
}
else if(i == 9)
{
// 각 객체 별로 자신의 클래스에 맞는 Draw()를 호출한다.
for(auto p : v) p->Draw();
}
else if(i ==0)
break;
}
return 0;
}
/*
* Template method 기법
* - 모든 도형에 공통적으로 변하지 않는 전체적인 흐름을 기반 클래스에서 제공하고
* - 각 도형 별로 변해야 하는 부분을 가상 함수로 제공해서 파생 클래스가 재정의 할 수 있게 한다.
*/
반응형