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

積木

No sub title

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

常用鏈接

留言簿(1)

我參與的團(tuán)隊

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

轉(zhuǎn)載自: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.

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

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

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

Command存在的兩個重要原因:

1. 解耦

17. C++實現(xiàn)Behavioral - Command模式 - 玄機(jī)逸士 - 玄機(jī)逸士博客

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

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

17. C++實現(xiàn)Behavioral - Command模式 - 玄機(jī)逸士 - 玄機(jī)逸士博客

C++具體實現(xiàn)代碼:

// 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;

}

輸出結(jié)果:

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...

說明:上面的實現(xiàn)的Command模式從形式來說和對象類型的Adapter幾乎沒有區(qū)別。

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

17. C++實現(xiàn)Behavioral - Command模式 - 玄機(jī)逸士 - 玄機(jī)逸士博客

注意:這個類圖是下面將要用C++代碼實現(xiàn)的示例程序中各類之間的關(guān)系圖。該示例程序用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)

{

// 將接收到的參數(shù),傳遞給基類構(gòu)造函數(shù)

}

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)

{

// 將接收到的參數(shù)傳遞給基類

}

~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用來存放已經(jīng)執(zhí)行過的名利了呢個,以便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();

// 保存操作結(jié)果。將執(zhí)行過的Command,壓入executeCommandStack

executeCommandStack.push(command);

}

void undoCommand()

{

if(executeCommandStack.size() > 0)

{

// executeCommandStack彈出最后一次執(zhí)行的command

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

executeCommandStack.pop();

command->undo();

// command壓入undoCommandStack

undoCommandStack.push(command);

}

}

void redoCommand()

{

if(undoCommandStack.size() > 0)

{

// undoCommandStack彈出最后一次執(zhí)行的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;

}

運行結(jié)果:

---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對象作為參數(shù)進(jìn)行傳遞(因為在JavaC#中,由于不存在指針,因此方法本身不能作為參數(shù)進(jìn)行傳遞,在C++盡管有指針,如果使用Command設(shè)計模式,還是可以提高解耦的能力,同時可以使代碼更具有可讀性),除去解耦的宗旨外,Command設(shè)計模式最重要的實質(zhì)就是,就是將方法封裝成為對象,從而可以作為參數(shù)進(jìn)行傳遞。

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

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

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

posted on 2013-03-08 10:36 Jacc.Kim 閱讀(271) 評論(0)  編輯 收藏 引用 所屬分類: 設(shè)計模式
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            久久久久九九九| 制服诱惑一区二区| 久久久精品日韩| 欧美在线观看一二区| 狠狠网亚洲精品| 欧美成人精品福利| 欧美高清你懂得| 亚洲午夜电影网| 欧美在线视频免费| 最近中文字幕mv在线一区二区三区四区| 免费一级欧美片在线观看| 免费国产自线拍一欧美视频| 亚洲乱码国产乱码精品精天堂| 亚洲人体1000| 国产精品久久久久秋霞鲁丝| 久久都是精品| 欧美99在线视频观看| 一区二区毛片| 欧美在线高清| 一本不卡影院| 久久精品成人一区二区三区| 亚洲精品系列| 欧美一区二区视频在线观看2020 | 久久成人精品| 日韩午夜中文字幕| 欧美一级网站| 宅男精品视频| 久久久999成人| 亚洲欧美日韩精品久久久久| 久久精品水蜜桃av综合天堂| 亚洲一二三区视频在线观看| 久久精品国产在热久久| 亚洲夜晚福利在线观看| 久久久久一区二区三区四区| 亚洲图片在线观看| 久久一区二区精品| 欧美一区日本一区韩国一区| 欧美美女福利视频| 美女免费视频一区| 国产欧美日韩一区| 一本大道久久a久久精二百| 精品成人一区二区三区| 一区二区三区高清不卡| 最新国产拍偷乱拍精品| 午夜亚洲视频| 午夜久久福利| 欧美日韩一区在线观看视频| 亚洲电影在线播放| 狠狠色伊人亚洲综合成人| 亚洲伊人网站| 亚洲欧美日本日韩| 欧美午夜电影在线观看| 亚洲欧洲精品成人久久奇米网| 曰本成人黄色| 久久国产日本精品| 久久av老司机精品网站导航| 国产精品国产三级国产aⅴ无密码| 亚洲电影有码| 亚洲精品中文字| 免费亚洲一区二区| 女人香蕉久久**毛片精品| 国精品一区二区| 欧美一区二区三区免费观看| 欧美一区精品| 国产尤物精品| 久久精品免费| 欧美福利视频网站| 亚洲国产二区| 欧美成人情趣视频| 亚洲激情啪啪| 在线亚洲一区观看| 欧美三区在线视频| 在线中文字幕一区| 亚洲欧美日韩久久精品| 国产精品欧美日韩一区| 午夜影院日韩| 女人香蕉久久**毛片精品| 亚洲精品乱码久久久久久日本蜜臀| 你懂的视频一区二区| 亚洲美女毛片| 欧美一区二区久久久| 国产欧美一区二区三区另类精品| 亚洲欧美激情在线视频| 久久天天躁狠狠躁夜夜爽蜜月| 伊人激情综合| 欧美日韩三级视频| 欧美日韩精品三区| 亚洲女爱视频在线| 蜜臀91精品一区二区三区| 亚洲毛片av在线| 国产精品免费观看在线| 久久九九电影| 日韩午夜激情| 久久艳片www.17c.com| 亚洲人成在线免费观看| 国产精品久久久久av免费| 久久激情五月丁香伊人| 亚洲黄色免费网站| 亚洲欧美日韩在线一区| 在线国产亚洲欧美| 国产精品第2页| 久久午夜精品一区二区| 99精品福利视频| 麻豆成人综合网| 亚洲天堂av图片| 亚洲激情视频在线观看| 国产精品视频网| 欧美激情片在线观看| 午夜精品成人在线| 亚洲精品国产欧美| 久久综合中文字幕| 亚洲免费一区二区| 亚洲人成网站影音先锋播放| 国产人成一区二区三区影院| 欧美成人一区二区三区片免费| 亚洲资源在线观看| 亚洲精品麻豆| 美女图片一区二区| 欧美一区国产二区| 亚洲一区二区三区午夜| 亚洲国产精品黑人久久久| 国产日产欧美精品| 欧美午夜激情视频| 欧美精品在线观看91| 久久这里只有| 久久九九精品| 久久久精品国产一区二区三区| 亚洲男同1069视频| 亚洲综合视频1区| 一区二区久久久久| 99re国产精品| 日韩视频在线一区二区| 亚洲国产精品久久久久婷婷老年| 久久综合伊人77777尤物| 久久精品导航| 欧美在线视频一区二区三区| 亚洲综合日本| 亚洲午夜久久久| 在线视频日本亚洲性| 日韩一区二区久久| 亚洲精品欧美日韩| 亚洲精品影院| 一区二区国产日产| 中国日韩欧美久久久久久久久| 日韩亚洲欧美在线观看| 一本色道久久综合一区| 一区二区三区高清在线观看| 亚洲视频一区二区| 新67194成人永久网站| 午夜在线a亚洲v天堂网2018| 亚洲欧美日本视频在线观看| 亚洲欧美日韩视频二区| 欧美一区二区视频在线| 久久久久久9| 欧美激情第8页| 亚洲精品少妇30p| 中日韩美女免费视频网址在线观看| 在线视频精品| 午夜免费久久久久| 久久精品国产一区二区三区| 开元免费观看欧美电视剧网站| 欧美成人亚洲成人| 欧美日韩成人一区| 国产精品自拍一区| 亚洲第一精品久久忘忧草社区| 亚洲乱码精品一二三四区日韩在线| 亚洲桃色在线一区| 欧美一区亚洲| 亚洲激情国产精品| 亚洲在线电影| 老色鬼久久亚洲一区二区| 欧美精品自拍| 国产综合自拍| 中日韩男男gay无套| 欧美在线一二三| 亚洲国产精品一区二区www在线| 日韩西西人体444www| 久久激情综合| 欧美午夜一区二区福利视频| 国内精品免费在线观看| 中文久久乱码一区二区| 久久久久久高潮国产精品视| 亚洲清纯自拍| 久久精品国产亚洲aⅴ| 欧美激情女人20p| 国语自产精品视频在线看一大j8| 夜夜嗨av一区二区三区中文字幕| 欧美在线精品免播放器视频| 亚洲精品久久嫩草网站秘色| 久久av红桃一区二区小说| 欧美日韩免费看| 在线精品亚洲一区二区| 欧美在线视频一区二区三区| 亚洲精品乱码视频| 蜜臀av国产精品久久久久| 国产精品一区免费视频| 亚洲无线一线二线三线区别av| 免费在线视频一区| 亚洲欧美日韩网| 欧美色网在线|