设计模式 笔记 命令模式 Command
//---------------------------15/04/25----------------------------
//Conmmand? 命令模式----對象行為型模式
/*
? ? 1:意圖:
? ? ? ? 將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進行參數(shù)化;對請求排隊或記錄請求日志,
? ? ? ? 以及支持可撤銷的操作。
? ? 2:別名:
? ? ? ? Action,Transaction(事務)
? ? 3:動機:
? ? 4:適用性:
? ? ? ? 1>抽象出待執(zhí)行的動作以參數(shù)化某對象。可以使用回調函數(shù)表達這種參數(shù)化機制。
? ? ? ? ? 也就是說,Conmmand模式是回調機制的一個面向對象的代替品。
? ? ? ? 2>在不同的時刻指定、排列和執(zhí)行請求。一個Conmmand對象可以有一個與初始請求無關的生存期。
? ? ? ? ? 如果請求的接收者可以用一種與地址空間無關的方式表達,那么就可以將負責該請求的命令對象
? ? ? ? ? 傳送給另一個不同的進程,并在那兒實現(xiàn)該請求。
? ? ? ? 3>支持取消操作。執(zhí)行操作后,可以調用一個接口來取消操作。
? ? ? ? 4>支持修改日志,這樣當系統(tǒng)崩潰時,這些修改可以被重做一遍。
? ? ? ? 5>用構建在原語操作上的高層操作構造一個系統(tǒng)。
? ? 5:結構:
? ? ? ? Client ? ? ? ? ? ? ? Invoker------->Command:
?? ? ? ? |? | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Execute()
? ? ? ? ? ? | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
?? ? ? ? |? | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ConcreteCommand:
? ? ? ? ? ? |------->Receiver:<-------------receiver
?? ? ? ? | ? ? ? ? ? Action() ? ? ? ? ? ? ? Execute()
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? { receiver->Action();}
?? ? ? ? |- - - - - - - - - - - - - - - - ->state
? ? 6:參與者:
? ? ? ? 1>Command:
? ? ? ? ? ? 聲明執(zhí)行操作的接口。
? ? ? ? 2>ConcreteCommand
? ? ? ? ? ? 1)將一個接收者對象綁定于一個動作。
? ? ? ? ? ? 2)調用接收者相應的操作,以實現(xiàn)Execute。
? ? ? ? 3>Client
? ? ? ? ? ? 創(chuàng)建一個具體命令對象并設定它的接受者。
? ? ? ? 4>Invoker
? ? ? ? ? ? 要求該命令執(zhí)行這個請求。
? ? ? ? 5>Receiver
? ? ? ? ? ? 知道如何實施與執(zhí)行一個請求相關的操作。任何類都可能作為一個接受者。
? ? 7:協(xié)作:
? ? ? ? 1>Client創(chuàng)建一個ConcreteCommand對象并指定它的Receiver對象。
? ? ? ? 2>某Invoker對象存儲該ConcreteCommand對象。
? ? ? ? 3>該Invoker通過調用Conmmand對象的Execute操作來提交一個請求。若該命令時可撤銷的,
? ? ? ? ? ConcreteCommand就在執(zhí)行Execute操作之前存儲當前狀態(tài)以用于取消該命令。
? ? ? ? 4>ConcreteCommand對象調用它的Receiver的一些操作以執(zhí)行該請求。
? ? 8:效果:
? ? ? ? 1>Command模式將調用操作的對象與指導如何實現(xiàn)該操作的對象解耦。
? ? ? ? 2>Command是頭等的對象。它們可以像其他的對象一樣被操作和擴展。
? ? ? ? 3>你可講多個命令裝配成一個復合命令。
? ? ? ? 4>增加新的Command很容易,因為這無需改變已有的類。
? ? 9:實現(xiàn):
? ? ? ? 1>一個命令對象應達到何種智能程度:
? ? ? ? ? ? 命令對象的能力可大可小。一個極端是只確定接收者和執(zhí)行該請求的動作。另一個極端是自己
? ? ? ? ? ? 實現(xiàn)所有功能,根本不需要額外的接收者對象。(這樣就退化成策略模式了)
? ? ? ? 2>支持取消和重做
? ? ? ? ? ? 如果Command提供方法逆轉他們操作的執(zhí)行(例如Unexecute或Undo操作),就可以支持取消和重做
? ? ? ? ? ? 功能。為了達到這個目的ConcreteCommand類需要存儲額外的狀態(tài)信息:
? ? ? ? ? ? ? ? 1)接收者對象,它真正執(zhí)行處理該請求的各操作。
? ? ? ? ? ? ? ? 2)接收者執(zhí)行操作的參數(shù)。
? ? ? ? ? ? ? ? 3)如果處理請求的操作會改變接收者對象中的某些值,那么這些值夜必須先存儲起來。接收者
? ? ? ? ? ? ? ? ? 還必須提供一些操作,以使該命令可將接收者恢復到它先前的狀態(tài)。
? ? ? ? 3>避免取消操作過程中的錯誤積累
? ? ? ? ? ? 使用Menmento模式來讓Command訪問信息時不暴露其他對象的內部信息。
? ? ? ? 4>使用C++模版
? ? ? ? ? ? 對 不能取消 并且 不需要參數(shù)的命令,可以使用C++模版實現(xiàn),這樣可以避免為每一種動作和接收者
? ? ? ? ? ? 都創(chuàng)建一個Command子類。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? 10:代碼示例:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */
//abstract Command類
class Command
{
public:
? ? virtual ~Command();
? ? virtual void Execute() = 0;
protected:
? ? Command();
};
//ConcreteCommand:
class OpenCommand : public Command
{
public:
? ? OpenCommand(Application*);
? ? virtual void Execute();
?? ?
protected:
? ? virtual const char* AskUser();
private:
? ? Application* _application;
? ? char* _response;
};
OpenCommand::OpenCommand(Application* a)
{
? ? _application = a;
}
//先請求一個名字,然后添加文件,然后打開之
void OpenCommand::Execute()
{
? ? const char* name = AskUser();
? ? if(name != 0)
? ? {
? ? ? ? Document* document = new Document(name);
? ? ? ? _application->Add(document);
? ? ? ? document->Open();
? ? }
}
//ConcreteCommand:
class PasteCommand : public Command
{
public:
? ? PasteCommand(Document*);
? ? virtual void Execute();
?? ?
private:
? ? Document* _document;
};
PasteCommand::PasteCommand(Document* doc)
{
? ? _document = doc;
}
void PasteCommand::Execute()
{
? ? _document->Paste();
}
//ConcreteCommand:通過模版實現(xiàn),避免多余的子類。
template<class Receiver>
class SimpleCommand : public Command
{
public:
? ? //創(chuàng)建一個別名:這是一個函數(shù)指針,一個參數(shù)為空,返回為空的Receiver類的成員函數(shù)指針
? ? //也是因為這個命令不需要參數(shù),所以可以聲明成模版類。
? ? typedef void (Receiver::* Action)();
? ? SimpleCommand(Receiver* r, Action a): _receiver(r), _action(a){}
? ? virtual void Execute();
?? ?
private:
? ? Action _action;
? ? Receiver* _receiver;
};
template<class Receiver>
void SimpleCommand<Receiver>::Execute()
{
? ? (_receiver->*_action)();
}
MyClass* Receiver = new MyClass;
//...
Command* aCommand = new SimpleCommand<MyClass>(receiver, &MyClass::Action);
//...
aCommand->Execute();
//ConcreteCommand:一次執(zhí)行多條命令的復合命令
class MarroCommand : public Command
{
public:
? ? MarroCommand();
? ? virtual ~MarroCommand();
?? ?
? ? virtual void Add(Command*);
? ? virtual void Remove(Command*);
?? ?
? ? virtual void Execute();
?? ?
private:
? ? List<Command*>* _cmds;
};
void MarroCommand::Execute()
{
? ? ListIterator<Command*> i(_cmds);
? ? for(i.First(); !i.IsDone(); i.Next())
? ? {
? ? ? ? Command* c = i.CurrentItem();
? ? ? ? c->Execute();
? ? }
}
void MarroCommand::Add(Command* c)
{
? ? _cmds->Append(c);
}
void MarroCommand::Remove(Command* c)
{
? ? _cmds->Remove(c);
}
轉載于:https://www.cnblogs.com/boydfd/p/4983124.html
總結
以上是生活随笔為你收集整理的设计模式 笔记 命令模式 Command的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [ZT]图像处理库的比较:OpenCV,
- 下一篇: TCP协议的一些认识及实践