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

積木

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 閱讀(271) 評論(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>
            一区二区黄色| 老牛影视一区二区三区| 欧美日本久久| 9久草视频在线视频精品| 久热精品视频在线观看| 久久不射网站| 1769国内精品视频在线播放| 欧美成人国产一区二区| 欧美激情一二三区| 亚洲综合视频网| 午夜精品久久一牛影视| 国内精品久久久久久久影视麻豆| 久久午夜激情| 欧美国产一区在线| 亚洲欧美国产视频| 久久久成人精品| 亚洲精品社区| 亚洲欧美卡通另类91av| 永久91嫩草亚洲精品人人| 亚洲欧洲在线播放| 欧美日韩精品欧美日韩精品一| 午夜精品99久久免费| 午夜精品一区二区三区在线视 | 性欧美精品高清| 亚洲福利小视频| 在线视频精品| 亚洲电影天堂av| 亚洲视频每日更新| 亚洲国产婷婷香蕉久久久久久99 | 久久亚洲免费| 中文一区二区| 欧美一区国产二区| 亚洲午夜伦理| 欧美sm视频| 久久欧美中文字幕| 欧美午夜影院| 欧美激情视频在线播放| 国产亚洲制服色| 99精品国产一区二区青青牛奶| 好看的av在线不卡观看| 中国日韩欧美久久久久久久久| 亚洲高清精品中出| 欧美一区二区三区另类| 中文av一区二区| 欧美成人一区二区三区在线观看| 亚洲午夜国产成人av电影男同| 美女被久久久| 麻豆av福利av久久av| 国产精品久久精品日日| 亚洲韩国精品一区| 狠狠色综合色综合网络| 亚洲在线免费观看| 亚洲一区二区黄| 久久综合久久综合久久| 久久婷婷亚洲| 国内精品伊人久久久久av影院| 一区二区三区四区五区精品| 99re热精品| 欧美精品一区二区三区在线看午夜 | 欧美一二区视频| 欧美日韩成人精品| 亚洲国产cao| 亚洲高清视频在线观看| 久久男人av资源网站| 看欧美日韩国产| 韩日精品视频一区| 久久国产精品久久久久久电车| 性做久久久久久久免费看| 国产精品久久久久久久久久久久久久| 亚洲国产成人av好男人在线观看| 狠狠色狠狠色综合日日91app| 亚洲综合清纯丝袜自拍| 欧美一区不卡| 国产婷婷色综合av蜜臀av| 午夜精品美女久久久久av福利| 午夜在线不卡| 国产在线高清精品| 美日韩精品视频| 亚洲国产欧美一区二区三区丁香婷| 雨宫琴音一区二区在线| 另类春色校园亚洲| 最新日韩中文字幕| 亚洲伊人网站| 国产色婷婷国产综合在线理论片a| 欧美一区二区三区视频免费播放 | 亚洲国产欧美一区| 欧美激情综合色综合啪啪| 亚洲免费播放| 亚洲线精品一区二区三区八戒| 国产精品久线观看视频| 午夜精品福利电影| 欧美激情久久久久| 亚洲在线中文字幕| 狠狠入ady亚洲精品经典电影| 两个人的视频www国产精品| 99re这里只有精品6| 欧美在线视频一区二区三区| 激情av一区二区| 欧美日韩大陆在线| 欧美一区二区三区在线免费观看| 另类天堂av| 亚洲天堂男人| 影音先锋日韩资源| 欧美午夜在线视频| 久久另类ts人妖一区二区| 99热精品在线| 免费日韩av片| 亚洲女优在线| 亚洲精品乱码久久久久久蜜桃91| 国产精品二区二区三区| 久久久久久香蕉网| 亚洲影院在线观看| 亚洲国产精品欧美一二99| 欧美一级理论片| 99精品国产福利在线观看免费| 国产婷婷一区二区| 欧美成黄导航| 欧美一区二区视频97| 一区二区三区高清视频在线观看| 免费在线观看成人av| 欧美一区二区三区免费看| 亚洲精品日韩一| 永久91嫩草亚洲精品人人| 国产欧美1区2区3区| 欧美激情第二页| 欧美主播一区二区三区美女 久久精品人 | 欧美成人午夜剧场免费观看| 亚洲尤物精选| 亚洲精品美女在线观看播放| 国内伊人久久久久久网站视频| 国产精品sm| 欧美日韩中文在线| 欧美精品在线视频| 久久精品观看| 久久av一区二区| 亚洲一区视频| 99视频日韩| 99热这里只有精品8| 欧美v日韩v国产v| 免费一级欧美片在线播放| 久久这里只精品最新地址| 午夜精品福利一区二区蜜股av| 亚洲精品日韩一| 一本色道久久综合亚洲精品按摩 | 欧美伊人精品成人久久综合97| 亚洲一区二区三区精品动漫| 一本色道综合亚洲| 99香蕉国产精品偷在线观看| 妖精成人www高清在线观看| 亚洲精品在线二区| 日韩视频在线免费观看| 99在线热播精品免费99热| 亚洲伊人一本大道中文字幕| 亚洲尤物精选| 欧美在线免费视屏| 久久久久久色| 免费成人av在线| 亚洲国产日韩欧美一区二区三区| 欧美成人午夜激情视频| 亚洲日本精品国产第一区| 99视频精品全部免费在线| 午夜精品久久久| 久久久中精品2020中文| 欧美激情一区二区三区高清视频| 欧美激情成人在线视频| 欧美午夜精品久久久久免费视 | 国产视频一区欧美| 怡红院精品视频| 亚洲精品国产精品乱码不99按摩| 亚洲国产专区校园欧美| 亚洲一级黄色| 久久午夜色播影院免费高清| 欧美二区在线播放| 亚洲人成在线观看网站高清| 亚洲国产毛片完整版 | 欧美xxx成人| 欧美天堂亚洲电影院在线播放| 国产精品私房写真福利视频| 国产一区二区三区久久久| 亚洲国产欧美日韩| 性欧美xxxx视频在线观看| 欧美xx视频| 亚洲综合首页| 欧美劲爆第一页| 国产亚洲一级高清| 一本一道久久综合狠狠老精东影业| 午夜免费在线观看精品视频| 欧美jizzhd精品欧美喷水| 亚洲午夜国产成人av电影男同| 蜜桃久久精品乱码一区二区| 国产精品久久久久久久久久妞妞 | 国语自产精品视频在线看| 一本色道久久综合亚洲精品小说| 午夜欧美大片免费观看 | 久久久久久伊人| 亚洲国产你懂的| 久久免费高清视频| 欧美少妇一区二区| 原创国产精品91| 久久精品99无色码中文字幕|