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