2012年5月26日 星期六

Design Patterns - Command pattern


Command pattern是一種將Action封裝起來,並提供一個general的interface作為呼叫時(invoke)的統一介面。

舉個生活例子來說明,想必您一定用過萬用遙控器,User可以設定遙控器上某個按鈕1的功能為電視的開關,所以當User按下按鈕1,就可以開關電視,接著User設定按鈕2為控制冷氣的開關,所以當User按下按鈕2,就可以開關冷氣,這樣簡單的運作就是一種Command Pattern。
電視開關是一種Action,被封裝成遙控器上面的按鈕,對User來說,這是一個General的interface,而且User在變更任和按鈕功能時,並不會影響遙控器上面的其他按鈕。

Command pattern有三個名詞需要解釋一下:
client:The client instantiates the command object and provides the information required to call the method at a later time.
invoker: The invoker decides when the method should be called.
receiver: The receiver is an instance of the class that contains the method's code.

client就可以想成"設定按鈕"的動作,invoker就是User了,而receiver就是電器了。

圖取自http://en.wikipedia.org/wiki/Command_pattern.


#include <iostream>

class Command {
public:
    virtual int exec(void *args) = 0;
};

// Receiver
class TV {
    bool turn_on_off;
public:
    void pwr_switch() {
        if (turn_on_off) {
            std::cout << "Turn off TV" << std::endl;
        } else {
            std::cout << "Turn on TV" << std::endl;
        }
        turn_on_off = !(turn_on_off);
    }
};

class CmdTvSwitch: public Command {
    TV *_tv;
public:
    CmdTvSwitch(TV *tv) {
        this->_tv = tv;
    }
    virtual int exec(void *args) {
        this->_tv->pwr_switch();
        return 0;
    }
};

int main(int argc, char *argv[])
{
    // Client
    TV tv;
    Command  *c;
    c = new CmdTvSwitch(&tv);
    c->exec(NULL);
    c->exec(NULL);
    return 0; 
}

就目前個人在使用這個Pattern上面的感觸就是"Command pattern是一種將Action封裝起來,並提供一個general的interface作為呼叫時(invoke)的統一介面。"比如,我在寫Message Queue會用到,提供新的指令供外界呼叫也會用到。
    參考資料:
  1. http://en.wikipedia.org/wiki/Command_pattern
  2. http://caterpillar.onlyfun.net/Gossip/DesignPattern/CommandPattern.htm




沒有留言:

張貼留言

熱門文章