GoF's Design Patterns를 다시 공부하면서 그 동안 만들어 놓은 Sample들이다.
UML로 표시된 구조를 가급적 맞추려고 노력해서 실제 Pattern들이 의미하는 바를 표현하기에는 역부족이다.
Sample Code를 보면서 구조는 쉽게 이해는 할 수 있을지 몰라도 Pattern들의 실제적인 의미나 사용을 하기
위해서는 책을 참고하는 것이 도움이 될 것 이다.
-----------------------------------------------------------------------------
[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
-----------------------------------------------------------------------------
[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()
-----------------------------------------------------------------------------
[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;
}
ConcreteProductB::Show(): 200
-----------------------------------------------------------------------------
[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()