-----------------------------------------------------------------------------
[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_B(Hello World!)
Receiver::Print_C()
Receiver::Print_D()