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

積木

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>
            久久久久久久精| av成人激情| 亚洲欧美在线观看| 亚洲国产精品久久久久婷婷884| 亚洲国产婷婷| 欧美www视频| 久久亚洲精品视频| 久久―日本道色综合久久| 亚洲欧美日韩综合一区| 亚洲午夜黄色| 欧美精品一区二| 亚洲黄色成人久久久| 暖暖成人免费视频| 蜜桃av噜噜一区二区三区| 久久国产精品72免费观看| 午夜精品久久久久久久99樱桃 | 久久天天躁狠狠躁夜夜爽蜜月| 亚洲在线1234| 亚洲欧美一区二区三区在线| 性欧美长视频| 久久综合久久久久88| 久久夜色精品国产欧美乱极品| 久久爱www久久做| 久久久久国产一区二区三区| 久久久美女艺术照精彩视频福利播放| 久久福利资源站| 久久午夜精品一区二区| 欧美成年视频| 欧美日韩视频不卡| 欧美激情影院| 亚洲欧洲在线视频| 中日韩美女免费视频网站在线观看| 日韩亚洲国产欧美| 亚洲性线免费观看视频成熟| 欧美亚洲视频| 欧美va天堂va视频va在线| 亚洲另类黄色| 性欧美1819性猛交| 美女精品网站| 国产精品va在线播放| 狠狠色丁香久久婷婷综合_中| 亚洲欧洲一区二区三区在线观看| av成人免费观看| 久久精品视频在线看| 亚洲电影第1页| 亚洲欧美成aⅴ人在线观看| 亚洲一区激情| 亚洲欧美日韩国产一区二区| 蜜桃视频一区| 国产日韩在线视频| 日韩午夜中文字幕| 老司机精品视频网站| 一区二区三区波多野结衣在线观看| 欧美伊人精品成人久久综合97 | 欧美人与性动交a欧美精品| 国产精品久久久久久久久久久久 | 亚洲淫性视频| 亚洲第一免费播放区| 亚洲性视频网址| 男女精品网站| 一区二区三区亚洲| 欧美一区二区成人| 99精品国产一区二区青青牛奶| 亚洲黄色影片| 国产精品久久久久久久久久尿 | 亚洲四色影视在线观看| 久久精品国产亚洲精品| 欧美日韩综合视频网址| 亚洲欧洲一区二区在线播放| 免费在线一区二区| 久久久久9999亚洲精品| 欧美国内亚洲| 亚洲电影观看| 久久综合色综合88| 一区二区免费看| 欧美亚洲免费在线| 国产婷婷精品| 欧美在线视频二区| 亚洲自拍电影| 国产一区二区三区观看| 久久精品网址| 久久精品国语| 在线成人www免费观看视频| 久久精品视频在线播放| 久久精品人人| 1000部精品久久久久久久久| 久久综合九色综合久99| 欧美亚洲在线| 精品粉嫩aⅴ一区二区三区四区| 久久精品久久综合| 欧美在线免费观看| 一色屋精品视频免费看| 美日韩丰满少妇在线观看| 久久久久看片| 国产在线精品一区二区夜色| 亚洲综合色丁香婷婷六月图片| 日韩视频免费观看高清完整版| 欧美久久久久久久| 中文在线不卡视频| 亚洲伊人伊色伊影伊综合网| 国产日本欧洲亚洲| 你懂的视频欧美| 欧美日韩1080p| 亚洲一区二区三区中文字幕 | 亚洲高清在线观看一区| 亚洲欧洲日产国产网站| 欧美日韩亚洲一区三区 | 久久久久免费视频| 亚洲精品小视频| 国内精品久久国产| 欧美一区二区三区视频| 亚洲电影免费观看高清完整版| 欧美性猛片xxxx免费看久爱| 欧美激情视频在线免费观看 欧美视频免费一| 欧美啪啪一区| 禁断一区二区三区在线| 欧美日韩国产片| 亚洲视频二区| 日韩视频免费在线观看| 亚洲综合二区| 136国产福利精品导航网址应用| 可以免费看不卡的av网站| 欧美制服第一页| 久久亚洲精选| 中文在线一区| 久久天天躁夜夜躁狠狠躁2022| 激情亚洲成人| 日韩视频精品在线| 亚洲欧美日韩网| 亚洲伦理在线观看| 久久国产精品久久久久久久久久 | 欧美日韩综合精品| 国产午夜精品一区二区三区欧美| 国产精品99一区| 国产在线精品二区| 国产一区二区三区的电影| 欧美日韩国语| 老**午夜毛片一区二区三区| 久久久人成影片一区二区三区| 夜夜嗨av色一区二区不卡| 欧美成年人视频| 亚洲欧美日韩网| 午夜在线一区| 午夜精品福利在线观看| 久久av一区二区三区漫画| 日韩亚洲欧美综合| 激情视频一区二区三区| 最新亚洲激情| 欧美高清视频www夜色资源网| 亚洲精品在线一区二区| 狠狠色噜噜狠狠狠狠色吗综合| 免费观看不卡av| 日韩午夜激情| 欧美插天视频在线播放| 欧美一区二区三区日韩视频| 亚洲欧美色婷婷| 久久久久国产一区二区| 国内自拍亚洲| 久久久国产精品一区| 欧美福利视频| 亚洲天堂成人在线视频| 国产精品稀缺呦系列在线| 久久er精品视频| 亚洲福利在线视频| 一区二区日韩欧美| 国产日韩一区二区三区在线播放| 久久精品人人做人人爽| 亚洲国产高清自拍| 午夜精品久久久久久久久久久久| 国产婷婷精品| 欧美二区在线播放| 午夜精品999| 亚洲区中文字幕| 久久精品2019中文字幕| 亚洲第一区色| 国产精品夜夜夜一区二区三区尤| 久久夜色精品国产噜噜av| 99视频+国产日韩欧美| 久久人人97超碰人人澡爱香蕉 | 久久精品首页| 一区二区免费在线视频| 欧美 日韩 国产一区二区在线视频 | 欧美日韩在线播放一区二区| 欧美在线亚洲在线| 亚洲欧洲精品一区二区三区不卡 | 欧美诱惑福利视频| 日韩亚洲一区在线播放| 国产日韩精品在线播放| 欧美日韩国产综合视频在线| 久久一区精品| 午夜免费电影一区在线观看| 欧美激情乱人伦| 久久精品亚洲一区二区| 一区二区动漫| 亚洲精品久久7777| 在线观看欧美日韩| 国产性天天综合网| 国产欧美精品日韩区二区麻豆天美| 欧美—级在线免费片| 久久一区二区三区av|