본문 바로가기

Programing/Design Pattern

shape #2

728x90

 

 

 

https://www.ecourse.co.kr/courses/cpp_designpattern/lessons/shape-example/#tab-201452

 

#include <iostream>
#include <vector>

class Shape
{
public:
	virtual void draw() = 0;
	virtual ~Shape() { }
};

class Rect : public Shape
{
public:
	void draw() override { std::cout << "draw Rect" << std::endl; }
};

class Circle : public Shape
{
public:
	void draw() override { std::cout << "draw Circle" << std::endl; }
};

int main()
{
	std::vector<Shape*> v;

	while (true)
	{
		int cmd;
		std::cin >> cmd;

		if (cmd == 1) v.push_back(new Rect);
		else if (cmd == 2) v.push_back(new Circle);
		else if (cmd == 8)
		{
			std::cout << "몇번째 도형을 복제 할까요 >> ";
			int k;
			std::cin >> k;

			//...
		}
	}

	return 0;
}

 

위와 같이 Shape을 상속받는 Rect와 Circle이 있고, cmd로 8을 입력받았을 때 (zero-base 기준으로) vector의 k번째 도형을 복사해서 vector에 추가해주는 기능을 구현해야 한다고 가정해 보자.

 

int main()
{
	//...

	while (true)
	{
		//...
        
		else if (cmd == 8)
		{
			std::cout << "몇번째 도형을 복제 할까요 >> ";
			int k;
			std::cin >> k;

			if (dynamic_cast<Rect*>(v[k]) != nullptr)
			{
				//...
			}
			else if (dynamic_cast<Circle*>(v[k]) != nullptr)
			{
				//...
			}
		}
	}

	//...
}

 

먼저 dynamic_cast를 이용해서 타입을 조사한 후 기능을 수행하는 방식을 생각해 볼 수 있는데, 새로운 도형(가령 Triangle)이 추가되면 해당 부분의 코드 수정도 이뤄져야 하기 때문에 이 경우엔 OCP 원칙을 위반하게 된다. 

 

class Shape
{
public:
	//...

	virtual Shape* Clone() const = 0
};

class Rect : public Shape
{
public:
	//...

	Rect* Clone() const override
	{
		return new Rect(*this);
	}
};

class Circle : public Shape
{
public:
	//...

	Circle* Clone() const override
	{
		return new Circle(*this);
	}
};
int main()
{
	//...

	while (true)
	{
		//...
        
		else if (cmd == 8)
		{
			std::cout << "몇번째 도형을 복제 할까요 >> ";
			int k;
			std::cin >> k;

			v.push_back(v[k]->Clone());
		}
	}

	//...
}

 

다음으로 복사 생성자를 이용해 자기 자신을 복사한 후 반환하는 기능을 하는 가상 함수 Clone을 추가하는 방법이 있다. 이를 통해 OCP를 만족하는 코드를 작성할 수 있다. 이와 같은 방식으로 기존 객체를 복사해 새로운 객체를 생성하는 패턴을 prototype 패턴이라고 한다.

 

(참고로 리팩토링 용어 중에도 'Replace Conditional with Polymorphism'이라는 개념이 있는데, 이는 OCP를 충족시키기 위해 제어문을 사용하기보다는 다형성을 활용하라는 의미이다.)

 

 

 

728x90

'Programing > Design Pattern' 카테고리의 다른 글

template method  (0) 2025.02.10
adapter #1  (0) 2025.02.09
dynamic_casting  (0) 2025.01.17
upcasting  (0) 2025.01.17
constructor  (0) 2025.01.16