设计模式之命令模式(Command)摘录
23種GOF設(shè)計模式一般分為三大類:創(chuàng)建型模式、結(jié)構(gòu)型模式、行為模式。
創(chuàng)建型模式抽象了實例化過程,它們幫助一個系統(tǒng)獨立于如何創(chuàng)建、組合和表示它的那些對象。一個類創(chuàng)建型模式使用繼承改變被實例化的類,而一個對象創(chuàng)建型模式將實例化委托給另一個對象。創(chuàng)建型模式有兩個不斷出現(xiàn)的主旋律。第一,它們都將關(guān)于該系統(tǒng)使用哪些具體的類的信息封裝起來。第二,它們隱藏了這些類的實例是如何被創(chuàng)建和放在一起的。整個系統(tǒng)關(guān)于這些對象所知道的是由抽象類所定義的接口。因此,創(chuàng)建型模式在什么被創(chuàng)建,誰創(chuàng)建它,它是怎樣被創(chuàng)建的,以及何時創(chuàng)建這些方面給予了很大的靈活性。它們允許用結(jié)構(gòu)和功能差別很大的“產(chǎn)品”對象配置一個系統(tǒng)。配置可以是靜態(tài)的(即在編譯時指定),也可以是動態(tài)的(在運行時)。
結(jié)構(gòu)型模式涉及到如何組合類和對象以獲得更大的結(jié)構(gòu)。結(jié)構(gòu)型類模式采用繼承機制來組合接口或?qū)崿F(xiàn)。結(jié)構(gòu)型對象模式不是對接口和實現(xiàn)進行組合,而是描述了如何對一些對象進行組合,從而實現(xiàn)新功能的一些方法。因為可以在運行時刻改變對象組合關(guān)系,所以對象組合方式具有更大的靈活性,而這種機制用靜態(tài)類組合是不可能實現(xiàn)的。
行為模式涉及到算法和對象間職責(zé)的分配。行為模式不僅描述對象或類的模式,還描述它們之間的通信模式。這些模式刻畫了在運行時難以跟蹤的復(fù)雜的控制流。它們將用戶的注意力從控制流轉(zhuǎn)移到對象間的聯(lián)系方式上來。行為類模式使用繼承機制在類間分派行為。行為對象模式使用對象復(fù)合而不是繼承。一些行為對象模式描述了一組對等的對象怎樣相互協(xié)作以完成其中任一個對象都無法單獨完成的任務(wù)。
創(chuàng)建型模式包括:1、FactoryMethod(工廠方法模式);2、Abstract Factory(抽象工廠模式);3、Singleton(單例模式);4、Builder(建造者模式、生成器模式);5、Prototype(原型模式).
結(jié)構(gòu)型模式包括:6、Bridge(橋接模式);7、Adapter(適配器模式);8、Decorator(裝飾模式);9、Composite(組合模式);10、Flyweight(享元模式);11、Facade(外觀模式);12、Proxy(代理模式).
行為模式包括:13、TemplateMethod(模板方法模式);14、Strategy(策略模式);15、State(狀態(tài)模式);16、Observer(觀察者模式);17、Memento(備忘錄模式);18、Mediator(中介者模式);19、Command(命令模式);20、Visitor(訪問者模式);21、Chain of Responsibility(責(zé)任鏈模式);22、Iterator(迭代器模式);23、Interpreter(解釋器模式).
Factory Method:定義一個用于創(chuàng)建對象的接口,讓子類決定將哪一個類實例化。Factory Method使一個類的實例化延遲到其子類。
Abstract Factory:提供一個創(chuàng)建一系列相關(guān)或相互依賴對象的接口,而無需指定他們具體的類。
Singleton:保證一個類僅有一個實例,并提供一個訪問它的全局訪問點。
Builder:將一個復(fù)雜對象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。
Prototype:用原型實例指定創(chuàng)建對象的種類,并且通過拷貝這個原型來創(chuàng)建新的對象。
Bridge:將抽象部分與它的實現(xiàn)部分分離,使它們都可以獨立地變化。
Adapter:將一個類的接口轉(zhuǎn)換成客戶希望的另外一個接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。
Decorator:動態(tài)地給一個對象添加一些額外的職責(zé)。就擴展功能而言, Decorator模式比生成子類方式更為靈活。
Composite:將對象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu)。Composite使得客戶對單個對象和復(fù)合對象的使用具有一致性。
Flyweight:運用共享技術(shù)有效地支持大量細粒度的對象。
Facade:為子系統(tǒng)中的一組接口提供一個一致的界面, Facade模式定義了一個高層接口,這個接口使得這一子系統(tǒng)更加容易使用。
Proxy:為其他對象提供一個代理以控制對這個對象的訪問。
Template Method:定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。Template Method使得子類可以不改變一個算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。
Strategy:定義一系列的算法,把它們一個個封裝起來, 并且使它們可相互替換。本模式使得算法的變化可獨立于使用它的客戶。
State:允許一個對象在其內(nèi)部狀態(tài)改變時改變它的行為。對象看起來似乎修改了它所屬的類。
Observer:定義對象間的一種一對多的依賴關(guān)系,以便當(dāng)一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都得到通知并自動刷新。
Memento:在不破壞封裝性的前提下,捕獲一個對象的內(nèi)部狀態(tài),并在該對象之外保存這個狀態(tài)。這樣以后就可將該對象恢復(fù)到保存的狀態(tài)。
Mediator:用一個中介對象來封裝一系列的對象交互。中介者使各對象不需要顯式地相互引用,從而使其耦合松散,而且可以獨立地改變它們之間的交互。
Command:將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進行參數(shù)化;對請求排隊或記錄請求日志,以及支持可取消的操作。
Visitor:表示一個作用于某對象結(jié)構(gòu)中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用于這些元素的新操作。
Chain of Responsibility:為解除請求的發(fā)送者和接收者之間耦合,而使多個對象都有機會處理這個請求。將這些對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有一個對象處理它。
Iterator:提供一種方法順序訪問一個聚合對象中各個元素, 而又不需暴露該對象的內(nèi)部表示。
Interpreter:給定一個語言, 定義它的文法的一種表示,并定義一個解釋器, 該解釋器使用該表示來解釋語言中的句子。
???????? Command:(1)、意圖: 將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進行參數(shù)化;對請求排隊或記錄請求日志,以及支持可撤銷的操作。
???????? (2)、適用性:A、抽象出待執(zhí)行的動作以參數(shù)化某對象;B、在不同的時刻指定、排列和執(zhí)行請求;C、支持取消操作;D、支持修改日志,這樣當(dāng)系統(tǒng)崩潰時,這些修改可以被重做一遍;E、用構(gòu)建在原語操作上的高層操作構(gòu)造一個系統(tǒng)。
???????? (3)、優(yōu)缺點:A、Command模式將調(diào)用操作的對象與知道如何實現(xiàn)該操作的對象解耦;B、Command是頭等的對象。它們可像其他的對象一樣被操作和擴展;C、你可將多個命令裝配成一個復(fù)合命令;D、增加新的Command很容易,因為這無需改變已有的類。
???????? (4)、相關(guān)模式:A、Composite模式可被用來實現(xiàn)宏命令;B、Memento模式可用來保持某個狀態(tài),命令用這一狀態(tài)來取消它的效果;C、在被放入歷史表列前必須被拷貝的命令起到一種原型的作用。
???????? (5)、命令模式:A、建立命令隊列;B、可以將命令記入日志;C、接收請求的一方可以拒絕;D、添加一個新命令類不影響其它類。命令模式把請求一個操作的對象與知道怎么操作一個操作的對象分開。
???????? (6)、Command模式通過將請求封裝到一個對象(Command)中,并將請求的接收者存放到具體的ConcreteCommand類中(Receiver),從而實現(xiàn)調(diào)用操作的對象和操作的具體實現(xiàn)者之間的解耦。
示例代碼1:
#include <iostream>
#include <string>
#include <vector>using namespace std;//烤肉師傅
class Barbucer
{
public:void MakeMutton(){cout<<"烤羊肉"<<endl;}void MakeChickenWing(){cout<<"烤雞翅膀"<<endl;}
};//抽象命令類
class Command {
protected:Barbucer* receiver;
public:Command(Barbucer* temp){receiver = temp;}virtual void ExecuteCmd() = 0;
};//烤羊肉命令
class BakeMuttonCmd : public Command
{
public:BakeMuttonCmd(Barbucer* temp) : Command(temp) {}virtual void ExecuteCmd(){receiver->MakeMutton();}
};//烤雞翅
class ChickenWingCmd : public Command
{
public:ChickenWingCmd(Barbucer* temp) : Command(temp) {}virtual void ExecuteCmd(){receiver->MakeChickenWing();}
};//服務(wù)員類
class Waiter
{
protected:vector<Command*> m_commandList;
public:void SetCmd(Command* temp){m_commandList.push_back(temp);cout<<"增加定單"<<endl;}//通知執(zhí)行void Notify(){vector<Command*>::iterator p = m_commandList.begin();while (p != m_commandList.end()) {(*p)->ExecuteCmd();p ++;}}
};//客戶端
int main()
{//店里添加烤肉師傅、菜單、服務(wù)員等顧客Barbucer* barbucer = new Barbucer();Command* cmd = new BakeMuttonCmd(barbucer);Command* cmd2 = new ChickenWingCmd(barbucer);Waiter* girl = new Waiter();//點菜girl->SetCmd(cmd);girl->SetCmd(cmd2);//服務(wù)員通知girl->Notify();/*result增加定單增加定單烤羊肉烤雞翅膀*/return 0;
}
示例代碼2:
Receiver.h:
#ifndef _RECEIVER_H_
#define _RECEIVER_H_class Receiver
{
public:Receiver();~Receiver();void Action();
protected:
private:
};#endif//~_RECEIVER_H_
Receiver.cpp:
#include "Receiver.h"
#include <iostream>Receiver::Receiver()
{}Receiver::~Receiver()
{}void Receiver::Action()
{std::cout<<"Receiver action ..."<<std::endl;
}
Command.h:
#ifndef _COMMAND_H_
#define _COMMAND_H_class Receiver;class Command
{
public:virtual ~Command();virtual void Excute() = 0;
protected:Command();
private:
};class ConcreteCommand : public Command
{
public:ConcreteCommand(Receiver* rev);~ConcreteCommand();void Excute();
protected:
private:Receiver* _rev;
};#endif//~_COMMAND_H_
Command.cpp:
#include "Command.h"
#include "Receiver.h"
#include <iostream>Command::Command()
{}Command::~Command()
{}void Command::Excute()
{}ConcreteCommand::ConcreteCommand(Receiver* rev)
{this->_rev = rev;
}ConcreteCommand::~ConcreteCommand()
{delete this->_rev;
}void ConcreteCommand::Excute()
{_rev->Action();std::cout<<"ConcreteCommand ..."<<std::endl;
}
Invoker.h:
#ifndef _INVOKER_H_
#define _INVOKER_H_class Command;class Invoker
{
public:Invoker(Command* cmd);~Invoker();void Invoke();
protected:
private:Command* _cmd;
};#endif//~_INVOKER_H_
Invoker.cpp:
#include "Invoker.h"
#include "Command.h"
#include <iostream>Invoker::Invoker(Command* cmd)
{_cmd = cmd;
}Invoker::~Invoker()
{delete _cmd;
}void Invoker::Invoke()
{_cmd->Excute();
}
main.cpp:
#include "Command.h"
#include "Invoker.h"
#include "Receiver.h"#include <iostream>using namespace std;int main()
{Receiver* rev = new Receiver();Command* cmd = new ConcreteCommand(rev);Invoker* inv = new Invoker(cmd);inv->Invoke();/*resultReceiver action ...ConcreteCommand ...*/return 0;
}
命令模式結(jié)構(gòu)圖:
參考文獻:
1、《大話設(shè)計模式C++》
2、《設(shè)計模式精解----GoF23種設(shè)計模式解析》
3、《設(shè)計模式----可復(fù)用面向?qū)ο筌浖幕A(chǔ)》
總結(jié)
以上是生活随笔為你收集整理的设计模式之命令模式(Command)摘录的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 设计模式之中介者模式(Mediator)
- 下一篇: 设计模式之访问者模式(Visitor)摘