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

積木

No sub title

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

常用鏈接

留言簿(1)

我參與的團隊

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

轉(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模式 - 玄機逸士 - 玄機逸士博客

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

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

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

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模式 - 玄機逸士 - 玄機逸士博客

注意:這個類圖是下面將要用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ù),玄機逸士認(rèn)為成為函數(shù)對象更合適一些),關(guān)于函數(shù)對象參見:函數(shù)對象

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

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

posted on 2013-03-08 10:36 Jacc.Kim 閱讀(275) 評論(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>
            国产欧美一区二区精品婷婷 | 免费日韩成人| 久久久福利视频| 久久久欧美一区二区| 久久在线精品| 亚洲缚视频在线观看| 亚洲国产精品久久久久婷婷884 | 久久久夜夜夜| 裸体女人亚洲精品一区| 欧美jizzhd精品欧美巨大免费| 开心色5月久久精品| 欧美国产一区二区三区激情无套| 欧美激情国产日韩| 亚洲九九爱视频| 亚洲一区二区精品| 久久av资源网| 欧美粗暴jizz性欧美20| 欧美日韩精品免费看| 国产精品女人毛片| 激情久久一区| 一区二区冒白浆视频| 欧美一级二区| 免费不卡在线观看av| 亚洲狼人精品一区二区三区| 夜夜嗨网站十八久久 | 国产精品永久| ●精品国产综合乱码久久久久| 亚洲欧洲一区二区三区在线观看| 夜夜躁日日躁狠狠久久88av| 亚洲欧美视频一区| 久久久噜噜噜久久人人看| 亚洲第一区在线观看| 亚洲最新在线视频| 久久精品国产免费| 欧美伦理一区二区| 国产真实精品久久二三区| 亚洲美女中文字幕| 欧美在线免费观看视频| 亚洲高清电影| 亚洲欧美日本视频在线观看| 另类成人小视频在线| 国产精品老牛| 91久久精品国产91性色| 午夜视黄欧洲亚洲| 欧美激情视频在线播放| 亚洲专区欧美专区| 欧美高清免费| 狠狠色狠狠色综合日日小说| 99re6这里只有精品视频在线观看| 欧美一二三区精品| 亚洲日韩欧美视频一区| 久久激情综合网| 国产精品h在线观看| 亚洲福利一区| 久久精品成人| 一本久道久久综合狠狠爱| 久久网站热最新地址| 国产精品网站一区| 日韩视频免费| 免费久久久一本精品久久区| 亚洲一区二区三区免费视频| 免费中文字幕日韩欧美| 国产三区二区一区久久| 国产精品99久久久久久久vr | 国产一区二区三区精品欧美日韩一区二区三区 | 玖玖综合伊人| 亚洲综合色婷婷| 欧美日韩在线播放三区四区| 亚洲电影免费在线观看| 久久国产精品99精品国产| 一二三区精品| 欧美日产一区二区三区在线观看| 136国产福利精品导航| 久久精品免费播放| 亚洲一区二区精品在线| 欧美视频在线视频| 一本色道久久精品| 亚洲国产岛国毛片在线| 麻豆成人在线| 在线观看日韩av先锋影音电影院| 欧美伊人久久久久久午夜久久久久 | 91久久在线| 欧美gay视频激情| 亚洲动漫精品| 欧美www视频| 久久免费视频在线观看| 狠狠综合久久| 蜜桃av一区二区| 久久久久国产精品一区三寸| 国产日韩专区| 久久久免费av| 久久久91精品国产一区二区三区| 国产乱码精品一区二区三区五月婷 | 国产精品入口麻豆原神| 亚洲欧美日韩一区| 亚洲免费在线精品一区| 国产精品一区二区久激情瑜伽| 亚洲欧美日韩国产成人| 亚洲视频欧美在线| 国产精品久久福利| 欧美一区二区高清| 欧美一区二区三区视频免费| 国产午夜精品全部视频播放| 久久国产精品久久国产精品| 欧美一区二区免费视频| 好看的av在线不卡观看| 免费看黄裸体一级大秀欧美| 久久综合网色—综合色88| 亚洲人成在线播放| 亚洲精品无人区| 国产精品卡一卡二| 久久激情久久| 久久综合给合| 99在线热播精品免费99热| 99视频超级精品| 国产欧美一区二区三区另类精品| 欧美在线综合视频| 久久久久久久久久久成人| 91久久综合亚洲鲁鲁五月天| 91久久综合亚洲鲁鲁五月天| 欧美午夜电影完整版| 久久成人在线| 老色批av在线精品| 一区二区三区精品久久久| 亚洲一区二区三区精品动漫| 国产亚洲欧洲| 亚洲高清不卡av| 国产精品久久久久久久浪潮网站| 久久精品亚洲国产奇米99| 另类尿喷潮videofree| 一区二区三区高清视频在线观看| 亚洲一区二区精品视频| 很黄很黄激情成人| 亚洲精品久久久蜜桃| 国产伦精品一区二区三| 欧美成人xxx| 国产精品hd| 免费看黄裸体一级大秀欧美| 欧美日韩一区二区在线播放| 久久精品视频在线播放| 欧美成人嫩草网站| 欧美一乱一性一交一视频| 麻豆亚洲精品| 性欧美1819性猛交| 欧美高清视频免费观看| 欧美专区在线播放| 欧美华人在线视频| 久久久www| 欧美日韩精品是欧美日韩精品| 久久精品国产清自在天天线| 欧美激情综合在线| 久久久www| 欧美视频福利| 欧美激情一区二区三区成人| 国产精品综合久久久| 亚洲国产小视频| 黄色成人免费观看| 亚洲一区二区精品在线观看| 亚洲破处大片| 久久精品亚洲一区二区三区浴池 | 亚洲欧洲日本国产| 性色av一区二区三区| 一区二区三区国产在线| 久久久精品网| 欧美一级艳片视频免费观看| 欧美 日韩 国产在线| 久久国产婷婷国产香蕉| 欧美视频免费看| 亚洲二区在线观看| 精品999日本| 欧美一区二区三区视频免费| 亚洲小说欧美另类社区| 欧美国产一区视频在线观看| 久久综合色播五月| 国产喷白浆一区二区三区| 妖精成人www高清在线观看| 亚洲破处大片| 老司机精品视频网站| 快射av在线播放一区| 国产日韩欧美在线一区| 亚洲午夜精品视频| 亚洲手机成人高清视频| 欧美激情亚洲综合一区| 欧美肥婆bbw| 亚洲风情亚aⅴ在线发布| 久久精品视频va| 久久亚洲一区| 国产亚洲视频在线观看| 中文日韩电影网站| 亚洲视频在线免费观看| 欧美日韩另类一区| 亚洲免费成人av| 99热这里只有精品8| 欧美另类极品videosbest最新版本| 欧美国产免费| 亚洲国产三级| 欧美粗暴jizz性欧美20| 亚洲国产精品女人久久久| 亚洲国产美女精品久久久久∴| 久久在线播放|