Pattern/C++

[C++] 컴포짓 패턴 (Composite pattern)

dpswlsldj 2021. 4. 7. 00:26
728x90

객체의 포함관계를 나타내는 패턴입니다.

객체들의 관계를 트리 구조로 구성하여 부분-전체 계층을 표현하는 패턴으로, 사용자가 단일 객체와 복합 객체 모두 동일하게 다루도록 한다.

https://ko.wikipedia.org/wiki/%EC%BB%B4%ED%8F%AC%EC%A7%80%ED%8A%B8_%ED%8C%A8%ED%84%B4

 

https://commons.wikimedia.org/wiki/File:Composite_UML_class_diagram_(fixed).svg

위의 코드를 구현해 보겠습니다.

 

간단히 아래와 같이 마우스 우클릭 메뉴라고 상상해보시면 됩니다.

 

 

Component는 Composite와 Leaf를 동일한 목적으로 사용하기 위해 만든 공통의 조상 클래스 입니다.

 

Leaf 클래스는 는 하위 메뉴가 없는 선택 가능한 메뉴로 operation() 을 수행합니다.

 

Composite 클래스는 add()와 remove()로 하위 메뉴를 추가하거나 삭제할 수 있고, operation() 을 수행합니다.

 

여기서 각각 객체를 만든다고 하면, Composite를 복합 객체, Leaf를 개별 객체라고 부를 수 있습니다.

 

Composite 패턴은 다음 두 가지 조건을 만족해야 합니다.

 

  1. 복합 객체와 개별 객체가 공통의 조상 클래스(여기서는 Component)를 가지고 있어야 합니다.
  2. 복합 객체와 개별 객체는 사용하는 방법이 동일해야 하며 동일한 동작을 수행하는 함수(여기서는 operation())는 조상 클래스에 위치해야 합니다.
#include <iostream>
#include <vector>

using namespace std;

class Component {
public:
	virtual void operation() = 0;
	virtual ~Component() {}
};

class Leaf : public Component {
private:
	int mValue;
public:
	Leaf(int value) : mValue(value) {

	}

	void operation() override {
		cout << "Leaf's operation [ " << mValue << " ]" << endl;
	}
};

class Composite : public Component {
private:
	vector <Component*> v;
	string mValue;
public:
	Composite(string value) : mValue(value) {

	}

	void operation() override  {
		cout << "Composite's operation [ " << mValue << " ]" << endl;
	}

	void add(Component* component) {
		v.push_back(component);
	}

	void remove() {
		v.pop_back();
	}

	void getChild() {
		for (vector<Component*>::const_iterator iter = v.begin(); iter != v.end(); iter++) {
			(*iter)->operation();
		}
	}


};

int main() {
	Composite container1("Container 1");
	Composite container2("Container 2");

	Leaf leaf1(1);
	Leaf leaf2(2);
	Leaf leaf3(3);
	Leaf leaf4(4);
	Leaf leaf5(5);
	Leaf leaf6(6);

	container1.add(&leaf1);
	container1.add(&leaf2);

	container2.add(&leaf3);
	container2.add(&leaf4);
	container2.add(&leaf5);
	container2.add(&leaf6);

	container1.add(&container2);

	container1.getChild();
	cout << endl;
	container2.getChild();
}

실행결과