2020년 7월 7일 화요일

GOF Design Pattern - Command





설명


 Command 를 통해 연산을 호출하는 개체와 수행하는 객체를 분리시킬 수 있음.

 호출하는 개체는 Invoker 고 수행하는 객체는 Receiver 임.



 위의 도표의 Invoker 는 새로운 클래스가 될 수 도 있고, 유저가 될 수도 있고 상관 없음.

 Receiver 는 Concrete Command 안에 구현되어 있어도 되고, 새로운 클래스가 위임받아도 됨.

중요한 것은 Invoker 와 Receiver 가 Command 라는 클래스를 통해 소통을 한다는 것임.




 이는 Undo, Redo 등의 Command 모음을 조작하는 작업으로 확장됨.


 절차지향 언어의 CallBack 함수를 객체화 한 것이기도 하며,

 실행취소, 복구, 반복, DBMS Transcation, 렌더링 후처리 등 여러방면에 활용됨.



예제 코드


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
struct AAA
{
    void Action() { std::cout << "함수실행" << std::endl; }
};
 
class Command
{
public:
    virtual ~Command() = default;
    virtual void Execute() = 0;
 
protected:
    Command();
};
 
template<class Receiver>
class SimpleCommand : public Command
{
public:
    typedef void(Receiver::* Action)();
 
    SimpleCommand(Receiver* r, Action a) : _receiver(r), _action(a) {}
 
    virtual void Execute() { (_receiver->*_action)(); }
    // cpp 로 안배면 에러뜸
 
private:
    Action _action;
    Receiver* _receiver;
};
cs

1
2
3
4
5
6
void main()
{
    AAA aaa;
    Command* cmd = new SimpleCommand<AAA>(&aaa, &AAA::Action);
    cmd->Execute();
}
cs

여기서 Invoker 는 mainI() 이고, receiver 는 AAA 임.


Command 는 모든 Command 를 상속함.

위의 SimpleCommand 도 마찬가지임.

어떤 새로운 종류의 Command 가 나와도 Command 를 상속받음.

그렇게 만들어진 Command 는 main 처럼 사후에 사용되고, 수정될 것임.




추가 설명

 
 CommandList 를 메멘토를 통해 구현해서 Redo, Undo 를 구현가능.




댓글 없음:

댓글 쓰기

List