2008/08/04~2008/08/25

GoF's Design Patterns를 다시 공부하면서 그 동안 만들어 놓은 Sample들이다.

UML로 표시된 구조를 가급적 맞추려고 노력해서 실제 Pattern들이 의미하는 바를 표현하기에는 역부족이다.

Sample Code를 보면서 구조는 쉽게 이해는 할 수 있을지 몰라도 Pattern들의 실제적인 의미나 사용을 하기
위해서는 책을 참고하는 것이 도움이 될 것 이다.


Posted by 셈말짓기 :

행위패턴-Interpreter

2008. 8. 25. 16:32 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Interpreter]
의도:
어떤 언어는 문법에 대한 표현을 정의하면서 그 언어로 기술된 문장을 해석하는 기법을 표현하기
위해서 인터프리터도 함께 정의하는 경우가 있다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Behavioral part of GoF's Design Patterns
//
// - Interpreter
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <string>
#include <list>
#include <deque>
#include <vector>
#include <map>
#include <iostream>


/////////////////////////////////////////////////////////////////////////////
//
// Interpreter
//
//
/////////////////////////////////////////////////////////////////////////////
class Context
{
public:
 std::map<std::string, bool> Variables_;
};

class AbstractExpression
{    
public:
 virtual bool Interpret(Context&) = 0;
};

class TerminalExpression_Variable: public AbstractExpression
{    
public:
 explicit TerminalExpression_Variable (std::string n) : Name_(n)
 {
 }

public:
 virtual bool Interpret(Context& context)
 {   
  return context.Variables_[Name_];
 }

private:
 std::string Name_;
};

class NonterminalExpression_And: public AbstractExpression
{
public:
 NonterminalExpression_And (AbstractExpression* p1, AbstractExpression* p2) :
  Operand1_(p1),
  Operand2_(p2)
 {
 }

public:
 virtual bool Interpret(Context& context)
 {
  return Operand1_->Interpret(context) && Operand2_->Interpret(context);
 }

private:
 AbstractExpression* Operand1_;
 AbstractExpression* Operand2_;
};

class NonterminalExpression_Or: public AbstractExpression
{
public:
 NonterminalExpression_Or (AbstractExpression* p1, AbstractExpression* p2) :
  Operand1_(p1),
  Operand2_(p2)
 {
 }

public:
 virtual bool Interpret(Context& context)
 {
  return Operand1_->Interpret(context) || Operand2_->Interpret(context);
 }

private:
 AbstractExpression* Operand1_;
 AbstractExpression* Operand2_;
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
bool _tmain(bool argc, _TCHAR* argv[])
{
 Context context;

 context.Variables_["A"] = 1;
 context.Variables_["B"] = 1;
 context.Variables_["C"] = 0;


 TerminalExpression_Variable a("A");
 TerminalExpression_Variable b("B");
 TerminalExpression_Variable c("C");


 NonterminalExpression_Or  exp1 (&a,    &b);
 NonterminalExpression_And exp2 (&exp1, &c);


 bool result = exp2.Interpret(context);

 std::cout << "result=" << result << std::endl;

 return 0;
};
-----------------------------------------------------------------------------
result=0

Posted by 셈말짓기 :

생성패턴-Singleton

2008. 8. 23. 19:22 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Singleton]
의도:
클래스에서 만들 수 있는 인스턴스가 오직 하나일 경우에 이에 대한 접근은 어디에서든지
하나로만 통일하여 제공한다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A creational part of GoF's Design Patterns
//
// - Singleton
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>


/////////////////////////////////////////////////////////////////////////////
//
// Singleton
//
//
/////////////////////////////////////////////////////////////////////////////
class Singleton
{
protected:
 Singleton () {}
public:
 virtual ~Singleton() {}

public:
 static Singleton& Instance(void)
 {
  if (Instance_.get() == 0)
  {
   Instance_.reset( new Singleton() );
  }

  return *Instance_;
 }

private:
 static std::auto_ptr<Singleton> Instance_;

public:
 void Operation (void)
 {
  std::cout << "Singleton::Operation()" << std::endl;
 }
};

std::auto_ptr<Singleton> Singleton::Instance_;


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 Singleton::Instance().Operation();

 return 0;
}
-----------------------------------------------------------------------------
Singleton::Operation()

Posted by 셈말짓기 :

생성패턴-Prototype

2008. 8. 23. 18:52 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Prototype]
의도:
견본적(prototypical) 인스턴스를 사용하여 생성할 객체의 종류를 명시하고 이렇게 만들어진
견본을 복사해서 새로운 객체를 생성한다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A creational part of GoF's Design Patterns
//
// - Prototype
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>



/////////////////////////////////////////////////////////////////////////////
//
// Prototype
//
//
/////////////////////////////////////////////////////////////////////////////
class Product
{
public:
 Product()          {}
 virtual ~Product() {}

public:
 virtual Product* Clone (void) = 0;
 virtual void     Show  (void) = 0;
};

class ConcreteProductA : public Product
{
public:
 explicit ConcreteProductA(int v) : Value_(v) {}
 virtual ~ConcreteProductA() {}

public:
 virtual Product* Clone (void)
 {
  return new ConcreteProductA(Value_);
 }
 virtual void Show (void)
 {
  std::cout << "ConcreteProductA::Show(): " << Value_ << std::endl;
 }

private:
 int Value_;
};

class ConcreteProductB : public Product
{
public:
 explicit ConcreteProductB(int v) : Value_(v) {}
 virtual ~ConcreteProductB() {}

public:
 virtual Product* Clone (void)
 {
  return new ConcreteProductB(Value_);
 }
 virtual void Show (void)
 {
  std::cout << "ConcreteProductB::Show(): " << Value_ << std::endl;
 }

private:
 int Value_;
};


/////////////////////////////////////////////////////////////////////////////
//
// Factory
//
//
/////////////////////////////////////////////////////////////////////////////
class ProductFactory
{
public:
 ProductFactory()
 {
  ProductA_.reset ( new ConcreteProductA(100) );
  ProductB_.reset ( new ConcreteProductB(200) );
 }

public:
 Product* CreateA (void)
 {
  return ProductA_->Clone();
 }

 Product* CreateB (void)
 {
  return ProductB_->Clone();
 }

private:
 std::auto_ptr<Product> ProductA_;
 std::auto_ptr<Product> ProductB_;
};
 


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 std::auto_ptr<Product>  p;
 ProductFactory          f;


 p.reset ( f.CreateA() );
 p->Show();

 std::cout << std::endl;

 p.reset ( f.CreateB() );
 p->Show();
 
 return 0;
}
-----------------------------------------------------------------------------
ConcreteProductA::Show(): 100

ConcreteProductB::Show(): 200

Posted by 셈말짓기 :

-----------------------------------------------------------------------------
[Factory Method]
의도:
객체를 생성하기 위해 인터페이스를 정의하지만, 어떤 클래스의 인스턴스를 생성할지에 대한
결정은 서브클래스에서 이루어지도록 Factory Method 패턴은 서브클래스에게 인스턴스 생성의
책임을 미룬다.

다른 이름:
Virtual Constructor
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A creational part of GoF's Design Patterns
//
// - Factory Method
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>


/////////////////////////////////////////////////////////////////////////////
//
// Product
//
//
/////////////////////////////////////////////////////////////////////////////
class Product
{
public:
 Product()          {}
 virtual ~Product() {}

public:
 virtual void Operation (void) = 0;
};

class ConcreteProductA : public Product
{
public:
 ConcreteProductA(){}
 virtual ~ConcreteProductA() {}

public:
 virtual void Operation (void)
 {
  std::cout << "ConcreteProductA::Operation()" << std::endl;
 }
};

class ConcreteProductB : public Product
{
public:
 ConcreteProductB(){}
 virtual ~ConcreteProductB() {}

public:
 virtual void Operation (void)
 {
  std::cout << "ConcreteProductB::Operation()" << std::endl;
 }
};

class ConcreteProductB_2 : public Product
{
public:
 ConcreteProductB_2(){}
 virtual ~ConcreteProductB_2() {}

public:
 virtual void Operation (void)
 {
  std::cout << "ConcreteProductB_2::Operation()" << std::endl;
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Factory Method
//
//
/////////////////////////////////////////////////////////////////////////////
enum ProductID
{
 Id_ConcreteProductA,
 Id_ConcreteProductB
};

class Createor
{
public:
 virtual ~Createor() {}

public:
 virtual std::auto_ptr<Product> Create (ProductID id)
 {
  if (Id_ConcreteProductA==id)
   return std::auto_ptr<Product> ( new ConcreteProductA() );

  if (Id_ConcreteProductB==id)
   return std::auto_ptr<Product> ( new ConcreteProductB() );

  return std::auto_ptr<Product>();
 }
};

class ConcreteCreateor : public Createor
{
public:
 virtual std::auto_ptr<Product> Create (ProductID id)
 {
  if (Id_ConcreteProductB==id)
   return std::auto_ptr<Product> ( new ConcreteProductB_2() );

  return Createor::Create(id);
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 std::auto_ptr<Createor> c;
 std::auto_ptr<Product>  p;


 std::cout << "Created by Createor()" << std::endl;
 c.reset ( new Createor() );

 p = c->Create ( Id_ConcreteProductA );
 p->Operation ();

 p = c->Create ( Id_ConcreteProductB );
 p->Operation ();
 std::cout << std::endl;


 std::cout << "Created by ConcreteCreateor()" << std::endl;
 c.reset ( new ConcreteCreateor() );

 p = c->Create ( Id_ConcreteProductA );
 p->Operation ();

 p = c->Create ( Id_ConcreteProductB );
 p->Operation ();
 std::cout << std::endl;

 return 0;
}
-----------------------------------------------------------------------------
Created by Createor()
ConcreteProductA::Operation()
ConcreteProductB::Operation()

Created by ConcreteCreateor()
ConcreteProductA::Operation()
ConcreteProductB_2::Operation()



Posted by 셈말짓기 :

생성패턴-Builder

2008. 8. 20. 14:21 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Builder]
-----------------------------------------------------------------------------
복잡한 객체를 생성하는 방법과 표현하는 방법을 정의하는 클래스를 별도로 분리하여 서로 다른
표현이라도 이를 생성할 수 있는 동일한 구축 공정을 제공할 수 있도록 한다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A creational part of GoF's Design Patterns
//
// - Builder
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>



/////////////////////////////////////////////////////////////////////////////
//
// A creational part of GoF's Design Patterns
//
// - Builder
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>


/////////////////////////////////////////////////////////////////////////////
//
// Builder
//
//
/////////////////////////////////////////////////////////////////////////////
class Product
{
public:
 Product() :
  PartA_(0),
  PartB_(0),
  PartC_(0)
 {
 }

 virtual ~Product()
 {
 }

public:
 void SetPartA  (int a) { PartA_= a; }
 void SetPartB  (int b) { PartB_= b; }
 void SetPartC  (int c) { PartC_= c; }

 void Operation (void)
 {
    std::cout << "[Product]" << std::endl
        << "PartA=" << PartA_ << std::endl
        << "PartB=" << PartB_ << std::endl
        << "PartC=" << PartC_ << std::endl
        << std::endl;
 }

private:
 int PartA_;
 int PartB_;
 int PartC_;
};

//// ------------------------------------------------------------------------

class AbstractBuilder
{
public:
 virtual ~AbstractBuilder() {}

public:
 std::auto_ptr<Product> GetResult (void)
 {
  return Product_;
 }
 
 void NewProduct (void)
 {
  Product_.reset ( new Product() );
 }

public:
 virtual void BuildPartA (void)=0;
 virtual void BuildPartB (void)=0;
 virtual void BuildPartC (void)=0;

protected:
 std::auto_ptr<Product> Product_;
};

class ConcreteBuilderA : public AbstractBuilder
{
public:
 virtual void BuildPartA (void) { Product_->SetPartA(1); }
 virtual void BuildPartB (void) { Product_->SetPartB(2); }
 virtual void BuildPartC (void) { Product_->SetPartC(3); }
};

class ConcreteBuilderB : public AbstractBuilder
{
public:
 virtual void BuildPartA (void) { Product_->SetPartA(4); }
 virtual void BuildPartB (void) { Product_->SetPartB(5); }
 virtual void BuildPartC (void) { Product_->SetPartC(6); }
};

//// ------------------------------------------------------------------------

class Director
{
public:
 Director() : Builder_(0) {}
 virtual ~Director()      {}
 
public:
 void SetBuilder (AbstractBuilder* b)
 {
  Builder_ = b;
 }

 void Construct (void)
 {
  Builder_->NewProduct ();
  Builder_->BuildPartA ();
  Builder_->BuildPartB ();
  Builder_->BuildPartC ();
 }

private:
 AbstractBuilder* Builder_;
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 Director               director;
 ConcreteBuilderA       builder_A;
 ConcreteBuilderB       builder_B;
 std::auto_ptr<Product> product;


 director.SetBuilder (&builder_A);
 director.Construct  ();
 product = builder_A.GetResult();
 product->Operation();

 director.SetBuilder (&builder_B);
 director.Construct  ();
 product = builder_B.GetResult();
 product->Operation();

 return 0;
}

-----------------------------------------------------------------------------
[Product]
PartA=1
PartB=2
PartC=3

[Product]
PartA=4
PartB=5
PartC=6

Posted by 셈말짓기 :

-----------------------------------------------------------------------------
[Abstract Factory]
의도:
구체적 클래스를 정의하지 않고도 서로 관련성이 있거나 독립적인 여러 객체의 군을 생성하기
위한 인터페이스를 제공한다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A creational part of GoF's Design Patterns
//
// - Abstract Factory
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>


/////////////////////////////////////////////////////////////////////////////
//
// Abstract Factory
//
//
/////////////////////////////////////////////////////////////////////////////
class AbstractProdcutA
{
public:
 AbstractProdcutA ()         {}
 virtual ~AbstractProdcutA() {}
};

class AbstractProdcutB
{
public:
 AbstractProdcutB ()         {}
 virtual ~AbstractProdcutB() {}
};
 
class AbstractFactory
{
public:
 virtual AbstractProdcutA* CreateProductA (void) = 0;
 virtual AbstractProdcutB* CreateProductB (void) = 0;
};

//// ------------------------------------------------------------------------

class ProdcutA1 : public AbstractProdcutA
{
public:
 ProdcutA1()
 {
  std::cout << "ProdcutA1()" << std::endl;
 }
};
class ProdcutA2 : public AbstractProdcutA
{
public:
 ProdcutA2()
 {
  std::cout << "ProdcutA2()" << std::endl;
 }
};
class ProdcutB1 : public AbstractProdcutB
{
public:
 ProdcutB1()
 {
  std::cout << "ProdcutB1()" << std::endl;
 }
};
class ProdcutB2 : public AbstractProdcutB
{
public:
 ProdcutB2()
 {
  std::cout << "ProdcutB2()" << std::endl;
 }
};

//// ------------------------------------------------------------------------

class ConcreteFactory1 : public AbstractFactory
{
public:
 virtual AbstractProdcutA* CreateProductA (void)
 {
  return new ProdcutA1();
 }
 virtual AbstractProdcutB* CreateProductB (void)
 {
  return new ProdcutB1();
 }
};

class ConcreteFactory2 : public AbstractFactory
{
 virtual AbstractProdcutA* CreateProductA (void)
 {
  return new ProdcutA2();
 }
 virtual AbstractProdcutB* CreateProductB (void)
 {
  return new ProdcutB2();
 }
};

//// ------------------------------------------------------------------------

class Client
{
public:
 void Create (AbstractFactory *f)
 {
  ProdcutA_.reset( f->CreateProductA() );
  ProdcutB_.reset( f->CreateProductB() );
 }

private:
 std::auto_ptr<AbstractProdcutA> ProdcutA_;
 std::auto_ptr<AbstractProdcutB> ProdcutB_;
};



/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 Client client;


 std::cout << "by ConcreteFactory1" << std::endl;
 client.Create ( &ConcreteFactory1() );

 std::cout << std::endl;

 std::cout << "by ConcreteFactory2" << std::endl;
 client.Create ( &ConcreteFactory2() );

 return 0;
}
-----------------------------------------------------------------------------
by ConcreteFactory1
ProdcutA1()
ProdcutB1()

by ConcreteFactory2
ProdcutA2()
ProdcutB2()

Posted by 셈말짓기 :

구조패턴-Proxy

2008. 8. 19. 16:04 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Proxy]
의도:
다른 객체에 접근하기 위해 중간 대리 역활을 하는 객체를 둔다.

다른 이름:
Surrogate
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Structural part of GoF's Design Patterns
//
// - Proxy
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>
#include <map>
#include <string>
#include <list>
#include <algorithm>


#define USE_HANDLE 1


#if (USE_HANDLE==1)
/////////////////////////////////////////////////////////////////////////////
//
// Handle
//
/////////////////////////////////////////////////////////////////////////////
template<typename T>
class CRefCountedInstance
{
public:
 CRefCountedInstance ();

public:
 inline void AddRef       (void);
 inline void Release      (void);
 inline void Assign       (T *p);
 inline bool IsReferenced (void);
 inline T*   GetInstance  (void);

private:
 T   *Instance_;
 int  RefCount_;
};

template<typename T>
CRefCountedInstance<T>::CRefCountedInstance () :
 RefCount_ (0),
 Instance_ (0)
{
}

template<typename T>
void CRefCountedInstance<T>::AddRef (void)
{
 RefCount_++;
}

template<typename T>
void CRefCountedInstance<T>::Release (void)
{
 if (RefCount_>0)
 {
  RefCount_--;
 }

 if (RefCount_==0)
 {
  if (Instance_)
  {
   delete Instance_;
  }

  Instance_ = 0;
 }
}

template<typename T>
void CRefCountedInstance<T>::Assign (T *p)
{
 Instance_ = p;
 AddRef ();
}

template<typename T>
bool CRefCountedInstance<T>::IsReferenced (void)
{
 if (RefCount_==0)
  return false;

 return true;
}

template<typename T>
T* CRefCountedInstance<T>::GetInstance (void)
{
 return Instance_;
}

template<typename T>
class Handle
{
public:
 Handle ();
 explicit Handle (T *p);
 Handle (const Handle<T> &copy);
 virtual ~Handle ();

public:
 Handle<T>& operator = (const Handle<T>& rhs);

public:
 inline T& operator*  () const;
 inline T* operator-> () const;
 inline T* Get    (void) const;

private:
 CRefCountedInstance<T>* Rep_;
};

template<typename T>
Handle<T>::Handle () : Rep_(0)
{
}

template<typename T>
Handle<T>::Handle (T *p)
{
 Rep_ = new CRefCountedInstance<T>();
 Rep_->Assign(p);
}

template<typename T>
Handle<T>::Handle (const Handle<T> &copy)
{
 Rep_ = copy.Rep_;

 if (Rep_)
  Rep_->AddRef ();
}

template<typename T>
Handle<T>::~Handle ()
{
 if (Rep_)
 {
  Rep_->Release ();

  if (!Rep_->IsReferenced())
   delete Rep_;
 }
}

template<typename T>
Handle<T>& Handle<T>::operator = (const Handle<T>& rhs)
{
 if (this == &rhs) return *this;

 if (Rep_)
  Rep_->Release ();

 Rep_ = rhs.Rep_;

 if (Rep_)
  Rep_->AddRef ();

 return *this;
}

template<typename T>
T& Handle<T>::operator*() const
{
 return *(Rep_->GetInstance());
}

template<typename T>
T* Handle<T>::operator -> () const
{
 if (Rep_==0)
  return 0;

 return (Rep_->GetInstance());
}

template<typename T>
T* Handle<T>::Get (void) const
{
 if (Rep_==0)
  return 0;

 return (Rep_->GetInstance());
}
#endif


/////////////////////////////////////////////////////////////////////////////
//
// Proxy
//
/////////////////////////////////////////////////////////////////////////////
class Subject
{
public:
 virtual ~Subject() {}

public:
 virtual void Request (void) = 0;
 virtual void SetData (int ) = 0;
};

class RealSubject : public Subject
{
public:
 explicit RealSubject (int n) :
  Data_ (n)
 {
  std::cout << "RealSubject::RealSubject(" << Data_ << ")" << std::endl;
 }

 virtual ~RealSubject ()
 {
  std::cout << "RealSubject::~RealSubject(" << Data_ << ")" << std::endl;
 }

public:
 virtual void Request (void)
 {
  std::cout << "RealSubject::Request(): Data_ = " << Data_ << std::endl;
 }

 virtual void SetData (int n)
 {
  Data_ = n;
 }

private:
 int Data_;
};


#if (USE_HANDLE==1)
class Proxy :
 public Subject
{
public:
 Proxy() : SubjectData_(0)
 {
 }

 explicit Proxy (int n) :
  SubjectData_ (n)
 {
 }

 Proxy (const Proxy &copy)
 {
  const_cast<Proxy&>(copy).Load();

  SubjectData_ = copy.SubjectData_;
  Subject_     = copy.Subject_;
 }

 virtual ~Proxy () {}

public:
 virtual void Request (void)
 {
  GetSubject()->Request();
 }

 virtual void SetData (int n)
 {
  GetSubject()->SetData(n);
 }

private:
 Subject* GetSubject (void)
 {
  if (Subject_.Get()==0)
  {
   Handle<Subject> s ( new RealSubject(SubjectData_) );
   Subject_ = s;
  }

  return Subject_.Get();
 }

public:
 void Load (void)
 {
  GetSubject();
 }

public:
 Proxy& operator = (const Proxy& rhs)
 {
  if (this == &rhs) return *this;

  const_cast<Proxy&>(rhs).Load();

  SubjectData_ = rhs.SubjectData_;
  Subject_     = rhs.Subject_;

  return *this;
 }

private:
 Handle<Subject>  Subject_;
 int              SubjectData_;
};
#else
class Proxy :
 public Subject
{
public:
 Proxy() :
  SubjectData_(0), 
  Subject_    (0)
 {
 }

 explicit Proxy (int n) :
 SubjectData_ (n),
  Subject_     (0)
 {
 }

 virtual ~Proxy ()
 {
  if (Subject_)
   delete Subject_;
 }

public:
 virtual void Request (void)
 {
  GetSubject()->Request();
 }

 virtual void SetData (int n)
 {
  GetSubject()->SetData(n);
 }

private:
 Subject* GetSubject (void)
 {
  if (Subject_==0)
  {
   Subject_ = new RealSubject(SubjectData_);
  }
  return Subject_;
 }

private:
 Subject         *Subject_;
 int              SubjectData_;
};
#endif


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
#if (USE_HANDLE==1)
 std::cout << "(USE_HANDLE==1)" << std::endl << std::endl;

 Proxy a(1);
 Proxy b;
 Proxy c;


 std::cout << "a.Load();" << std::endl;
 //a.Load();
 std::cout << std::endl;


 std::cout << "b=a;" << std::endl;
 b=a;
 std::cout << std::endl;


 std::cout << "a.Request ();" << std::endl;
 a.Request ();
 std::cout << std::endl;


 std::cout << "a.SetData (2);" << std::endl;
 a.SetData (2);
 std::cout << std::endl;


 std::cout << "b.Request ();" << std::endl;
 b.Request ();
 std::cout << std::endl;


 std::cout << "c=a" << std::endl;
 c=a;
 std::cout << "c.Request()" << std::endl;
 c.Request ();
 std::cout << std::endl;
#else
 std::cout << "(USE_HANDLE==0)" << std::endl << std::endl;

 Proxy       a(1);
 RealSubject b(2);


 std::cout << std::endl;

 std::cout << "a.Request()" << std::endl;
 a.Request (); // late creating instance
 std::cout << std::endl;

 std::cout << "a.Request()" << std::endl;
 b.Request ();
 std::cout << std::endl;
#endif

 return 0;
}
-----------------------------------------------------------------------------
(USE_HANDLE==1)

a.Load();
RealSubject::RealSubject(1)

b=a;

a.Request ();
RealSubject::Request(): Data_ = 1

a.SetData (2);

b.Request ();
RealSubject::Request(): Data_ = 2

c=a
c.Request()
RealSubject::Request(): Data_ = 2

RealSubject::~RealSubject(2)
-----------------------------------------------------------------------------
(USE_HANDLE==0)

RealSubject::RealSubject(2)

a.Request()
RealSubject::RealSubject(1)
RealSubject::Request(): Data_ = 1

a.Request()
RealSubject::Request(): Data_ = 2

RealSubject::~RealSubject(2)
RealSubject::~RealSubject(1)

Posted by 셈말짓기 :

구조패턴-Flyweight

2008. 8. 19. 00:28 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Flyweight]
의도:
대규모의 미세한 객체들을 효과적으로 사용하기 위해서는 공유 개념을 도입
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Structural part of GoF's Design Patterns
//
// - Flyweight
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>
#include <map>
#include <string>
#include <list>
#include <algorithm>


/////////////////////////////////////////////////////////////////////////////
//
// Flyweight
//
/////////////////////////////////////////////////////////////////////////////
class Flyweight
{
public:
 virtual ~Flyweight() {}
public:
 virtual void Operation (void) = 0;
};

class ConcreteFlyweight : public Flyweight
{
public:
 ConcreteFlyweight (std::string s, int n) :
  Key_   (n),
  Value_ (s)
 {
 }

public:
 virtual void Operation (void)
 {
  std::cout << Value_.c_str() << "(" << Key_ << ")" << std::endl;
 }

private:
 int         Key_;
 std::string Value_;
};

class UnsharedConcreteFlyweight : public Flyweight
{
public:
 UnsharedConcreteFlyweight (std::string s) :
  Value_ (s)
 {
 }

public:
 virtual void Operation (void)
 {
  std::cout << Value_.c_str() << std::endl;
 }

private:
 std::string Value_;
};

//// ------------------------------------------------------------------------

class FlyweightFactory
{
private:
 struct PoolDeleter
 {
 public:
  PoolDeleter() : Count_(0) {}
 public:
  void operator()(std::pair<int,Flyweight*> i)
  {
   Flyweight *p = i.second;

   if (p)
   {
    Count_++;
    delete p;
   }
  }
  operator int ()
  {
   return Count_;
  }
 private:
  int Count_;
 };

public:
 virtual ~FlyweightFactory ()
 {
  int Count;

  Count = std::for_each(Pool_.begin(), Pool_.end(), PoolDeleter());
  std::cout << "~FlyweightFactory(): [ConcreteFlyweight] deleting count="
            << Count
            << std::endl
            << std::endl;
 }

public:
 Flyweight* GetFlyweight (std::string value, int key)
 {
  Flyweight*  f;

  if ( Pool_.end() == Pool_.find (key) )
  {
   f = new ConcreteFlyweight (value, key);
   Pool_[key] = f;
  }
  else
  {
   f = Pool_[key];
  }

  return f;
 }

 Flyweight* GetUnsharedFlyweight (std::string value)
 {
  Flyweight* f;

  f = new UnsharedConcreteFlyweight ( value );

  return f;
 }

private:
 std::map <int,Flyweight*> Pool_;
};

//// ------------------------------------------------------------------------

class Context
{
private:
 template<class T>
 struct OperationCaller : public std::unary_function<T, void>
 {
 public:
  void operator()(T ptr)
  {
   if (ptr)
    ptr->Operation();
  }
 };

 template<class T>
 struct ListDeleter : public std::unary_function<T, void>
 {
 public:
  ListDeleter() : Count_(0) {}
 public:
  void operator()(T ptr)
  {
   if (ptr)
   {
    if (dynamic_cast<UnsharedConcreteFlyweight*>(ptr))
    {
     Count_++;
     delete ptr;
    }
   }
  }
  operator int ()
  {
   return Count_;
  }
 private:
  int Count_;
 };

public:
 ~Context ()
 {
  int Count;

  Count = std::for_each(List_.begin(), List_.end(), ListDeleter<Flyweight*>());
  std::cout << "~Context(): [UnsharedConcreteFlyweight] deleting count="
            << Count
            << std::endl;
 }

public:
 void Add (std::string s, int n=0)
 {
  if (n)
   List_.push_back ( Factory_.GetFlyweight (s, n) );
  else
   List_.push_back ( Factory_.GetUnsharedFlyweight (s) );
 }

 void Operation (void)
 {
  std::for_each(List_.begin(), List_.end(), OperationCaller<Flyweight*>());  

  std::cout << std::endl;
 }

private:
 std::list<Flyweight*> List_;
 FlyweightFactory      Factory_;
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 Context context;

 context.Add ("one", 1);
 context.Add ("two"   );
 context.Add ("one", 1);
 context.Add ("two"   );
 context.Add ("one", 1);
 context.Add ("two"   );
 context.Add ("one", 1);
 context.Add ("two"   );
 context.Add ("one", 1);
 context.Add ("two"   );

 context.Operation ();

 return 0;
}
-----------------------------------------------------------------------------
one(1)
two
one(1)
two
one(1)
two
one(1)
two
one(1)
two

~Context(): [UnsharedConcreteFlyweight] deleting count=5
~FlyweightFactory(): [ConcreteFlyweight] deleting count=1


Posted by 셈말짓기 :

구조패턴-Facade

2008. 8. 18. 21:03 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Facade]
의도:
서브시스템을 합성하는 다수의 객체들의 인터페이스 집합에 대해 일관된 하나의 인터페이스를
제공할 수 있게 한다. Facade는 서브시스템을 사용하기 쉽게 하기 위한 포괄적 개념의 인터
페이스를 정의 한다.
-----------------------------------------------------------------------------/////////////////////////////////////////////////////////////////////////////
//
// A Structural part of GoF's Design Patterns
//
// - Facade
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>


/////////////////////////////////////////////////////////////////////////////
//
// Subsystem
//
/////////////////////////////////////////////////////////////////////////////
class SubsystemA
{
public:
 void OperationA (void)
 {
  std::cout << "\tSubsystemA::OperationA()" << std::endl;
 }
 void OperationB (void)
 {
  std::cout << "\tSubsystemA::OperationB()" << std::endl;
 }
};

class SubsystemB
{
public:
 void Operation (void)
 {
  std::cout << "\tSubsystemB::Operation()" << std::endl;
 }
};

class SubsystemC
{
public:
 void OperationA (void)
 {
  std::cout << "\tSubsystemC::OperationA()" << std::endl;
 }
 void OperationB (void)
 {
  std::cout << "\tSubsystemC::OperationB()" << std::endl;
 }
 void OperationC (void)
 {
  std::cout << "\tSubsystemC::OperationC()" << std::endl;
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Facade
//
/////////////////////////////////////////////////////////////////////////////
class Facade
{
public:
 void OperationA (void)
 {
  std::cout << "Facade::OperationA()" << std::endl;
  A_.OperationA();
  B_.Operation ();
  C_.OperationA();
  std::cout << std::endl;
 }

 void OperationB (void)
 {
  std::cout << "Facade::OperationB()" << std::endl;
  A_.OperationB();
  C_.OperationB();
  C_.OperationC();
  std::cout << std::endl;
 }

private:
 SubsystemA A_;
 SubsystemB B_;
 SubsystemC C_;
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 Facade f;

 f.OperationA();
 f.OperationB();

 return 0;
}
-----------------------------------------------------------------------------Facade::OperationA()
        SubsystemA::OperationA()
        SubsystemB::Operation()
        SubsystemC::OperationA()

Facade::OperationB()
        SubsystemA::OperationB()
        SubsystemC::OperationB()
        SubsystemC::OperationC()

Posted by 셈말짓기 :

구조패턴-Decorator

2008. 8. 18. 20:28 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Decorator]
의도:
객체에 동적으로 새로운 서비스를 추가할 수 있게 한다. Decorator패턴은 기능의 추가를
위해서 서브클래스를 생성하는 것보다 융통성 있는 방법을 제공한다.

다른 이름:
Wrapper
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Structural part of GoF's Design Patterns
//
// - Decorator
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>


/////////////////////////////////////////////////////////////////////////////
//
// Decorator
//
//
/////////////////////////////////////////////////////////////////////////////
class Component
{
public:
 virtual ~Component() {}

public:
 virtual void Operation (void) = 0;
};

class ConcreteComponent : public Component
{
public:
 virtual void Operation (void)
 {
  std::cout << "ConcreteComponent::Operation()" << std::endl;
 }
};

class Decorator : public Component
{
public:
 explicit Decorator (Component* p) :
  Component_(p)
 {
 }

public:
 virtual void Operation (void)
 {
  if (Component_.get())
   Component_->Operation ();
 }

private:
 std::auto_ptr<Component> Component_;
};

class ConcreteDecoratorA : public Decorator
{
public:
 explicit ConcreteDecoratorA (Component* p) :
  Decorator(p)
 {
 }

public:
 virtual void Operation (void)
 {
  Decorator::Operation();
  std::cout << "ConcreteDecoratorA::Operation()" << std::endl;
 }
};

class ConcreteDecoratorB : public Decorator
{
public:
 explicit ConcreteDecoratorB (Component* p) :
  Decorator(p)
 {
 }
public:
 virtual void Operation (void)
 {
  Decorator::Operation();
  std::cout << "ConcreteDecoratorB::Operation()" << std::endl;
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 std::auto_ptr<Component> p;
 
 p.reset( new ConcreteDecoratorB (
              new ConcreteDecoratorA (
                  new ConcreteComponent())) );

 p->Operation ();

 return 0;
}
-----------------------------------------------------------------------------
ConcreteComponent::Operation()
ConcreteDecoratorA::Operation()
ConcreteDecoratorB::Operation()

Posted by 셈말짓기 :

구조패턴-Bridge

2008. 8. 18. 17:38 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Bridge]
의도:
구현과 추상화 개념을 분리하려는 것이다. 이로써 구현 자체도 하나의 추상화 개념으로 다양한
변형이 가능해지고, 구현과 독립적으로 인터페이스도 다양함을 가질 수 있게 된다.

다른 이름:
Handle/body
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Structural part of GoF's Design Patterns
//
// - Bridge
//
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>

#include <iostream>
#include <memory>


/////////////////////////////////////////////////////////////////////////////
//
// Bridge
//
/////////////////////////////////////////////////////////////////////////////
class Implementor
{
public:
 virtual ~Implementor () {}
public:
 virtual void OperationImp (void) = 0;
};

class ConcreteImplementorA : public Implementor
{
public:
 virtual void OperationImp (void)
 {
  std::cout<< "ConcreteImplementorA::OperationImp()" << std::endl;
 }
};

class ConcreteImplementorB : public Implementor
{
public:
 virtual void OperationImp (void)
 {
  std::cout<< "ConcreteImplementorB::OperationImp()" << std::endl;
 }
};

class ImplementorFactory
{
private:
 ImplementorFactory(void) : Env_(0) {};
public:
 static ImplementorFactory* Instance (void)
 {
  if (0==Instance_)
  {
   Instance_ = new ImplementorFactory();
  }

  return Instance_;
 }

private:
 static ImplementorFactory* Instance_;

public:
 Implementor* CreateImplementor (void)
 {
  Implementor* p;
 
  if (Env_==0)
   p = new ConcreteImplementorA();
  else
   p = new ConcreteImplementorB();

  return p;
 }

public:
 void SetEnv (int e)
 {
  Env_ = e;
 }

 int  GetEnv (void)
 {
  return Env_;
 }

private:
 int Env_;
};

ImplementorFactory* ImplementorFactory::Instance_ = 0;

class Abstraction
{
public:
 Abstraction () : Imp_(0)
 {
 }

public:
 virtual void Operation (void)
 {
  GetImp ()->OperationImp();
 }

private:
 Implementor* GetImp (void)
 {
  if (Imp_==0)
  {
   Imp_ = ImplementorFactory::Instance()->CreateImplementor ();
  }

  return Imp_;
 }

private:
 Implementor *Imp_;
};

class RefinedAbstraction : public Abstraction
{
public:
 virtual void RefinedOperation (void)
 {
  Abstraction::Operation();
  std::cout<< "RefinedAbstraction::RefinedOperation()" << std::endl;
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 std::auto_ptr<RefinedAbstraction> p;


 p.reset ( new RefinedAbstraction() );
 p->RefinedOperation ();
 p.reset ();

 std::cout << std::endl;
 ImplementorFactory::Instance()->SetEnv (1);

 p.reset ( new RefinedAbstraction() );
 p->RefinedOperation ();
 p.reset ();

 return 0;
}
-----------------------------------------------------------------------------
ConcreteImplementorA::OperationImp()
RefinedAbstraction::RefinedOperation()

ConcreteImplementorB::OperationImp()
RefinedAbstraction::RefinedOperation()

Posted by 셈말짓기 :

구조패턴-Adapter

2008. 8. 17. 01:22 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Adapter]
의도:
클래스의 인터페이스를 클라이언트가 기대하는 형태의 인터페이스로 변환한다.
어댑터 패턴은 서로 일치하지 않는 인터페이스를 갖는 클래스들을 함께 작동 시킨다.

다른 이름:
Wrapper
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Structural part of GoF's Design Patterns
//
// - Adapter
//
/////////////////////////////////////////////////////////////////////////////

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

#include <iostream>
#include <memory>


/////////////////////////////////////////////////////////////////////////////
//
// Adapter-1
//
//
/////////////////////////////////////////////////////////////////////////////
class Target
{
public:
 virtual ~Target() {}
public:
 virtual void Request (void) = 0;
};

class Adaptee
{
public:
 void SpecificRequest (void)
 {
  std::cout << "Adaptee::SpecificRequest()" << std::endl;
 }
};

class Adapter_1 :
 public  Target,
 private Adaptee
{
public:
 virtual void Request (void)
 {
  std::cout << "Adaptee::SpecificRequest()" << std::endl;
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Adapter-2
//
//
/////////////////////////////////////////////////////////////////////////////
class Adapter_2 :
 public Target
{
public:
 virtual void Request (void)
 {
  Adaptee_.SpecificRequest();
 }
private:
 Adaptee Adaptee_;
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 std::auto_ptr<Target> t1 ( new Adapter_1() );
 std::auto_ptr<Target> t2 ( new Adapter_2() );

 t1->Request ();
 t2->Request ();

 return 0;
}
-----------------------------------------------------------------------------
Adaptee::SpecificRequest()
Adaptee::SpecificRequest()

Posted by 셈말짓기 :

행위패턴-Iterator

2008. 8. 16. 18:19 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Iterator]
의도:
복합 객체 요소들의 내부 표현 방식을 공개하지 않고도 순차적으로 접근할 수 있는 방법을 제공
한다.

다른 이름:
Cursor

설명:
STL의 컨테이너들에 대한 iterator를 생각하면 된다.
-----------------------------------------------------------------------------

GoF에서는 Iterator에 대한 인터페이스를 아래와 같이 표현하고 있다.
template<class Item>
class Iterator
{
public:
 virtual void First()        = 0;
 virtual void Next()         = 0;
 virtual bool IsDone() const = 0;
protected:
 Iterator() {};
};

Posted by 셈말짓기 :

행위패턴-State

2008. 8. 16. 17:59 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[State]
의도:
객체 자신의 내부 상태에 따라 행위를 변경하도록 한다. 객체가 클래스를 바꾸는 것처럼 보일
수 있다.

다른 이름:
Object for State

설명:
FSM(Finite State Machine)를 구현함에 있어서 State패턴을 이용한다.
-----------------------------------------------------------------------------

/////////////////////////////////////////////////////////////////////////////
//
// A Behavioral part of GoF's Design Patterns
//
// - State
//
/////////////////////////////////////////////////////////////////////////////

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

#include <iostream>


/////////////////////////////////////////////////////////////////////////////
//
// State
//
/////////////////////////////////////////////////////////////////////////////
class Context;

class State
{
public:
 virtual ~State() {}
public:
 virtual void Handle      (Context*) {}
protected:
 virtual void ChangeState (Context*, State*);
};

//// ------------------------------------------------------------------------

class ConcreteStateA : public State
{
public:
 virtual void Handle(Context* c);
};

class ConcreteStateB : public State
{
public:
 virtual void Handle(Context* c);
};

class ConcreteStateC : public State
{
public:
 virtual void Handle(Context* c);
};

void ConcreteStateA::Handle(Context* c)
{
 std::cout << "ConcreteStateA::Handle()" << std::endl;
 ChangeState (c, new ConcreteStateB());
}

void ConcreteStateB::Handle(Context* c)
{
 std::cout << "ConcreteStateB::Handle()" << std::endl;
 ChangeState (c, new ConcreteStateC());
}

void ConcreteStateC::Handle(Context* c)
{
 std::cout << "ConcreteStateC::Handle()" << std::endl;
 ChangeState (c, new ConcreteStateA());
}

//// ------------------------------------------------------------------------

class Context
{
public:
 friend class State;
public:
 Context () : State_(0)
 {
  State_ = new ConcreteStateA();
 }

 virtual ~Context ()
 {
  if (State_)
   delete State_;
 }

public:
 void Request (void)
 {
  if (State_)
  {
   State_->Handle(this);
  }
 }

protected:
 void ChangeState (State *s)
 {
  if (State_)
  {
   delete State_;
  }

  State_ = s;
 }

private:
 State *State_;
};

//// ------------------------------------------------------------------------

void State::ChangeState (Context* c, State* s)
{
 c->ChangeState (s);
}


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 Context context;

 context.Request();
 context.Request();
 context.Request();

 context.Request();
 context.Request();
 context.Request();

 return 0;
}
-----------------------------------------------------------------------------
ConcreteStateA::Handle()
ConcreteStateB::Handle()
ConcreteStateC::Handle()
ConcreteStateA::Handle()
ConcreteStateB::Handle()
ConcreteStateC::Handle()


Posted by 셈말짓기 :

행위패턴-Observer

2008. 8. 16. 17:17 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Observer]
의도:
일대다의 관련성을 갖는 객체들의 경우 한 객체의 상태가 변하면 다른 모든 객체에 그 사항을
알리고 필요한 수정이 자동으로 이루어지도록 할 수 있어야 한다.

다른 이름:
Dependent, Publish-Subject

설명:
MFC의 CView::OnUpdate(), CDocument::UpdateAllViews()와 같은 개념으로 MVC 모델에서
One-Document에 Multi-View모델을 생각하면 쉽다. 이 때 Document는 Subject이고 View는
Observer이다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Behavioral part of GoF's Design Patterns
//
// - Observer
//
/////////////////////////////////////////////////////////////////////////////

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

#include <iostream>
#include <list>
#include <algorithm>


/////////////////////////////////////////////////////////////////////////////
//
// Observer
//
/////////////////////////////////////////////////////////////////////////////
class Subject;

class Observer
{
public:
 virtual ~Observer() {}

public:
 virtual void Update (Subject* s) = 0;
};

class Subject
{
public:
 virtual ~Subject() {}

public:
 void Attach (Observer *o)
 {
  Observers_.push_back (o);
 }
 void Detach (Observer *o)
 {
  std::list<Observer*>::iterator i;

  i = std::find (Observers_.begin(), Observers_.end(), o);
  if (i!=Observers_.end())
  {
   Observers_.erase (i);
  }
 }
 void Notify (void)
 {
  std::list<Observer*>::iterator i;

  for (i=Observers_.begin(); i!=Observers_.end(); i++)
  {
   (*i)->Update (this);
  } 
 }

private:
 std::list<Observer*> Observers_;
};

////-------------------------------------------------------------------------

class ConcreteSubject : public Subject
{
public:
 void SetState (std::string s)
 {
  State_ = s;

  Notify ();
 }

 std::string GetState (void) const
 {
  return State_;
 }

private:
 std::string State_;
};

class ConcreteObserverA : public Observer
{
public:
 explicit ConcreteObserverA(ConcreteSubject* s) : Subject_(s)
 {
  Subject_->Attach (this);
 }
 virtual ~ConcreteObserverA()
 {
  Subject_->Detach (this);
 }

public:
 virtual void Update (Subject* s)
 {
  if (s==Subject_)
  {
   std::cout << "ConcreteObserverA::Update(): Subject_->GetState()="
             << Subject_->GetState().c_str()
       << std::endl;
  }
 }

protected:
 ConcreteSubject *Subject_;
};

class ConcreteObserverB : public Observer
{
public:
 explicit ConcreteObserverB (ConcreteSubject* s) : Subject_(s)
 {
  Subject_->Attach (this);
 }
 virtual ~ConcreteObserverB()
 {
  Subject_->Detach (this);
 }

public:
 virtual void Update (Subject* s)
 {
  if (s==Subject_)
  {
   std::cout << "ConcreteObserverB::Update(): Subject_->GetState()="
             << Subject_->GetState().c_str()
       << std::endl;
  }
 }

protected:
 ConcreteSubject *Subject_;
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 ConcreteSubject   subject;
 ConcreteObserverA observerA(&subject);
 ConcreteObserverB observerB(&subject);

 subject.SetState ("one");
 subject.SetState ("two");
 subject.SetState ("three");

 return 0;
}
-----------------------------------------------------------------------------
ConcreteObserverA::Update(): Subject_->GetState()=one
ConcreteObserverB::Update(): Subject_->GetState()=one
ConcreteObserverA::Update(): Subject_->GetState()=two
ConcreteObserverB::Update(): Subject_->GetState()=two
ConcreteObserverA::Update(): Subject_->GetState()=three
ConcreteObserverB::Update(): Subject_->GetState()=three

Posted by 셈말짓기 :

행위패턴-Memento

2008. 8. 16. 12:32 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Memento]
의도:
캡슐화를 위배하지 않으면서 객체의 내부 상태를 파악하고 표현함으로써 객체의 상태를 저장해
둔 상태로 다시 복구 할 수 있게 한다.

다른 이름:
Token
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Behavioral part of GoF's Design Patterns
//
// - Memento
//
/////////////////////////////////////////////////////////////////////////////

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

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



/////////////////////////////////////////////////////////////////////////////
//
// Utility
//
/////////////////////////////////////////////////////////////////////////////
template<class T>
struct deleteobject_functor : public std::unary_function<T, void>
{
public:
 void operator()(T ptr)
 {
  delete ptr;
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Memento
//
/////////////////////////////////////////////////////////////////////////////
typedef std::string State;

class Memento
{
private:
 friend class Originator;

private:
 Memento(void) : State_("empty")
 {
 }

public:
 State GetState (void) const
 {
  return State_;
 }

 void SetState (State s)
 {
  State_ = s;
 }

private:
 State State_;
};

class Originator
{
public:
 Originator (void) : State_("empty")
 {
 }

public:
 Memento* CreateMemento (void)
 {
  Memento *m;

  m = new Memento();
  m->SetState (State_);

  return m;
 }

 void SetMemento (const Memento* m)
 {
  State_ = m->GetState ();

  delete m;
 }

 void SetState (std::string s)
 {
  State_ = s;
 }

private:
 State State_;

public:
 friend std::ostream& operator<< (std::ostream&, const Originator&);
};

class CareTaker
{
public:
 virtual ~CareTaker ()
 {
  std::for_each(History_.begin(), History_.end(), deleteobject_functor<Memento*>());
 }

public:
 void Push (Memento* m)
 {
  History_.push_back (m);
 }

 Memento* Pop (void)
 {
  Memento* m = 0;

  if (!History_.empty())
  {
   m=History_.back();
   History_.pop_back();
  }

  return m;
 }

private:
 std::deque <Memento*> History_;
};

////-------------------------------------------------------------------------

std::ostream& operator<< (std::ostream& os, const Originator &org)
{
 os << "Originator's State=" << org.State_.c_str();

 return os;
}

/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 Originator originator;
 CareTaker  caretaker;


 originator.SetState ("first");
 std::cout << originator << std::endl;

 std::cout << std::endl;

 caretaker.Push ( originator.CreateMemento () );
 originator.SetState ("second");
 std::cout << originator << std::endl;

 caretaker.Push ( originator.CreateMemento () );
 originator.SetState ("third");
 std::cout << originator << std::endl;

 std::cout << std::endl;

 originator.SetMemento ( caretaker.Pop () );
 std::cout << originator << std::endl;

 originator.SetMemento ( caretaker.Pop () );
 std::cout << originator << std::endl;

 return 0;
}
-----------------------------------------------------------------------------
Originator's State=first

Originator's State=second
Originator's State=third

Originator's State=second
Originator's State=first


Posted by 셈말짓기 :

행위패턴-Mediator

2008. 8. 16. 00:19 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Mediator]
의도:
객체들 간의 상호작용을 캡슐화하여 하나의 객체 안에 정의한다. Mediator 패턴은 각 객체가
관련성을 갖는 다른 객체에 대한 참조 관계를 직접 정의하기보다는 이를 독립된 다른 객체가
관리하게 한다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Behavioral part of GoF's Design Patterns
//
// - Mediator
//
/////////////////////////////////////////////////////////////////////////////

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

#include <iostream>
#include <memory>


/////////////////////////////////////////////////////////////////////////////
//
// Mediator
//
//
/////////////////////////////////////////////////////////////////////////////
class Colleague;

class Mediator
{
public:
 virtual ~Mediator () {}
public:
 virtual void OnNotify (Colleague *) {}
};

class Colleague
{
public:
 Colleague (Mediator* m) : Mediator_(m) {}
 virtual ~Colleague () {}
public:
 virtual void Notify ()
 {
  if (Mediator_)
  {
   Mediator_->OnNotify (this);
  }
 }

protected:
 Mediator* Mediator_;
};

////-------------------------------------------------------------------------

class ConcreteColleague1 : public Colleague
{
public:
 ConcreteColleague1 (Mediator* m) : Colleague (m) {}

public:
 void Act1 (void)
 {
  Notify ();
 }
};

class ConcreteColleague2 : public Colleague
{
public:
 ConcreteColleague2 (Mediator* m) : Colleague (m) {}

public:
 void Act2 (void)
 {
  Notify ();
 }
};

class ConcreteMediator : public Mediator
{
public:
 void Init (void)
 {
  Colleague1_.reset ( new ConcreteColleague1(this) );
  Colleague2_.reset ( new ConcreteColleague2(this) );
 }

 void Run (void)
 {
  Colleague1_->Act1 ();
  Colleague2_->Act2 ();
 }

 virtual void OnNotify (Colleague *c)
 {
  if      (c==Colleague1_.get())
  {
   std::cout << "ConcreteMediator::OnNotify() = Colleague1_" << std::endl;
  }
  else if (c==Colleague2_.get())
  {
   std::cout << "ConcreteMediator::OnNotify() = Colleague2_" << std::endl;
  }
 }

private:
 std::auto_ptr<ConcreteColleague1> Colleague1_;
 std::auto_ptr<ConcreteColleague2> Colleague2_;
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 ConcreteMediator mediator;

 mediator.Init ();
 mediator.Run  ();

 return 0;
}
-----------------------------------------------------------------------------
ConcreteMediator::OnNotify() = Colleague1_
ConcreteMediator::OnNotify() = Colleague2_

Posted by 셈말짓기 :

-----------------------------------------------------------------------------
[Template Method]
의도:
오퍼레이션에 알고리즘의 기본 골격 구조를 정의하고 구체적인 단계는 서브클래스에 정의한다.
Template Method 클래스의 서브클래스는 알고리즘의 구조를 변경하지 않고 알고리즘 처리
단계들을 재정의 할 수 있다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Behavioral part of GoF's Design Patterns
//
// - Template Method
//
/////////////////////////////////////////////////////////////////////////////

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

#include <iostream>
#include <memory>


/////////////////////////////////////////////////////////////////////////////
//
// Template Method
//
/////////////////////////////////////////////////////////////////////////////
class AbstractClass
{
public:
 virtual ~AbstractClass()
 {
 }

public:
 void TemplateMethod (void)
 {
  std::cout << "AbstractClass::TemplateMethod()" << std::endl;

  std::cout << "\t";
  PrimitiveOperation1();

  std::cout << "\t";
  PrimitiveOperation2();

  std::cout << std::endl;
 }

 virtual void PrimitiveOperation1 (void)
 {
 }

 virtual void PrimitiveOperation2 (void)
 {
 }
};

class ConcreteClassA : public AbstractClass
{
public:
 virtual void PrimitiveOperation1 (void)
 {
  std::cout << "ConcreteClassA::PrimitiveOperation1()" << std::endl;
 }

 virtual void PrimitiveOperation2 (void)
 {
  std::cout << "ConcreteClassA::PrimitiveOperation2()" << std::endl;
 }
};

class ConcreteClassB : public AbstractClass
{
public:
 virtual void PrimitiveOperation1 (void)
 {
  std::cout << "ConcreteClassB::PrimitiveOperation1()" << std::endl;
 }

 virtual void PrimitiveOperation2 (void)
 {
  std::cout << "ConcreteClassB::PrimitiveOperation2()" << std::endl;
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 std::auto_ptr<AbstractClass> a;

 a.reset ( new ConcreteClassA() );
 a->TemplateMethod ();

 a.reset ( new ConcreteClassB() );
 a->TemplateMethod ();

 return 0;
}
-----------------------------------------------------------------------------AbstractClass::TemplateMethod()
        ConcreteClassA::PrimitiveOperation1()
        ConcreteClassA::PrimitiveOperation2()

AbstractClass::TemplateMethod()
        ConcreteClassB::PrimitiveOperation1()
        ConcreteClassB::PrimitiveOperation2()


Posted by 셈말짓기 :

행위패턴-Strategy

2008. 8. 15. 18:32 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Strategy]
의도:
다양한 알고리즘이 존재하면 이들 각각을 하나의 클래스로 캡슐화하여 알고리즘의 대체가 가능
하도록 한다. Strategy패턴을 이용하면 클라이언트와 독립적인 다양한 알고리즘으로 변형할 수
있다. 알고리즘을 바구더라도 클라이언트는 아무런 변경을 할 필요가 없다.

다른 이름:
Policy

참고:
Policy-based design이 Strategy을 이용한 디자인 방법이다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Behavioral part of GoF's Design Patterns
//
// - Strategy
//
/////////////////////////////////////////////////////////////////////////////

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

#include <iostream>


/////////////////////////////////////////////////////////////////////////////
//
// Strategy
//
//
/////////////////////////////////////////////////////////////////////////////
class Strategy
{
public:
 virtual ~Strategy() {}
public:
 virtual void AlgorithmInterface(void) = 0;
};

template <typename Strategy>
class Context
{
public:
 void operator() ()
 {
  Strategy_.AlgorithmInterface ();
 }

private:
 Strategy Strategy_;
};

class ContextByRunTime
{
public:
 explicit ContextByRunTime (Strategy *s) :
  Strategy_ (s)
 {
 }

public:
 void operator() ()
 {
  Strategy_->AlgorithmInterface ();
 }

private:
 Strategy *Strategy_;
};

class ConcreteStrategyA : public Strategy
{
public:
 virtual void AlgorithmInterface(void)
 {
  std::cout << "ConcreteStrategyA::AlgorithmInterface()" << std::endl;
 }
};

class ConcreteStrategyB : public Strategy
{
public:
 virtual void AlgorithmInterface(void)
 {
  std::cout << "ConcreteStrategyB::AlgorithmInterface()" << std::endl;
 }
};

class ConcreteStrategyC : public Strategy
{
public:
 virtual void AlgorithmInterface(void)
 {
  std::cout << "ConcreteStrategyC::AlgorithmInterface()" << std::endl;
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 ConcreteStrategyA s1;
 ConcreteStrategyB s2;
 ConcreteStrategyC s3;

 ContextByRunTime cr1(&s1);
 ContextByRunTime cr2(&s2);
 ContextByRunTime cr3(&s3);

 Context<ConcreteStrategyA> cc1;
 Context<ConcreteStrategyB> cc2;
 Context<ConcreteStrategyC> cc3;

 std::cout << "by run-time" << std::endl;
 cr1();
 cr2();
 cr3();

 std::cout << std::endl;

 std::cout << "by compile-time" << std::endl;
 cc1();
 cc2();
 cc3();

 return 0;
}
-----------------------------------------------------------------------------
by run-time
ConcreteStrategyA::AlgorithmInterface()
ConcreteStrategyB::AlgorithmInterface()
ConcreteStrategyC::AlgorithmInterface()

by compile-time
ConcreteStrategyA::AlgorithmInterface()
ConcreteStrategyB::AlgorithmInterface()
ConcreteStrategyC::AlgorithmInterface()


Posted by 셈말짓기 :

-----------------------------------------------------------------------------
[Chain Of Responsibility]
의도:
메시지를 보내는 객체와 이를 받아 처리하는 객체들 간의 결합도를 없애기 위한 패턴이다.
하나의 요청에 대한 처리가 반드시 한 객체에서만 이루어지지 않고, 여러 객체에게 그 처리의
기회를 주려는 것이다. 즉, 이 패턴에서는 하나의 서비스 처리를 여러 객체에 나눌 수 있도록
한다. 메시지를 수신하여 처리를 담당할 객체들을 하나의 연결 고리로 만들고, 실제로 요청을
처리하는 객체를 만날 때까지 계속해서 요청을 전달하게 한다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Behavioral part of GoF's Design Patterns
//
// - Chain Of Responsibility
//
/////////////////////////////////////////////////////////////////////////////

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

#include <memory>

#include <iostream>
#include <deque>
#include <list>
#include <vector>
#include <algorithm>
#include <iomanip>


/////////////////////////////////////////////////////////////////////////////
//
// Chain Of Responsibility
//
//
/////////////////////////////////////////////////////////////////////////////
class Handler
{
public:
 typedef int Topic;

public:
 explicit Handler (Handler *s=0, Topic t=0) :
  Successor_(s),
  Topic_    (t)
 {
 }

 virtual ~Handler ()
 {
 }

public:
 virtual void HandleRequest(void)
 {
  if (Successor_)
  {
   Successor_->HandleRequest ();
  }
  else
  {
   std::cout << "Handler::HandleRequest() : no Successor_" << std::endl;
  }
 }

 virtual void SetHandler (Handler *s=0, Topic t=0)
 {
  Successor_=s;
  Topic_    =t;
 }

protected:
 Handler* Successor_;
 Topic    Topic_;
};

class ConcreteHandler1 : public Handler
{
public:
 ConcreteHandler1 (Handler *s=0, Topic t=0) :
  Handler(s,t)
 {
 }
public:
 virtual void HandleRequest(void)
 {
  if (Topic_==1)
  {
   std::cout << "ConcreteHandler1::HandleRequest()" << std::endl;
  }
  else
  {
   Handler::HandleRequest();
  }
 };
};

class ConcreteHandler2 : public Handler
{
public:
 ConcreteHandler2 (Handler *s=0, Topic t=0) :
  Handler(s,t)
 {
 }

public:
 virtual void HandleRequest(void)
 {
  if (Topic_==2)
  {
   std::cout << "ConcreteHandler2::HandleRequest()" << std::endl;
  }
  else
  {
   Handler::HandleRequest();
  }
 };
};

class ConcreteChildHandler : public ConcreteHandler2
{
public:
 ConcreteChildHandler (Handler *s=0, Topic t=0) :
  ConcreteHandler2(s,t)
 {
 }

public:
 virtual void HandleRequest(void)
 {
  if (Topic_==3)
  {
   std::cout << "ConcreteChildHandler::HandleRequest()" << std::endl;
  }
  else
  {
   ConcreteHandler2::HandleRequest();
  }
 };
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 Handler* handler1 = new Handler              ();
 Handler* handler2 = new ConcreteHandler1     (handler1, 1);
 Handler* handler3 = new ConcreteHandler2     (handler2, 1);
 Handler* handler4 = new ConcreteChildHandler (handler3, 2);
 Handler* handler5 = new ConcreteChildHandler (handler3, 3);

 handler1->HandleRequest();
 handler2->HandleRequest();
 handler3->HandleRequest();
 handler4->HandleRequest();
 handler5->HandleRequest();

 delete handler1;
 delete handler2;
 delete handler3;
 delete handler4;
 delete handler5;

 return 0;
}
-----------------------------------------------------------------------------Handler::HandleRequest() : no Successor_
ConcreteHandler1::HandleRequest()
ConcreteHandler1::HandleRequest()
ConcreteHandler2::HandleRequest()
ConcreteChildHandler::HandleRequest()

Posted by 셈말짓기 :

행위패턴-Command

2008. 8. 15. 01:31 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Command]
의도:
요청 자체를 객체화하는 것이다. 그리고 서로 다른 요청을 객체화하여 클라이언트에게
파라미터로 넘겨줄 수 있게한다.

다른이름:
Action, Transaction
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Behavioral part of GoF's Design Patterns
//
// - Command
//
/////////////////////////////////////////////////////////////////////////////

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

#include <iostream>
#include <deque>
#include <list>
#include <vector>
#include <algorithm>
#include <iomanip>


/////////////////////////////////////////////////////////////////////////////
//
// Command
//
//
/////////////////////////////////////////////////////////////////////////////
class Command
{
protected:
 Command () {}
public:
 virtual ~Command () {}

public:
 virtual void Execute   (void) = 0;
 virtual void Unexecute (void) {}
};


/////////////////////////////////////////////////////////////////////////////
//
// Utility
//
/////////////////////////////////////////////////////////////////////////////
template<class T>
struct deleteobject_functor : public std::unary_function<T, void>
{
public:
 void operator()(T ptr)
 {
  delete ptr;
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Application
//
//
/////////////////////////////////////////////////////////////////////////////
class Receiver
{
public:
 void Print_A (int a)
 {
  std::cout << "Receiver::Print_A(" << a << ")" << std::endl;
 }
 void Print_B (const char *b)
 {
  std::cout << "Receiver::Print_B(" << b << ")" << std::endl;
 }
 void Print_C (void)
 {
  std::cout << "Receiver::Print_C()" << std::endl;
 }
 void Print_D (void)
 {
  std::cout << "Receiver::Print_D()" << std::endl;
 }
};

////-------------------------------------------------------------------------
////  Commands
////-------------------------------------------------------------------------
template <typename Receiver>
class SimpleCommand : public Command
{
public:
 typedef void (Receiver::*Action)(void);

public:
 SimpleCommand (Receiver *receiver, Action action) :
  Receiver_ (receiver),
  Action_   (action)
 {
 }

public:
 virtual void Execute (void)
 {  
  (Receiver_->*Action_) ();
 }

private:
 Receiver *Receiver_;
 Action    Action_;
};

class ConcreteACommand : public Command
{
public:
 ConcreteACommand (Receiver *receiver, int param) :
  Receiver_ (receiver),
  Param_    (param)
 {
 }

public:
 virtual void Execute (void)
 {  
  Receiver_->Print_A (Param_);
 }

private:
 Receiver *Receiver_;
 int       Param_;
};

class ConcreteBCommand : public Command
{
public:
 ConcreteBCommand (Receiver *receiver, std::string param) :
  Receiver_ (receiver),
  Param_    (param)
 {
 }

public:
 virtual void Execute (void)
 {  
  Receiver_->Print_B (Param_.c_str());
 }

private:
 Receiver    *Receiver_;
 std::string  Param_;
};

class MacroCommand : public Command
{
public:
 virtual ~MacroCommand ()
 {
  std::for_each (Commands_.begin(), Commands_.end(), deleteobject_functor<Command*>());
 }

protected:
 static void ExecuteCommand (Command* cmd)
 {
  cmd->Execute();
 }

public:
 void Add (Command* cmd)
 {
  Commands_.push_back (cmd);
 }

 virtual void Execute (void)
 {
  std::for_each (Commands_.begin(), Commands_.end(), ExecuteCommand);
 }

private:
 std::list<Command*> Commands_;
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 Receiver     receiver;
 MacroCommand macrocmd;
 
 macrocmd.Add (new ConcreteACommand (&receiver, 100));
 macrocmd.Add (new ConcreteBCommand (&receiver, "Hello World!"));
 macrocmd.Add (new SimpleCommand<Receiver> (&receiver, &Receiver::Print_C));
 macrocmd.Add (new SimpleCommand<Receiver> (&receiver, &Receiver::Print_D));

 macrocmd.Execute();

 return 0;
}
-----------------------------------------------------------------------------

Receiver::Print_A(100)
Receiver::Print_B(Hello World!)
Receiver::Print_C()
Receiver::Print_D()



 


Posted by 셈말짓기 :

-----------------------------------------------------------------------------
Compoiste 객체를 Visitor가 순회할때 자식 객체들은 Accept를 재귀호출하고 자신은 Visit를
수행하는 방법으로 순회 한다.
--------------------------------------------------------------------------------
#include <windows.h>
#include <tchar.h>

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


/////////////////////////////////////////////////////////////////////////////
//
// Base Patterns
//
//
/////////////////////////////////////////////////////////////////////////////

//// ------------------------------------------------------------------------
////  Visitor Pattern
//// ------------------------------------------------------------------------
class Visitable;

class Visitor
{
protected:
 Visitor() {}
public:
 virtual void Visit (Visitable *) {}
};

class Visitable
{
protected:
 Visitable() {}
public:
 virtual void Accept (Visitor &v)
 {
  v.Visit (this);
 }
};

class VisitableObjectAcceptor
{
protected:
 Visitor &Visitor_;

public:
 explicit VisitableObjectAcceptor (Visitor &v) : Visitor_(v)
 {
 }

public:
 void operator () (Visitable* o)
 {
  if (o)
  {
   o->Accept (Visitor_);
  }
 }
};

//// ------------------------------------------------------------------------
////  Composite Pattern
//// ------------------------------------------------------------------------
class Composite;

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

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

class Composite : public Component
{
protected:
 Composite () {}

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 void Accept (Visitor &v)
 {
  v.Visit (this);
  std::for_each(components_.begin(), components_.end(), VisitableObjectAcceptor(v));

 }

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

class Leaf : public Component
{
};


/////////////////////////////////////////////////////////////////////////////
//
// Application
//
//
/////////////////////////////////////////////////////////////////////////////

//// ------------------------------------------------------------------------
////  Composite
//// ------------------------------------------------------------------------
class Directory : public Composite
{
public:
 Directory (const std::string name) : name_ (name)
 {
 }

public:
 virtual std::string GetName      (void) const { return name_;              }
 virtual size_t      GetFileCount (void) const { return components_.size(); }

protected:
 std::string name_;
};

class File : public Leaf
{
public:
 File (const std::string name, int size=0) : name_ (name), size_(size)
 {
 }

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

protected:
 std::string name_;
 int         size_;
};

class Mp3File : public File
{
public:
 Mp3File (const std::string filename) : File (filename, 1000) {}
};

class TxtFile : public File
{
public:
 TxtFile (const std::string filename) : File (filename, 10) {}
};

//// ------------------------------------------------------------------------
////  Vistor
//// ------------------------------------------------------------------------
class Enumerator: public Visitor
{
public:
 Enumerator ()
 {
 }

public:
 virtual void Visit (Visitable *o)
 {
  File      *file=dynamic_cast<File*>      (o);
  Directory *dir =dynamic_cast<Directory*> (o);

  if (file) std::cout << "\"" << file->GetName() << "\"" << std::endl;
  if (dir ) std::cout << "["  << dir ->GetName() << "]"  << std::endl;
 }
};

class CalcTotalSize : public Visitor
{
public:
 CalcTotalSize () : m_TotalSize(0)
 {
 }

public:
 virtual void Visit (Visitable *o)
 {
  File *file=dynamic_cast<File*> (o);

  if (file)
  {
   m_TotalSize+=file->GetSize();
  }
 }

public:
 int GetTotalSize (void) { return m_TotalSize; }

private:
 int m_TotalSize;
};


/////////////////////////////////////////////////////////////////////////////
//
// Start up
//
//
/////////////////////////////////////////////////////////////////////////////

int _tmain (int argc, _TCHAR* argv[])
{
 Directory dir_root   ("RootDirectory");
 Directory dir_sub1   ("SubDirectory1");
 Directory dir_sub2   ("SubDirectory2");
 Mp3File   file_mp3_1 ("a.mp3");
 Mp3File   file_mp3_2 ("b.mp3");
 TxtFile   file_txt_1 ("a.txt");
 TxtFile   file_txt_2 ("b.txt");


 dir_sub1.Add (&file_mp3_1);
 dir_sub1.Add (&file_mp3_2);
 dir_sub2.Add (&file_mp3_1);
 dir_sub2.Add (&file_txt_1);

 dir_root.Add (&dir_sub1);
 dir_root.Add (&dir_sub2);

 dir_root.Add (&file_txt_1);
 dir_root.Add (&file_txt_2);


 CalcTotalSize calc_size;

 dir_root.Accept (calc_size);
 std::cout << "# CalcTotalSize::GetTotalSize()=" << calc_size.GetTotalSize() << std::endl;


 std::cout << std::endl;


 std::cout << "# Enumerator" << std::endl;
 Enumerator show_enum;

 dir_root.Accept (show_enum);

 return 0;
}

--------------------------------------------------------------------------------
# CalcTotalSize::GetTotalSize()=3030

# Enumerator
[RootDirectory]
[SubDirectory1]
"a.mp3"
"b.mp3"
[SubDirectory2]
"a.mp3"
"a.txt"
"a.txt"
"b.txt"

Posted by 셈말짓기 :

구조패턴-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 셈말짓기 :

행위패턴-Visitor

2008. 8. 4. 22:52 from 셈말짓기/GoF

-----------------------------------------------------------------------------
[Visitor]
의도:
객체 구조의 요소들에 수행할 오퍼레이션을 표한한 패턴이다. Visitor 패턴은
오퍼레이션이 처리할 요소의 클래스를 변경하지 않고도 새로운 오퍼레이션을
정의 할 수 있게한다.
-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// A Behavioral part of GoF's Design Patterns
//
// - Visitor
//
/////////////////////////////////////////////////////////////////////////////

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

#include <iostream>
#include <list>

class ElementA;
class ElementB;
class CompoisteElement;

/////////////////////////////////////////////////////////////////////////////
//
// Visitor base
//
/////////////////////////////////////////////////////////////////////////////
class Visitor
{
protected:
 Visitor();
public:
 virtual ~Visitor();

public:
 virtual void VisitElementA (ElementA *);
 virtual void VisitElementB (ElementB *);
 virtual void VisitCompoistElement(CompoisteElement *);
};

Visitor::Visitor() {}
Visitor::~Visitor() {}

void Visitor::VisitElementA (ElementA *)
{
 std::cout << "Visitor::VisitElementA (ElementA *)" << std::endl;
}

void Visitor::VisitElementB (ElementB *)
{
 std::cout << "Visitor::VisitElementB (ElementA *)" << std::endl;
}

void Visitor::VisitCompoistElement(CompoisteElement *)
{
 std::cout << "Visitor::VisitCompoistElement (ElementA *)" << std::endl;
}


/////////////////////////////////////////////////////////////////////////////
//
// Element base
//
/////////////////////////////////////////////////////////////////////////////
class Element
{
protected:
 Element ();
public:
 virtual ~Element ();

public:
 virtual void Accept (Visitor &) = 0;
};

Element::Element () {};
Element::~Element () {};


/////////////////////////////////////////////////////////////////////////////
//
// Elements
//
/////////////////////////////////////////////////////////////////////////////
class ElementA : public Element
{
public:
 virtual void Accept (Visitor &v)
 {
  v.VisitElementA (this);
 }
};

class ElementB : public Element
{
public:
 virtual void Accept (Visitor &v)
 {
  v.VisitElementB (this);
 }
};

class CompoisteElement : public Element
{
public:
 virtual void Accept (Visitor &v)
 {
  std::list<Element*>::iterator i;

  for (i=childs_.begin(); i!=childs_.end(); i++)
  {
   (*i)->Accept (v);
  }

  v.VisitCompoistElement (this);
 }
public:
 std::list<Element*> childs_;
};

/////////////////////////////////////////////////////////////////////////////
//
// Visitors
//
/////////////////////////////////////////////////////////////////////////////
class VisitorA : public Visitor
{
public:
 virtual void VisitElementA (ElementA *)
 {
  std::cout << "VisitorA::VisitElementA (ElementA *)" << std::endl;
 }
 virtual void VisitElementB (ElementB *)
 {
  std::cout << "VisitorA::VisitElementB (ElementB *)" << std::endl;
 }
 virtual void VisitCompoistElement(CompoisteElement *)
 {
  std::cout << "VisitorA::VisitCompoistElement (CompoisteElement *)" << std::endl;
 }
};

class VisitorB : public Visitor
{
public:
 virtual void VisitElementA (ElementA *)
 {
  std::cout << "VisitorB::VisitElementA (ElementA *)" << std::endl;
 }
 virtual void VisitElementB (ElementB *)
 {
  std::cout << "VisitorB::VisitElementB (ElementB *)" << std::endl;
 }
 virtual void VisitCompoistElement(CompoisteElement *)
 {
  std::cout << "VisitorB::VisitCompoistElement (CompoisteElement *)" << std::endl;
 }
};


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 ElementA         element_a;
 ElementB         element_b;
 CompoisteElement c_element;

 c_element.childs_.push_back (&element_a);
 c_element.childs_.push_back (&element_b);

 VisitorA visitor_a;
 VisitorB visitor_b;

 element_a.Accept (visitor_a);
 element_b.Accept (visitor_a);
 c_element.Accept (visitor_a);

 std::cout << std::endl;

 element_a.Accept (visitor_b);
 element_b.Accept (visitor_b);
 c_element.Accept (visitor_b);

 std::cout << std::endl;
 std::cout << std::endl;
 std::cout << std::endl;


 Element *e;

 std::cout << "by element_a" << std::endl;
 e = &element_a;
 e->Accept (visitor_a);
 e->Accept (visitor_b);
 std::cout << std::endl;

 std::cout << "by element_b" << std::endl;
 e = &element_b;
 e->Accept (visitor_a);
 e->Accept (visitor_b);
 std::cout << std::endl;

 std::cout << "by c_element" << std::endl;
 e = &c_element;
 e->Accept (visitor_a);
 e->Accept (visitor_b);

 return 0;
}
-----------------------------------------------------------------------------
VisitorA::VisitElementA (ElementA *)
VisitorA::VisitElementB (ElementB *)
VisitorA::VisitElementA (ElementA *)
VisitorA::VisitElementB (ElementB *)
VisitorA::VisitCompoistElement (CompoisteElement *)

VisitorB::VisitElementA (ElementA *)
VisitorB::VisitElementB (ElementB *)
VisitorB::VisitElementA (ElementA *)
VisitorB::VisitElementB (ElementB *)
VisitorB::VisitCompoistElement (CompoisteElement *)


by element_a
VisitorA::VisitElementA (ElementA *)
VisitorB::VisitElementA (ElementA *)

by element_b
VisitorA::VisitElementB (ElementB *)
VisitorB::VisitElementB (ElementB *)

by c_element
VisitorA::VisitElementA (ElementA *)
VisitorA::VisitElementB (ElementB *)
VisitorA::VisitCompoistElement (CompoisteElement *)
VisitorB::VisitElementA (ElementA *)
VisitorB::VisitElementB (ElementB *)
VisitorB::VisitCompoistElement (CompoisteElement *)

Posted by 셈말짓기 :