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