구조패턴-Composite

2008. 8. 5. 00:15 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Composite]
의도:
부분-전체 계층을 나타내기 위핸 복합 객체를 트리 구조로 만든다.
Composite 패턴은 클라이언트가 개별적 객체와 복합 객체 모두를 동일하게 다루도록
한다.

설명:
순환구조일때 즉, Compoiste구조에서 A와 B가 있을때 A는 B를 Child 객체로 소유하고, 또한
B가 A를 Child로 소유하고 있을 경우 A와 B가 Handle로 구현되어있는 경우 서로 Reference-
Counting으로 관계가 있기 때문에 Memory Leak이 생길 수 있다.  이를 해결하기 위해서는
Gabege-collector를 구현해야 하는데, 그냥 Handle로 안하는 것이 정신 건강에 이롭다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Structural part of GoF's Design Patterns
//
// - Composite
//
/////////////////////////////////////////////////////////////////////////////


#include <windows.h>
#include <tchar.h>

#include <list>
#include <string>
#include <algorithm>
#include <iostream>
#include <deque>


/////////////////////////////////////////////////////////////////////////////
//
// Composite
//
/////////////////////////////////////////////////////////////////////////////
class Composite;

class Component
{
public:
 explicit Component (const std::string name) : name_ (name)
 {
 }

public:
 virtual Composite* GetComposite (void)
 {
  return 0;
 }

 virtual void Add   (Component* c) {};
 virtual void Remove(Component* c) {};

public:
 virtual std::string GetName (void) const { return name_; }

protected:
 std::string name_;
};

class Composite : public Component
{
public:
 explicit Composite (const std::string name) : Component(name) {}

public:
 virtual Composite* GetComposite (void)
 {
  return this;
 }

public:
 virtual void Add (Component* c)
 {
  components_.push_back (c);
 };

 virtual void Remove(Component* c)
 {
  components_.remove (c);
 };

 virtual std::list<Component*>* GetChilds (void)
 {
  return &components_;
 }

protected:
 std::list <Component*> components_;
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
/////////////////////////////////////////////////////////////////////////////
void ShowComposite (Composite* composite, int indent)
{
 int i;

 for (i=0; i<indent; i++)
  std::cout << "   ";

 std::cout << "[" << composite->GetName() << "]" << std::endl;

 std::list <Component*>::iterator child;

 indent++;
 for (child=composite->GetChilds()->begin();
      child!=composite->GetChilds()->end();
      child++)
 {
  if (0==(*child)->GetComposite())
  {
   for (i=0; i<indent; i++)
    std::cout << "   ";
   std::cout << (*child)->GetName() << std::endl;
  }
  else
  {
   ShowComposite ((*child)->GetComposite(), indent);
  }
 }
 indent--;
}

int _tmain (int argc, _TCHAR* argv[])
{
 Composite Root ("Root");
 Composite Sub1 ("Sub1");
 Composite Sub2 ("Sub2");
 Component Item1("Item1");
 Component Item2("Item2");
 Component Item3("Item3");
 Component Item4("Item4");
 Component Item5("Item5");

 Root.Add (&Sub1);
 Root.Add (&Sub2);
 Root.Add (&Item1);

 Sub1.Add (&Item2);
 Sub1.Add (&Item3);

 Sub2.Add (&Item4);
 Sub2.Add (&Item5);

 ShowComposite (&Root, 0);

 return 0;
}
-----------------------------------------------------------------------------
[Root]
   [Sub1]
      Item2
      Item3
   [Sub2]
      Item4
      Item5
   Item1

Posted by 셈말짓기 :