青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

積木

No sub title

  C++博客 :: 首頁 :: 聯系 :: 聚合  :: 管理
  140 Posts :: 1 Stories :: 11 Comments :: 0 Trackbacks

常用鏈接

留言簿(1)

我參與的團隊

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

轉載自:http://patmusing.blog.163.com/blog/static/13583496020101501317634/

The COR (Chain Of Responsibility) pattern forwards requests along a chain of classes, but the Command pattern forwards a request only to a specific object. It encloses the request for a specific action inside an object and gives it a known public interface.
It lets you give the client the ability to make requests without knowing anything about the actual action that will be performed and allows you to change that action without affecting the client program in any way.

One way to ensure that every object receives its own commands directly is to use the Command design pattern and create individual Command objects.

在軟件構建過程中,行為請求者行為實現者通常呈現一種緊耦合。但在某些場合,比如需要對行為進行記錄、撤銷/重做(undo/redo)、事務等處理,這種無法抵御變化的緊耦合是不合適的。Command設計模式就是在這種情況下,將行為請求者行為實現者解耦,將一組行為抽象為對象,以實現二者之間的松耦合。

“Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.” – GoF

將一個請求封裝為一個對象,從而可用不同的請求(一個被封裝成了對象的請求)對客戶程序(即調用者)進行參數化;對請求排隊或記錄請求日志,以及支持可撤銷的操作。

Command存在的兩個重要原因:

1. 解耦

17. C++實現Behavioral - Command模式 - 玄機逸士 - 玄機逸士博客

2. 由于C#Java不存在指針,因此不能將請求(即方法或者成員函數)作為參數進行傳遞或者存儲。在C++中盡管可以使用函數指針達到同樣的效果,但使用Command模式還是可以是代碼更容易理解一些。

最基本的Command模式之UML類圖:

17. C++實現Behavioral - Command模式 - 玄機逸士 - 玄機逸士博客

C++具體實現代碼:

// Command.h

#include <iostream>

#include <string>

#include <memory>

using namespace std;

// 抽象類

class Command

{

public:

virtual void execute() = 0;

public:

virtual ~Command()

{

cout << "in the destructor of Command..." << endl;

}

};

// Receiver

class Document

{

public:

void doDocument()

{

cout << "this is in Document::doDocument()..." << endl;

}

public:

~Document()

{

cout << "in the destructor of Document..." << endl;

}

};

// Receiver

class Graphics

{

public:

void doGraphics()

{

cout << "this is in Graphics::doGraphics()..." << endl;

}

public:

~Graphics()

{

cout << "in the destructor of Graphics..." << endl;

}

};

// ConcreteCommand

class DocumentCommand : public Command

{

private:

auto_ptr<Document> document;

public:

DocumentCommand()

{

auto_ptr<Document> temp_document(new Document);

document = temp_document;

}

~DocumentCommand()

{

cout << "in the destructor of DocumentCommand..." << endl;

}

public:

void execute()

{

cout << "this is in DocumentCommand::execute()..." << endl;

document->doDocument();

}

};

// ConcreteCommand

class GraphicsCommand : public Command

{

private:

auto_ptr<Graphics> graphics;

public:

GraphicsCommand()

{

auto_ptr<Graphics> temp_graphics(new Graphics);

graphics = temp_graphics;

}

~GraphicsCommand()

{

cout << "in the destructor of GraphicsCommand..." << endl;

}

public:

void execute()

{

cout << "this is in GraphicsCommand::execute()..." << endl;

graphics->doGraphics();

}

};

// Command.cpp

#include "Command.h"

int main(int argc, char **argv)

{

auto_ptr<Command> cmd1(new DocumentCommand);

auto_ptr<Command> cmd2(new GraphicsCommand);

cmd1->execute();

cout << "-------------------------------------" << endl;

cmd2->execute();

cout << "-------------------------------------" << endl;

return 0;

}

輸出結果:

this is in DocumentCommand::execute()...

this is in Document::doDocument()...

-------------------------------------

this is in GraphicsCommand::execute()...

this is in Graphics::doGraphics()...

-------------------------------------

in the destructor of GraphicsCommand...

in the destructor of Graphics…

in the destructor of Command...

in the destructor of DocumentCommand...

in the destructor of Document...

in the destructor of Command...

說明:上面的實現的Command模式從形式來說和對象類型的Adapter幾乎沒有區別。

Command模式的變體(實現undo/redo)

17. C++實現Behavioral - Command模式 - 玄機逸士 - 玄機逸士博客

注意:這個類圖是下面將要用C++代碼實現的示例程序中各類之間的關系圖。該示例程序用Command模式模擬了一個文本編輯器的undo/redo。下面是該示例程序的全部代碼:

// Command.h

#include <iostream>

#include <string>

#include <stack>

using namespace std;

class Receiver

{

private:

string str;

public:

~Receiver()

{

cout << "in the destructor of Receiver..." << endl;

}

public:

void append(const string& str)

{

this->str += str;

}

void set_data(const string& str)

{

this->str = str;

}

string get_data()

{

return str;

}

};

class Command

{

protected:

Receiver *receiver;

string parameter;

public:

Command(Receiver *receiver, string parameter) : receiver(receiver), parameter(parameter)

{

}

virtual ~Command()

{

cout << "in the destructor of Command..." << endl;

}

public:

virtual void execute() = 0;

};

class UndoableCommand : public Command

{

public:

UndoableCommand(Receiver *receiver, string parameter) : Command(receiver, parameter)

{

// 將接收到的參數,傳遞給基類構造函數

}

virtual ~UndoableCommand()

{

cout << "in the destructor of UndoableCommand..." << endl;

}

public:

virtual void undo() = 0;

virtual void redo() = 0;

};

class ConcreteCommand : public UndoableCommand

{

private:

string previous_str;

string current_str;

public:

ConcreteCommand(Receiver *receiver, string parameter) : UndoableCommand(receiver, parameter)

{

// 將接收到的參數傳遞給基類

}

~ConcreteCommand()

{

cout << "in the destructor of ConcreteCommand..." << endl;

}

public:

void execute()

{

previous_str = receiver->get_data();

receiver->append(parameter);

current_str = receiver->get_data();

}

void undo()

{

receiver->set_data(previous_str);

}

void redo()

{

receiver->set_data(current_str);

}

};

class CommandManager

{

private:

// executeCommandStack用來存放已經執行過的名利了呢個,以便undo

stack<Command*> executeCommandStack;

// undoCommandStack用來存放undo過的命令,以便redo

stack<Command*> undoCommandStack;

public:

~CommandManager()

{

cout << "in the destructor of CommandManager..." << endl;

}

public:

void executeCommand(Command *command)

{

command->execute();

// 保存操作結果。將執行過的Command,壓入executeCommandStack

executeCommandStack.push(command);

}

void undoCommand()

{

if(executeCommandStack.size() > 0)

{

// executeCommandStack彈出最后一次執行的command

UndoableCommand *command = dynamic_cast<UndoableCommand*>(executeCommandStack.top());

executeCommandStack.pop();

command->undo();

// command壓入undoCommandStack

undoCommandStack.push(command);

}

}

void redoCommand()

{

if(undoCommandStack.size() > 0)

{

// undoCommandStack彈出最后一次執行的command

UndoableCommand *command = dynamic_cast<UndoableCommand*>(undoCommandStack.top());

undoCommandStack.pop();

command->redo();

}

}

};

// Command.cpp

#include "Command.h"

int main(int argc, char **argv)

{

CommandManager *commandMan = new CommandManager;

Receiver *receiver = new Receiver;

cout << "---execute command---" << endl;

Command *command_A = new ConcreteCommand(receiver, "aaa\n");

commandMan->executeCommand(command_A);

Command *command_B = new ConcreteCommand(receiver, "bbb\n");

commandMan->executeCommand(command_B);

Command *command_C = new ConcreteCommand(receiver, "ccc\n");

commandMan->executeCommand(command_C);

Command *command_D = new ConcreteCommand(receiver, "ddd\n");

commandMan->executeCommand(command_D);

cout << "the data in receiver:" << endl;

cout << receiver->get_data() << endl;

cout << "---undo---: After undo twice..." << endl;

commandMan->undoCommand();

commandMan->undoCommand();

cout << "the data in receiver:" << endl;

cout << receiver->get_data() << endl;

cout << "---redo---: After redo twice..." << endl;

commandMan->redoCommand();

commandMan->redoCommand();

cout << "the data in receiver:" << endl;

cout << receiver->get_data() << endl;

delete commandMan;

delete receiver;

delete command_A;

delete command_B;

delete command_C;

delete command_D;

return 0;

}

運行結果:

---execute command---

the data in receiver:

aaa

bbb

ccc

ddd

---undo---: After undo twice...

the data in receiver:

aaa

bbb

---redo---: After redo twice...

the data in receiver:

aaa

bbb

ccc

ddd

in the destructor of CommandManager...

in the destructor of Receiver...

in the destructor of ConcreteCommand...

in the destructor of UndoableCommand...

in the destructor of Command...

in the destructor of ConcreteCommand...

in the destructor of UndoableCommand...

in the destructor of Command...

in the destructor of ConcreteCommand...

in the destructor of UndoableCommand...

in the destructor of Command...

in the destructor of ConcreteCommand...

in the destructor of UndoableCommand...

in the destructor of Command...

在上面的程序中,我們看到了Command對象作為參數進行傳遞(因為在JavaC#中,由于不存在指針,因此方法本身不能作為參數進行傳遞,在C++盡管有指針,如果使用Command設計模式,還是可以提高解耦的能力,同時可以使代碼更具有可讀性),除去解耦的宗旨外,Command設計模式最重要的實質就是,就是將方法封裝成為對象,從而可以作為參數進行傳遞。

C++中,一定程度上,也可以將Command對象理解成函數對象(function objectfunctor,有人稱之為仿函數,玄機逸士認為成為函數對象更合適一些),關于函數對象參見:函數對象

還有一點,上面的Receiver類,可以考慮用Singleton模式來實現。

Command對象的本質就是在該對象中指定了需要執行某種操作的接受者。

posted on 2013-03-08 10:36 Jacc.Kim 閱讀(276) 評論(0)  編輯 收藏 引用 所屬分類: 設計模式
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            午夜视频在线观看一区| 午夜精品理论片| 国外成人在线| 亚洲一级片在线观看| 最新成人在线| 久久九九热re6这里有精品| 亚洲视频在线二区| 奶水喷射视频一区| 久久一二三区| 国产精品夜色7777狼人 | 午夜综合激情| 欧美日韩国产小视频| 欧美国产欧美综合 | 久久精彩免费视频| 欧美视频在线一区二区三区| 欧美激情一区二区三区在线视频| 国产综合亚洲精品一区二| 亚洲视频一区二区| 亚洲视频1区2区| 欧美日本国产在线| 91久久精品国产91久久| 在线观看91精品国产麻豆| 久久大逼视频| 久久成人人人人精品欧| 国产三区二区一区久久 | 一区二区毛片| 亚洲永久精品国产| 国产精品毛片大码女人| 亚洲一级电影| 欧美资源在线| 狠狠色丁香久久婷婷综合丁香| 午夜亚洲精品| 免费亚洲电影| 亚洲精品欧洲| 欧美日韩无遮挡| 亚洲午夜激情网页| 欧美专区在线播放| 尤物在线观看一区| 欧美sm视频| 99亚洲伊人久久精品影院红桃| 亚洲性av在线| 国产一区二区成人久久免费影院| 久久久久久婷| 亚洲国产欧美日韩精品| 亚洲欧美日韩国产综合在线 | 久久尤物电影视频在线观看| 在线观看国产成人av片| 欧美成人一区二区在线| 日韩视频一区二区三区在线播放免费观看 | 国产精品久久久久9999高清| 亚洲在线观看免费视频| 美女主播一区| 制服丝袜亚洲播放| 国产日韩精品一区| 久色成人在线| 亚洲专区一二三| 欧美福利视频网站| 亚洲字幕一区二区| 激情视频一区二区三区| 欧美视频第二页| 久久精品一区二区三区不卡| 亚洲激情在线视频| 久久精品欧美日韩| 91久久精品国产91久久性色| 国产精品美女在线| 免费在线亚洲| 欧美一级大片在线免费观看| 亚洲激情一区二区三区| 久久久精品tv| 亚洲一区观看| 亚洲毛片在线看| 国产一区二三区| 欧美午夜理伦三级在线观看| 久久视频精品在线| 亚洲一区观看| 亚洲精品一区在线| 欧美高清你懂得| 欧美在线观看一区| 一区二区三区蜜桃网| 亚洲福利专区| 国产在线精品成人一区二区三区| 欧美日韩精品综合| 欧美高清一区| 久久青草久久| 午夜国产精品视频免费体验区| 亚洲日本成人| 欧美韩日一区二区| 久久免费国产| 久久福利视频导航| 亚洲欧美日韩国产成人精品影院| 日韩一区二区精品在线观看| 亚洲第一页在线| 激情久久综艺| 在线成人激情视频| 激情婷婷亚洲| 激情久久综合| 一区国产精品| 极品av少妇一区二区| 国产精品一二三四| 国产精品乱子乱xxxx| 欧美日韩一卡二卡| 欧美日韩国产亚洲一区| 欧美精品乱码久久久久久按摩| 裸体丰满少妇做受久久99精品| 欧美专区在线观看一区| 亚洲欧美日韩在线一区| 亚洲天堂成人在线视频| 中文亚洲免费| 亚洲自拍偷拍一区| 亚洲你懂的在线视频| 欧美亚洲在线观看| 久久精品国产一区二区三区| 久久gogo国模啪啪人体图| 久久久777| 欧美成年人视频网站| 欧美精品日韩www.p站| 欧美日韩情趣电影| 欧美性猛交一区二区三区精品| 欧美性大战xxxxx久久久| 国产精品网站在线| 国产综合香蕉五月婷在线| 在线不卡a资源高清| 亚洲精品激情| 亚洲一区二区高清| 欧美一区午夜视频在线观看| 久久野战av| 亚洲欧洲一区二区三区久久| 99综合视频| 午夜日韩福利| 久久在线观看视频| 欧美日韩午夜视频在线观看| 国产精品国产三级国产aⅴ无密码| 国产麻豆综合| 亚洲国产一区二区视频| 一本色道**综合亚洲精品蜜桃冫| 午夜国产精品影院在线观看| 美女精品一区| 99精品视频免费全部在线| 香蕉av777xxx色综合一区| 裸体丰满少妇做受久久99精品| 欧美精品一区三区| 国产精品视频网| 亚洲国产日韩欧美在线动漫| 亚洲一区在线观看视频| 久久久久久亚洲精品不卡4k岛国| 亚洲电影免费观看高清完整版| 亚洲天堂av高清| 老司机成人在线视频| 国产精品国产三级国产a| 影视先锋久久| 亚洲欧美不卡| 91久久久久久久久久久久久| 亚洲男人的天堂在线aⅴ视频| 老司机67194精品线观看| 国产精品―色哟哟| 亚洲精品国产视频| 久久精品日产第一区二区三区| 91久久综合| 久久久久久尹人网香蕉| 国产精品色午夜在线观看| 亚洲三级电影在线观看| 久久国产66| 亚洲一区一卡| 欧美精品一卡二卡| 有坂深雪在线一区| 久久se精品一区二区| 日韩天堂av| 免费看成人av| 精品成人久久| 久久国产精品久久国产精品| 99riav国产精品| 欧美国产日本韩| 亚洲福利在线看| 美腿丝袜亚洲色图| 亚洲欧美在线免费观看| 欧美视频二区36p| 一区二区三区免费网站| 亚洲高清视频一区二区| 久久露脸国产精品| 国产亚洲在线| 久久精品视频免费播放| 亚洲一区二区久久| 欧美午夜宅男影院在线观看| 日韩小视频在线观看| 欧美激情第1页| 裸体丰满少妇做受久久99精品| 激情一区二区三区| 久久久久久久综合狠狠综合| 亚洲免费视频中文字幕| 国产精品久久久一区二区三区| 在线一区二区日韩| 日韩视频一区二区在线观看 | 在线成人国产| 欧美大香线蕉线伊人久久国产精品| 久久精品欧美日韩精品| 一区二区三区在线观看视频| 久久久久久久成人| 久久乐国产精品| 亚洲精选久久| 99国产精品99久久久久久粉嫩 |