• <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++博客 :: 首頁 :: 聯系 :: 聚合  :: 管理
              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 閱讀(268) 評論(0)  編輯 收藏 引用 所屬分類: 設計模式
            中文国产成人精品久久不卡| 精品无码久久久久久尤物| 国产69精品久久久久9999| 久久se精品一区精品二区国产| 久久亚洲天堂| 久久青青草原精品国产| 开心久久婷婷综合中文字幕| 久久精品国产亚洲av高清漫画| 热久久国产精品| 色婷婷综合久久久久中文| 国内精品久久久久影院网站| 99久久99久久精品国产片果冻 | 亚洲乱码精品久久久久..| 青青草国产精品久久| 欧美熟妇另类久久久久久不卡| 国产精品99久久久久久董美香| 久久久久久久精品成人热色戒| 大香网伊人久久综合网2020| 九九久久自然熟的香蕉图片| 久久只有这精品99| 久久国产精品免费| 久久91综合国产91久久精品| 久久午夜伦鲁片免费无码| 伊人色综合久久天天人手人婷 | MM131亚洲国产美女久久| 久久成人国产精品免费软件| 亚洲欧美日韩精品久久亚洲区| 天天久久狠狠色综合| 亚洲AV无码成人网站久久精品大| 亚洲欧美久久久久9999| 日日狠狠久久偷偷色综合0| 国产精品va久久久久久久| 国产99久久九九精品无码| 国产精品美女久久久久av爽| 丰满少妇人妻久久久久久4| 国产日韩久久久精品影院首页| 国产精品日韩深夜福利久久| 亚洲欧美精品伊人久久| 精品久久久久中文字| 久久久久女教师免费一区| 区亚洲欧美一级久久精品亚洲精品成人网久久久久 |