Command Pattern

commnad patternÀº ¸í·ÉÀ» ÆÐÅÏÈ­ ½ÃŲ °ÍÀ¸·Î ±¸Ã¼ÀûÀ¸·Î À̾߱â ÇÏÀÚ¸é ÇÔ¼ö³ª ¸Þ½îµå¸¦ ÀϹÝÈ­ ½ÃŲ´Ù.

ÁÖ »ç¿ë ¿ëµµ´Â ¹®ÀÚ¿­¿¡ ÀÇÇØ ¸í·ÉÀ» ³»¸±¶§, Undo, Redo ±â´ÉÀ» ±¸Çö ÇÒ ¶§ »ç¿ëµÈ´Ù.

command patternÀ» »ç¿ëÇϸé command¿¡ µû¸¥ Ŭ·¡½º°¡ ¸¹¾ÆÁö´Â ´ÜÁ¡ÀÌ ÀÖ´Ù.

UMLÀ» ºÁµµ ÀÌÇØÇÏ´Â°Ô ½±Áö ¾Ê´Ù. ¿ë¾î¸¦ ¾Ë¾Æº¸°í Äڵ带 ºÁ¾ß ´«¿¡ µé¾î ¿Ã °ÍÀÌ´Ù.

<¿ë¾î Á¤¸®>

client : ¾îÇø®ÄÉÀ̼Ç, ¸ÞÀÎ ·çƾ
Receiver : ½ÇÇàÇÒ ÇÔ¼ö³ª ¸Þ½îµåÀÌ´Ù.
Command : ¸í·É ÀÎÅÍÆäÀ̽º
ConcreteCommand : Command¸¦ »ó¼ÓÇØ Receiver¸¦ ½ÇÇàÇÑ´Ù.
Invoker : Command °ü¸®ÀÚ³ª Command¸¦ ½ÇÇàÇÒ ¼ö ÀÖ´Â ¼­¹öÀÌ´Ù.

< ¿¹Á¦ ÄÚµå >
¿¹Á¦¸¦ ½ÇÇà Çϸé, CommandManager¿¡¼­ Å¥·Î ÀúÀåµÈ ¸í·ÉµéÀ» ´Ù½Ã Çѹø ¹Ýº¹ÇÏ¿© ½ÇÇà ÇÑ´Ù.
¿¹Á¦ÀÌ´Ù º¸´Ï Undo¿¡ »ç¿ëÇϱ⿡´Â ¿Ïº®ÇÏÁö´Â ¾ÊÁö¸¸ ±âº» °³³äÀº ÀÌÇØ ÇÒ ¼ö ÀÖÀ» °ÍÀÌ´Ù.

client : ¾îÇø®ÄÉÀ̼Ç, ¸ÞÀÎ ·çƾ
Receiver : CFog::Move(), CObject::Move(), CObject::Scale()
Command : ICommand
ConcreteCommand : CommandMoveFog, CommandMoveObject, CommandScaleObject
Invoker : CommandManagerÀÇ ¸Þ½îµåµé

#include <stdio.h>

#include <vector>

#include <string>

#include <queue>

#include <iostream>

 

 

class ICommand

{

public:

    virtual void Execute() = 0;

};

 

class CommandMoveFog;

class CommandMoveObject;

class CommandScaleObject;

 

 

class CFog

{

public:

    void CTextureFog()

    {

        m_fx = 0.0f; m_fy = 0.0f; m_fRadius = 0.0f;

    }

    void Move(float fx, float fy, float fRadius)

    {

        m_fx = fx;   m_fy = fy;   m_fRadius = fRadius;   

        std::cout << "CFog::Move(" << fx <<  ",  " << fy << ", " << fRadius << ")" << std::endl;

    }

 

    float m_fx, m_fy, m_fRadius;

};

 

 

class CObject

{

public:

    CObject()

    {

        m_fx = 0.0f; m_fy = 0.0f; m_fz = 0.0f;  m_fScale = 0.0f;

    }

 

    void Move(float fx, float fy, float fz)

    {

        m_fx = fx;   m_fy = fy;   m_fz = fz;

        std::cout << "CObject::Move(" << fx  << ",  " << fy << ", " << fz << ")" << std::endl;

    }

 

    void Scale(float fScale)

    {

        m_fScale = fScale;

        std::cout << "CObject::Move(" << fScale << ")" << std::endl;

    }

 

    float m_fx, m_fy, m_fz, m_fScale;

};

 

 

class CommandMoveFog : public ICommand

{

    //¿©±â¿¡ ÀúÀåÇÏ°íÀÚ ÇÏ´Â ¿ÀºêÁ§Æ®³ª ¿ÀºêÁ§Æ®ÀÇ ÀÎÅÍÆäÀ̽º¸¦ ÀúÀåÇÑ´Ù.

    //¿ÀºêÁ§Æ® »èÁ¦¸¦ °í·ÁÇØ¾ß ÇÑ´Ù¸é, Æ÷ÀÎÅͺ¸´Ù´Â °ªÀ̳ª Á¤º¸¸¦ ³Ö´Â´Ù.

    CFog* m_pFog;

    float    m_fx, m_fy, m_fRadius;

 

public:

    CommandMoveFog(CFog* pFog, float fx, float fy, float fRadius) :

      m_pFog(pFog), m_fx(fx), m_fy(fy), m_fRadius(fRadius)  {}

 

    virtual void Execute()

    {

        m_pFog->Move(m_fx, m_fy, m_fRadius);

    }

};

 

class CommandMoveObject : public ICommand

{

    CObject* m_pObject;

    float    m_fx, m_fy, m_fz;

public:

    CommandMoveObject(CObject* pObject, float fx, float fy, float fz) :

      m_pObject(pObject), m_fx(fx), m_fy(fy), m_fz(fz) {}

 

 

    virtual void Execute()

    {

        m_pObject->Move(m_fx, m_fy, m_fz);

    }

};

 

class CommandScaleObject : public ICommand

{

    CObject* m_pObject;

    float    m_fScale;

public:

    CommandScaleObject(CObject* pObject, float fScale) :

      m_pObject(pObject), m_fScale(fScale) {}

 

    void Execute()

    {

        m_pObject->Scale(m_fScale);

    }

};

 

 

class CommandManager

{

    std::queue< ICommand * >  m_pCommandQueue;

public:

    CommandManager() {}

 

    void MoveFog(CFog* pFog, float fx, float fy, float fRadius)

    {

        m_pCommandQueue.push(new CommandMoveFog(pFog, fx, fy, fRadius));

    }

    void MoveObject(CObject* pObject, float fx, float fy, float fz)

    {

        m_pCommandQueue.push(new CommandMoveObject(pObject, fx, fy, fz));   

    }

    void ScaleObject(CObject* pObject, float fScale)

    {

        m_pCommandQueue.push(new CommandScaleObject(pObject, fScale));   

    }

 

    bool Update()

    {

        bool bUpdate = false;

        if(!m_pCommandQueue.empty())

        {

            ICommand * pCommand = m_pCommandQueue.front();

            pCommand->Execute();

            delete pCommand;

            m_pCommandQueue.pop();

            bUpdate = true;

        }

 

        return bUpdate;

    }

};

 

 

void main()

{

    CommandManager command;

    CFog fog;

    CObject object;

 

    fog.Move( 10.0f, 10.0f, 100.0f);

    command.MoveFog( &fog, 10.0f, 10.0f, 100.0f);

 

    object.Move( 1000.0f, 1000.0f, 0.0f);

    command.MoveObject( &object, 1000.0f, 1000.0f, 0.0f);

 

    object.Scale( 100.0f);

    command.ScaleObject( &object, 100.0f);

 

    object.Scale( 1.0f);

    command.ScaleObject( &object, 1.0f);

 

    std::cout << "-------------------Run Command Pattern-------------------" << std::endl;

    while(command.Update());

 

    getchar();

}

¼Ò½º : command_pattern.cpp