행위패턴-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 셈말짓기 :