2015년 12월 27일 일요일

Composite Pattern (복합체 패턴)

의도
  • 각각의 단일 객체와 복합체를 한 종류의 클래스로 설계하여 사용자는 단일 객체든 복합체든 상관없이 똑같이 다룰 수 있는 편리함을 부여하는 패턴
이럴 때 사용하자.
  • 부분-전체의 객체 계등을 표현하고 싶을 때
  • 사용자가 객체의 합성으로 생긴 복합 객체와 개개의 객체 사이의 차이를 알지 않고도 자기 일을 할 수 있도록 만들고 싶을 때
장점은?
  • 기본 객체와 복합 객체로 구성된 하나의 일관된 클래스를 정의함으로써 기본, 복합 구분하지 않고 일관되게 프로그래밍할 수 있음
  • 사용자 코드가 단순해짐
  • 새로운 요소를 쉽게 추가할 수 있음
단점은?
  • 복합체의 구성요소의 제약을 가하기 힘듦
코드
Component 클래스
class Component
{
public:
   virtual void Operation() = 0;
   virtual void Add(Component* pComponent) {};
   virtual void Remove(Component* pComponent) {};
   virtual Component* GetChild(int i) { return 0; };
};

Leaf1, Leaf2 클래스
class Leaf1 : public Component
{
public:
   virtual void Operation() {
      cout << "Leaf1 operation.." << endl;
   };
};

class Leaf2 : public Component
{
public:
   virtual void Operation() {
      cout << "Leaf2 operation.." << endl;
   };
};

Composite 클래스
class Composite : public Component
{
public:
   virtual void Operation() {
      for each (Component* pComponent in m_listComponent) {
         pComponent->Operation();
      }
   };
   virtual void Add(Component* pComponent) {
      m_listComponent.push_back(pComponent);
   };
   virtual void Remove(Component* pComponent) {
      m_listComponent.remove(pComponent);

   };
   virtual Component* GetChild(int i) {
      int nCnt = 0;
      for (auto iter = m_listComponent.begin(); iter != m_listComponent.end(); iter++, nCnt++) {
         if (i == nCnt) return *iter;
      }
      return NULL;
   };
private:
   list<Component*> m_listComponent;
};

실행부분
void main()
{
   Leaf1 leaf1;
   Leaf2 leaf2;
   Composite composite;

   composite.Add(&leaf1);
   composite.Add(&leaf2);

   composite.Operation();
}

UML - class 다이어그램

참고
  • GoF의 디자인 패턴(개정판) 재사용성을 지닌 객체지향 소프트웨어의 핵심요소
  • http://copynull.tistory.com/135

댓글 없음:

댓글 쓰기

참고: 블로그의 회원만 댓글을 작성할 수 있습니다.