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 셈말짓기 :
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 셈말짓기 :

§ GoF의 디자인 패턴이란?
     먼저, GoF란 Design Patterns: Elements of Reusable Object-Oriented Software이란 책을 쓰신
   Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides 네명의 사람들을 가리키는 Gang
   of Four로 표현되어지는데 이를 약어로 GoF라 쓰고있다.

     GoF에 나오는 디자인 패턴이란 소프트웨어 개발자들이 소프트웨어를 구현을 할 때 이루어지는
   구조들을 정리한 내용이다.  

     개발자들이 알게 모르게 자주 쓰는 기법들을 어휘화 해서 정리하여 이름을 붙인 패턴들이 GoF에는
   총 23개가  정리 되어있는데 생성패턴은 5개, 구조패턴은 7개, 행위패턴은 11개로 이루어 져있다.

1. 생성패턴(Creational Patterns)
   Abstract Factory groups object factories that have a common theme.
   Builder constructs complex objects by separating construction and representation.
   Factory Method creates objects without specifying the exact class to create.
   Prototype creates objects by cloning an existing object.
   Singleton restricts object creation for a class to only one instance.

2. 구조패턴(Structural Patterns)
   Adapter allows classes with incompatible interfaces to work together by wrapping its own
                interface around that of an already existing class.
   Bridge decouples an abstraction from its implementation so that the two can vary independently.
   Composite composes one-or-more similar objects so that they can be manipulated as one object.
   Decorator dynamically adds/overrides behaviour in an existing method of an object.
   Facade provides a simplified interface to a large body of code.
   Flyweight reduces the cost of creating and manipulating a large number of similar objects.
   Proxy provides a placeholder for another object to control access, reduce cost, and reduce complexity.

3. 행위패턴(Behavioral Patterns)
   Chain of Responsibility delegates commands to a chain of processing objects.
   Command creates objects which encapsulate actions and parameters.
   Interpreter implements a specialized language.
   Iterator accesses the elements of an object sequentially without exposing its underlying  
                representation.
   Mediator allows loose coupling between classes by being the only class that has detailed
                   knowledge of their methods.
   Memento provides the ability to restore an object to its previous state (undo).
   Observer is a publish/subscribe pattern which allows a number of observer objects to see an event.
   State allows an object to alter its behavior when its internal state changes.
   Strategy allows one of a family of algorithms to be selected on-the-fly at runtime.
   Template Method defines the skeleton of an algorithm as an abstract class, allowing its subclasses
                                to provide concrete behavior.
   Visitor separates an algorithm from an object structure by moving the hierarchy of methods into
                one object.

사용자 삽입 이미지

사용자 삽입 이미지

출저: http://www.mcdonaldland.info/2007/11/28/40/



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 셈말짓기 :