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