-----------------------------------------------------------------------------
[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