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

積木

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>
            欧美日韩国产bt| 欧美一级在线视频| 亚洲美女在线视频| 久久久久久久久伊人| 欧美色图一区二区三区| 亚洲国产精品久久久久秋霞不卡| 亚洲欧美三级在线| 亚洲美女av电影| 欧美激情一级片一区二区| 激情综合中文娱乐网| 欧美在线免费观看| 亚洲视频欧洲视频| 欧美日韩亚洲一区二区三区四区| 亚洲成人资源| 麻豆精品网站| 久久久久国产一区二区三区四区| 国产视频一区在线观看一区免费| 午夜亚洲性色福利视频| 一本久道久久综合狠狠爱| 欧美日产一区二区三区在线观看| 亚洲精品黄网在线观看| 亚洲国产电影| 久久精品最新地址| 精久久久久久| 欧美激情一区二区三区高清视频 | 亚洲网站在线观看| 国产精品精品视频| 久久国内精品自在自线400部| 欧美在线播放一区| 亚洲国产精品va在线看黑人| 9人人澡人人爽人人精品| 国产精自产拍久久久久久| 亚洲精品乱码视频| 亚洲国产高清自拍| 欧美午夜激情小视频| 亚洲免费播放| 在线视频日韩| 国产亚洲亚洲| 久久精品免费播放| 欧美成人dvd在线视频| 国产精品99久久久久久www| 亚洲永久字幕| 亚洲国产精品久久久久秋霞影院 | 欧美肉体xxxx裸体137大胆| 亚洲另类黄色| 一本大道久久精品懂色aⅴ| 欧美视频在线不卡| 久久久精品国产免大香伊| 欧美亚洲一区| 黄色综合网站| 日韩视频中午一区| 国产精品无码永久免费888| 久久av一区二区三区漫画| 亚洲第一主播视频| 欧美日韩精品一区二区在线播放| 亚洲永久在线| 免费不卡亚洲欧美| 亚洲在线成人精品| 久久免费视频观看| 99re热这里只有精品免费视频| 99国产精品久久久| 国产欧美日韩综合| 欧美精品免费观看二区| 香蕉久久夜色| 免费h精品视频在线播放| 亚洲在线成人| 久久在线免费观看| 亚洲一区二区在| 久久av免费一区| 一区二区动漫| 久久在线91| 亚洲欧美大片| 欧美96在线丨欧| 欧美一区二区三区在线免费观看 | 欧美日韩精品在线| 欧美国产欧美综合| 国产美女诱惑一区二区| 亚洲国内在线| 狠狠色噜噜狠狠色综合久 | 蜜臀久久久99精品久久久久久 | 欧美亚洲一区| 欧美日韩免费观看一区| 免费欧美电影| 国产视频久久| 狠狠入ady亚洲精品| 亚洲美女毛片| 欧美jjzz| 女生裸体视频一区二区三区| 欧美成人午夜剧场免费观看| 国产欧美日韩91| 亚洲最新在线| 99精品热视频只有精品10| 亚洲——在线| 亚洲第一天堂av| 国产一区二区三区自拍| 欧美福利在线观看| 欧美在线日韩| 99精品国产福利在线观看免费| 欧美一区在线看| 久久久久久尹人网香蕉| 亚洲人成在线观看网站高清| 久久阴道视频| 你懂的网址国产 欧美| 国产亚洲成av人在线观看导航 | 亚洲欧洲日产国码二区| 亚洲国产成人在线播放| 久久久亚洲一区| 欧美www视频| 亚洲第一黄网| 美女视频黄a大片欧美| 久久久久国内| 欧美—级在线免费片| 噜噜噜91成人网| 午夜在线一区| 亚洲小视频在线| 亚洲日本电影| 亚洲高清不卡| 这里只有精品丝袜| 亚洲制服av| 欧美乱妇高清无乱码| 亚洲欧洲日本一区二区三区| 午夜在线电影亚洲一区| 久久久久久网站| avtt综合网| 久久久美女艺术照精彩视频福利播放| 一本综合久久| 久久狠狠婷婷| 欧美激情精品久久久久久| 亚洲综合色在线| 老鸭窝亚洲一区二区三区| 猫咪成人在线观看| 欧美国产日韩一二三区| 亚洲无限av看| 欧美日本成人| 欧美激情亚洲精品| 国产伦精品一区二区三区照片91 | 亚洲高清免费视频| 亚洲肉体裸体xxxx137| 91久久在线播放| 亚洲一区亚洲二区| 国产亚洲精品aa午夜观看| 久久精品国产精品亚洲| 欧美bbbxxxxx| 亚洲欧美一级二级三级| 亚洲三级免费| 国产婷婷成人久久av免费高清| 麻豆av一区二区三区| aa亚洲婷婷| 欧美福利视频在线| 亚洲一区二区三区精品视频| 国产视频一区欧美| 欧美日韩精品免费观看| 久久精品官网| 亚洲性感激情| 亚洲高清一二三区| 欧美在线视频一区| 午夜影院日韩| 欧美日韩国产三区| 欧美在线啊v一区| 一区二区三区久久久| 欧美大秀在线观看| 欧美中文字幕在线播放| 一区二区毛片| 亚洲高清视频的网址| 国产欧美视频一区二区| 欧美精品在线观看一区二区| 欧美有码在线观看视频| 亚洲视频第一页| 91久久久久| 欧美刺激性大交免费视频| 欧美一区二区视频观看视频| 一二三四社区欧美黄| 亚洲人线精品午夜| 在线观看三级视频欧美| 国产精品日韩欧美一区二区| 欧美日韩国产丝袜另类| 久久一区亚洲| 久久精品一区二区三区不卡| 亚洲欧美在线看| 亚洲图片欧美一区| 中文高清一区| av不卡在线观看| 一本久久综合亚洲鲁鲁| 亚洲精品久久视频| 亚洲国产小视频| 欧美日韩一区二区在线视频| 欧美日韩精品欧美日韩精品| 在线视频欧美日韩精品| 国产精品入口夜色视频大尺度| 欧美精品激情blacked18| 另类春色校园亚洲| 久久亚洲图片| 另类亚洲自拍| 欧美大色视频| 欧美日韩理论| 国产精品美女www爽爽爽| 国产精品欧美日韩| 国产视频精品免费播放| 亚洲国产精品一区二区久| 亚洲精品久久久久|