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

            積木

            No sub title

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

            常用鏈接

            留言簿(1)

            我參與的團(tuán)隊(duì)

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            轉(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)建過(guò)程中,行為請(qǐng)求者行為實(shí)現(xiàn)者通常呈現(xiàn)一種緊耦合。但在某些場(chǎng)合,比如需要對(duì)行為進(jìn)行記錄、撤銷/重做(undo/redo)、事務(wù)等處理,這種無(wú)法抵御變化的緊耦合是不合適的。Command設(shè)計(jì)模式就是在這種情況下,將行為請(qǐng)求者行為實(shí)現(xiàn)者解耦,將一組行為抽象為對(duì)象,以實(shí)現(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

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

            Command存在的兩個(gè)重要原因:

            1. 解耦

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

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

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

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

            C++具體實(shí)現(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...

            說(shuō)明:上面的實(shí)現(xiàn)的Command模式從形式來(lái)說(shuō)和對(duì)象類型的Adapter幾乎沒(méi)有區(qū)別。

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

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

            注意:這個(gè)類圖是下面將要用C++代碼實(shí)現(xiàn)的示例程序中各類之間的關(guān)系圖。該示例程序用Command模式模擬了一個(gè)文本編輯器的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用來(lái)存放已經(jīng)執(zhí)行過(guò)的名利了呢個(gè),以便undo

            stack<Command*> executeCommandStack;

            // undoCommandStack用來(lái)存放undo過(guò)的命令,以便redo

            stack<Command*> undoCommandStack;

            public:

            ~CommandManager()

            {

            cout << "in the destructor of CommandManager..." << endl;

            }

            public:

            void executeCommand(Command *command)

            {

            command->execute();

            // 保存操作結(jié)果。將執(zhí)行過(guò)的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;

            }

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

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

            還有一點(diǎn),上面的Receiver類,可以考慮用Singleton模式來(lái)實(shí)現(xiàn)。

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

            posted on 2013-03-08 10:36 Jacc.Kim 閱讀(265) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 設(shè)計(jì)模式
            热99RE久久精品这里都是精品免费 | 久久国产热这里只有精品| 一本一道久久精品综合| 老司机午夜网站国内精品久久久久久久久| 狠狠色丁香婷综合久久| 久久影视国产亚洲| 国产精品99久久99久久久| 色综合色天天久久婷婷基地| 亚洲а∨天堂久久精品| 精品永久久福利一区二区| 精品国产青草久久久久福利| 性欧美大战久久久久久久久 | 无遮挡粉嫩小泬久久久久久久| 国内精品久久久久伊人av| 婷婷久久综合九色综合九七| 国内精品久久人妻互换| 伊人久久大香线蕉综合5g| 蜜桃麻豆www久久| 久久精品亚洲一区二区三区浴池| 久久高清一级毛片| 精品久久久久久国产91| 久久国产精品成人片免费| 一本久久精品一区二区| 国产精品亚洲综合专区片高清久久久| 漂亮人妻被中出中文字幕久久| 中文字幕久久欲求不满| 1000部精品久久久久久久久| 日本欧美久久久久免费播放网| 久久人妻少妇嫩草AV蜜桃| 婷婷久久五月天| 久久久久波多野结衣高潮| 伊人热热久久原色播放www| 久久精品免费网站网| 伊人久久免费视频| 精品午夜久久福利大片| 久久久久99精品成人片欧美| 少妇精品久久久一区二区三区| 亚洲国产精品无码久久98| 久久婷婷五月综合97色| 久久精品国产精品青草| 色综合久久综合网观看|