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

積木

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>
            亚洲电影免费观看高清完整版在线 | 卡通动漫国产精品| 性久久久久久久| 国产综合婷婷| 亚洲国产精品成人久久综合一区| 老牛嫩草一区二区三区日本| 亚洲人成艺术| 亚洲午夜精品一区二区| 国产一区二区三区四区五区美女| 老牛国产精品一区的观看方式| 久久综合九色综合欧美狠狠| 亚洲日本va午夜在线影院| 夜夜精品视频| 激情久久中文字幕| 亚洲破处大片| 国产欧美二区| 亚洲电影视频在线| 国产精品高精视频免费| 久久理论片午夜琪琪电影网| 欧美成人亚洲成人| 欧美一级艳片视频免费观看| 久久精品国产免费观看| 一区二区高清在线| 久久精品国产免费看久久精品| 亚洲精选在线观看| 欧美一级播放| 一区二区三区精品视频在线观看| 校园春色国产精品| 夜色激情一区二区| 久久精品久久99精品久久| 这里只有精品视频在线| 久久成人久久爱| 亚洲午夜在线观看| 免播放器亚洲一区| 久久久久国产精品一区| 欧美日韩影院| 亚洲国产精品精华液2区45| 国产日韩欧美高清| 一区二区国产日产| 亚洲人成在线观看一区二区| 新片速递亚洲合集欧美合集| 在线一区视频| 欧美精品成人一区二区在线观看| 久久青青草原一区二区| 国产精品午夜国产小视频| 91久久线看在观草草青青| 一区一区视频| 久久精品观看| 欧美在线一级va免费观看| 欧美日韩一区在线| 亚洲啪啪91| 亚洲人体1000| 六月婷婷一区| 欧美激情a∨在线视频播放| 国模精品一区二区三区色天香| 一区二区三区免费网站| 在线视频亚洲一区| 欧美日韩国产欧| 亚洲精品一二| aa级大片欧美| 欧美日韩精品久久| 99精品视频一区二区三区| 日韩午夜电影av| 欧美连裤袜在线视频| 最近中文字幕mv在线一区二区三区四区 | 久久久蜜臀国产一区二区| 久久精品观看| 黑人巨大精品欧美黑白配亚洲| 亚洲欧美成人一区二区三区| 午夜精品视频在线| 国产一区二区三区av电影| 久久国产精品久久精品国产| 久久精品国产2020观看福利| 好吊成人免视频| 久久影视精品| 亚洲人成欧美中文字幕| a91a精品视频在线观看| 国产精品麻豆va在线播放| 中文精品一区二区三区| 久久精品导航| 亚洲国产一区二区三区高清| 欧美激情国产日韩精品一区18| 亚洲精品乱码久久久久久日本蜜臀 | 久久久人成影片一区二区三区观看 | 日韩午夜在线视频| 欧美色网在线| 欧美一区二区三区在线看| 欧美大片在线观看一区| 一区二区黄色| 国产一区二区三区四区| 免费在线亚洲欧美| 一本一本久久a久久精品牛牛影视| 亚洲欧美在线磁力| 激情欧美一区二区三区在线观看 | 亚洲女女女同性video| 久久三级视频| 日韩午夜一区| 国产主播在线一区| 欧美国产视频一区二区| 亚洲欧美激情诱惑| 亚洲电影在线| 欧美一区二区视频在线观看| 亚洲高清av在线| 国产精品久久久久久久久| 久久影视三级福利片| 一区二区三区视频在线播放| 免费观看成人网| 亚洲欧美日韩成人高清在线一区| 尤物yw午夜国产精品视频| 国产精品久久久久婷婷| 美女网站在线免费欧美精品| 亚洲欧美国产三级| 亚洲三级观看| 欧美成人激情在线| 久久久国产成人精品| 这里只有精品视频| 亚洲激情在线激情| 国内精品嫩模av私拍在线观看| 欧美日韩二区三区| 免费高清在线一区| 久久精品国产99国产精品| 亚洲性视频网址| 亚洲毛片在线看| 欧美激情乱人伦| 美国十次了思思久久精品导航| 性欧美videos另类喷潮| 一本色道久久| 亚洲美女视频在线观看| 亚洲第一区中文99精品| 狠狠色2019综合网| 国产亚洲激情| 国产亚洲综合精品| 国产精品一区二区久久国产| 欧美日韩午夜激情| 欧美精品综合| 欧美日韩成人网| 欧美日韩大陆在线| 欧美日韩一二三区| 欧美日韩p片| 欧美日韩视频免费播放| 欧美国产视频日韩| 欧美日本视频在线| 欧美日韩不卡一区| 国产精品分类| 国产精品一区二区三区久久久 | 欧美激情久久久久| 欧美激情五月| 欧美日韩理论| 国产精品裸体一区二区三区| 国产精品卡一卡二卡三| 国产伦精品一区二区三区视频孕妇 | 91久久精品日日躁夜夜躁欧美| 亚洲高清电影| 亚洲美女啪啪| 亚洲主播在线观看| 香蕉免费一区二区三区在线观看| 欧美在线日韩| 久久人人精品| 欧美日韩国产在线| 国产精品嫩草久久久久| 国产在线观看91精品一区| 黄色一区二区三区四区| 亚洲国产精品视频| 亚洲视频一区二区免费在线观看| 午夜精品在线观看| 久久综合伊人77777蜜臀| 亚洲大胆人体视频| 中文精品视频| 久久久久久久久久久久久久一区 | 老司机亚洲精品| 欧美日本精品在线| 国产日韩欧美综合一区| 亚洲高清电影| 西西人体一区二区| 免费在线播放第一区高清av| 亚洲精品免费看| 欧美在线看片| 欧美日韩三级| 在线日韩成人| 亚洲永久精品国产| 欧美成ee人免费视频| 一本大道久久精品懂色aⅴ| 久久国产欧美精品| 欧美日韩精品在线视频| 狠狠色狠狠色综合| 亚洲一区二区三区影院| 欧美va亚洲va国产综合| 亚洲视频日本| 欧美激情在线狂野欧美精品| 国产在线乱码一区二区三区| 一本一本a久久| 乱码第一页成人| 亚洲女人天堂av| 欧美老女人xx| 伊人蜜桃色噜噜激情综合| 亚洲欧美日韩在线综合| 亚洲人成人一区二区三区| 久久精品欧美| 国产一区二区欧美日韩| 新狼窝色av性久久久久久|