設計模式——命令模式(C++)

/*****************************************
Copyright (c) 2016 Jingshuang Hu

@filename:main.cpp
@datetime:2016.09.13
@author:HJS
@e-mail:[email protected]
@blog:http://blog.csdn.net/hujingshuang
*****************************************/
#include <iostream>

#include "Invoker.h"
#include "Command.h"
#include "Receiver.h"

using namespace std;

// 命令模式的優點:
// 1 降低對象之間的耦合度;
// 2 可以很容易添加、撤銷、恢復命令;
// 3 可以很容易的設計出一個組合命令;
// 4 調用同一方法(action)實現不同的功能;
// 缺點:
// 1 若存在過多的命令,就會導致代碼中出現過多的類

// client(客戶端)
int main() {
    concreteReceiver* receiver = new concreteReceiver();                // 命令接收者

    concreteCommandA* commandA = new concreteCommandA(receiver);        // 具體命令A
    concreteCommandB* commandB = new concreteCommandB(receiver);        // 具體命令B
    concreteCommandC* commandC = new concreteCommandC(receiver);        // 具體命令C

    Invoker* invoker = new Invoker();           // 命令發起者(該對象持有許多命令,具有添加、撤銷、恢復命令的功能)
    
    invoker->addCommand(commandA);              // 添加命令A
    invoker->addCommand(commandB);              // 添加命令B
    invoker->addCommand(commandC);              // 添加命令C

    invoker->action();                          // 執行所有命令

    invoker->undoCommand(commandA);             // 撤銷命令A
    invoker->action();                          // 執行所有命令

    invoker->undoCommand(commandB);             // 撤銷命令B
    invoker->action();                          // 執行所有命令

    invoker->redoCommand(commandA);             // 恢復命令A
    invoker->action();                          // 執行所有命令

    system("pause");
    return 0;
}
// 個人理解:感覺這個模式有點像觀察者模式和裝飾模式的結合的味道,甚至能感覺到有一絲絲工廠方法模式的存在。
/*****************************************
Copyright (c) 2016 Jingshuang Hu

@filename:Receiver.h
@datetime:2016.09.13
@author:HJS
@e-mail:[email protected]
@blog:http://blog.csdn.net/hujingshuang
*****************************************/
#ifndef _RECEIVER_H
#define _RECEIVER_H

// 抽象的接收者
class Receiver {
public:
    virtual void doA() = 0;             // 接收者持有的動作A
    virtual void doB() = 0;             // 接收者持有的動作B
    virtual void doC() = 0;             // 接收者持有的動作C
};

// 具體的接收者
class concreteReceiver : public Receiver {
public:
    virtual void doA();
    virtual void doB();
    virtual void doC();
};

#endif // _RECEIVER_H
/*****************************************
Copyright (c) 2016 Jingshuang Hu

@filename:Receiver.cpp
@datetime:2016.09.13
@author:HJS
@e-mail:[email protected]
@blog:http://blog.csdn.net/hujingshuang
*****************************************/
#include "Receiver.h"
#include <iostream>

using namespace std;

// 抽象接收者
void Receiver::doA() {

}

void Receiver::doB() {

}

void Receiver::doC() {

}

// 具體接收者
void concreteReceiver::doA() {          // 動作A
    cout << "do A" << endl;
}

void concreteReceiver::doB() {          // 動作B
    cout << "do B" << endl;
}

void concreteReceiver::doC() {          // 動作C
    cout << "do C" << endl;
}
/*****************************************
Copyright (c) 2016 Jingshuang Hu

@filename:Command.h
@datetime:2016.09.13
@author:HJS
@e-mail:[email protected]
@blog:http://blog.csdn.net/hujingshuang
*****************************************/
#ifndef _COMMAND_H
#define _COMMAND_H

#include "Receiver.h"

class Receiver;

// 抽象命令
class Command {
public:
    virtual void execute() = 0;             // 執行命令
};

// 具體命令A
class concreteCommandA : public Command {
private:
    Receiver* receiver;
public:
    concreteCommandA(Receiver* receiver);
    virtual void execute();
};

// 具體命令B
class concreteCommandB : public Command {
private:
    Receiver* receiver;
public:
    concreteCommandB(Receiver* receiver);
    virtual void execute();
};

// 具體命令C
class concreteCommandC : public Command {
private:
    Receiver* receiver;
public:
    concreteCommandC(Receiver* receiver);
    virtual void execute();
};

#endif // _COMMAND_H
/*****************************************
Copyright (c) 2016 Jingshuang Hu

@filename:Command.cpp
@datetime:2016.09.13
@author:HJS
@e-mail:[email protected]
@blog:http://blog.csdn.net/hujingshuang
*****************************************/
#include "Command.h"
#include <iostream>

using namespace std;

// 抽象命令
void Command::execute() {

}

// 具體命令A
concreteCommandA::concreteCommandA(Receiver* receiver) {
    this->receiver = receiver;
}

void concreteCommandA::execute() {      // 具體命令A執行動作A(命令A<------>動作A)
    receiver->doA();
}

// 具體命令B
concreteCommandB::concreteCommandB(Receiver* receiver) {
    this->receiver = receiver;
}

void concreteCommandB::execute() {      // 命令B<------>動作B
    receiver->doB();
}

// 具體命令C
concreteCommandC::concreteCommandC(Receiver* receiver) {
    this->receiver = receiver;
}

void concreteCommandC::execute() {      // 命令C<------>動作C
    receiver->doC();
}
/*****************************************
Copyright (c) 2016 Jingshuang Hu

@filename:Invoker.h
@datetime:2016.09.13
@author:HJS
@e-mail:[email protected]
@blog:http://blog.csdn.net/hujingshuang
*****************************************/
#ifndef _INVOKER_H
#define _INVOKER_H

#include "Command.h"
#include <list>

class Command;

// 命令的發起者
class Invoker {
private:
    std::list<Command*> lst;                    // 命令池(類似於觀察者模式中的觀察者集合)
public:
    Invoker();
    Invoker(Command* command);
    void addCommand(Command* command);          // 添加命令
    void undoCommand(Command* command);         // 撤銷命令
    void redoCommand(Command* command);         // 恢復命令
    void action();                              // 執行所有命令
    void action(Command* command);              // 執行指定命令
};

#endif // _INVOKER_H
/*****************************************
Copyright (c) 2016 Jingshuang Hu

@filename:Invoker.cpp
@datetime:2016.09.13
@author:HJS
@e-mail:[email protected]
@blog:http://blog.csdn.net/hujingshuang
*****************************************/
#include "Invoker.h"
#include <list>

using namespace std;

Invoker::Invoker() {

}

Invoker::Invoker(Command* command) {
    this->addCommand(command);
}

// 添加命令
void Invoker::addCommand(Command* command) {
    lst.push_back(command);
}

// 撤銷命令
void Invoker::undoCommand(Command* command) {
    lst.remove(command);
}

void Invoker::redoCommand(Command* command) {
    this->addCommand(command);
}

// 執行所有命令
void Invoker::action() {
    list<Command*>::iterator it = lst.begin();
    for (; it != lst.end(); it++) {
        (*it)->execute();
    }
}

// 執行指定命令
void Invoker::action(Command* command) {
    command->execute();
}


這就完啦。。。

發佈了117 篇原創文章 · 獲贊 391 · 訪問量 62萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章