设计模式 笔记 命令模式 Command
//---------------------------15/04/25----------------------------
//Conmmand? 命令模式----對(duì)象行為型模式
/*
? ? 1:意圖:
? ? ? ? 將一個(gè)請(qǐng)求封裝為一個(gè)對(duì)象,從而使你可用不同的請(qǐng)求對(duì)客戶(hù)進(jìn)行參數(shù)化;對(duì)請(qǐng)求排隊(duì)或記錄請(qǐng)求日志,
? ? ? ? 以及支持可撤銷(xiāo)的操作。
? ? 2:別名:
? ? ? ? Action,Transaction(事務(wù))
? ? 3:動(dòng)機(jī):
? ? 4:適用性:
? ? ? ? 1>抽象出待執(zhí)行的動(dòng)作以參數(shù)化某對(duì)象。可以使用回調(diào)函數(shù)表達(dá)這種參數(shù)化機(jī)制。
? ? ? ? ? 也就是說(shuō),Conmmand模式是回調(diào)機(jī)制的一個(gè)面向?qū)ο蟮拇嫫贰?/p>
? ? ? ? 2>在不同的時(shí)刻指定、排列和執(zhí)行請(qǐng)求。一個(gè)Conmmand對(duì)象可以有一個(gè)與初始請(qǐng)求無(wú)關(guān)的生存期。
? ? ? ? ? 如果請(qǐng)求的接收者可以用一種與地址空間無(wú)關(guān)的方式表達(dá),那么就可以將負(fù)責(zé)該請(qǐng)求的命令對(duì)象
? ? ? ? ? 傳送給另一個(gè)不同的進(jìn)程,并在那兒實(shí)現(xiàn)該請(qǐng)求。
? ? ? ? 3>支持取消操作。執(zhí)行操作后,可以調(diào)用一個(gè)接口來(lái)取消操作。
? ? ? ? 4>支持修改日志,這樣當(dāng)系統(tǒng)崩潰時(shí),這些修改可以被重做一遍。
? ? ? ? 5>用構(gòu)建在原語(yǔ)操作上的高層操作構(gòu)造一個(gè)系統(tǒng)。
? ? 5:結(jié)構(gòu):
? ? ? ? Client ? ? ? ? ? ? ? Invoker------->Command:
?? ? ? ? |? | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Execute()
? ? ? ? ? ? | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
?? ? ? ? |? | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ConcreteCommand:
? ? ? ? ? ? |------->Receiver:<-------------receiver
?? ? ? ? | ? ? ? ? ? Action() ? ? ? ? ? ? ? Execute()
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? { receiver->Action();}
?? ? ? ? |- - - - - - - - - - - - - - - - ->state
? ? 6:參與者:
? ? ? ? 1>Command:
? ? ? ? ? ? 聲明執(zhí)行操作的接口。
? ? ? ? 2>ConcreteCommand
? ? ? ? ? ? 1)將一個(gè)接收者對(duì)象綁定于一個(gè)動(dòng)作。
? ? ? ? ? ? 2)調(diào)用接收者相應(yīng)的操作,以實(shí)現(xiàn)Execute。
? ? ? ? 3>Client
? ? ? ? ? ? 創(chuàng)建一個(gè)具體命令對(duì)象并設(shè)定它的接受者。
? ? ? ? 4>Invoker
? ? ? ? ? ? 要求該命令執(zhí)行這個(gè)請(qǐng)求。
? ? ? ? 5>Receiver
? ? ? ? ? ? 知道如何實(shí)施與執(zhí)行一個(gè)請(qǐng)求相關(guān)的操作。任何類(lèi)都可能作為一個(gè)接受者。
? ? 7:協(xié)作:
? ? ? ? 1>Client創(chuàng)建一個(gè)ConcreteCommand對(duì)象并指定它的Receiver對(duì)象。
? ? ? ? 2>某Invoker對(duì)象存儲(chǔ)該ConcreteCommand對(duì)象。
? ? ? ? 3>該Invoker通過(guò)調(diào)用Conmmand對(duì)象的Execute操作來(lái)提交一個(gè)請(qǐng)求。若該命令時(shí)可撤銷(xiāo)的,
? ? ? ? ? ConcreteCommand就在執(zhí)行Execute操作之前存儲(chǔ)當(dāng)前狀態(tài)以用于取消該命令。
? ? ? ? 4>ConcreteCommand對(duì)象調(diào)用它的Receiver的一些操作以執(zhí)行該請(qǐng)求。
? ? 8:效果:
? ? ? ? 1>Command模式將調(diào)用操作的對(duì)象與指導(dǎo)如何實(shí)現(xiàn)該操作的對(duì)象解耦。
? ? ? ? 2>Command是頭等的對(duì)象。它們可以像其他的對(duì)象一樣被操作和擴(kuò)展。
? ? ? ? 3>你可講多個(gè)命令裝配成一個(gè)復(fù)合命令。
? ? ? ? 4>增加新的Command很容易,因?yàn)檫@無(wú)需改變已有的類(lèi)。
? ? 9:實(shí)現(xiàn):
? ? ? ? 1>一個(gè)命令對(duì)象應(yīng)達(dá)到何種智能程度:
? ? ? ? ? ? 命令對(duì)象的能力可大可小。一個(gè)極端是只確定接收者和執(zhí)行該請(qǐng)求的動(dòng)作。另一個(gè)極端是自己
? ? ? ? ? ? 實(shí)現(xiàn)所有功能,根本不需要額外的接收者對(duì)象。(這樣就退化成策略模式了)
? ? ? ? 2>支持取消和重做
? ? ? ? ? ? 如果Command提供方法逆轉(zhuǎn)他們操作的執(zhí)行(例如Unexecute或Undo操作),就可以支持取消和重做
? ? ? ? ? ? 功能。為了達(dá)到這個(gè)目的ConcreteCommand類(lèi)需要存儲(chǔ)額外的狀態(tài)信息:
? ? ? ? ? ? ? ? 1)接收者對(duì)象,它真正執(zhí)行處理該請(qǐng)求的各操作。
? ? ? ? ? ? ? ? 2)接收者執(zhí)行操作的參數(shù)。
? ? ? ? ? ? ? ? 3)如果處理請(qǐng)求的操作會(huì)改變接收者對(duì)象中的某些值,那么這些值夜必須先存儲(chǔ)起來(lái)。接收者
? ? ? ? ? ? ? ? ? 還必須提供一些操作,以使該命令可將接收者恢復(fù)到它先前的狀態(tài)。
? ? ? ? 3>避免取消操作過(guò)程中的錯(cuò)誤積累
? ? ? ? ? ? 使用Menmento模式來(lái)讓Command訪問(wèn)信息時(shí)不暴露其他對(duì)象的內(nèi)部信息。
? ? ? ? 4>使用C++模版
? ? ? ? ? ? 對(duì) 不能取消 并且 不需要參數(shù)的命令,可以使用C++模版實(shí)現(xiàn),這樣可以避免為每一種動(dòng)作和接收者
? ? ? ? ? ? 都創(chuàng)建一個(gè)Command子類(lèi)。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? 10:代碼示例:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */
//abstract Command類(lèi)
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;
}
//先請(qǐng)求一個(gè)名字,然后添加文件,然后打開(kāi)之
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:通過(guò)模版實(shí)現(xiàn),避免多余的子類(lèi)。
template<class Receiver>
class SimpleCommand : public Command
{
public:
? ? //創(chuàng)建一個(gè)別名:這是一個(gè)函數(shù)指針,一個(gè)參數(shù)為空,返回為空的Receiver類(lèi)的成員函數(shù)指針
? ? //也是因?yàn)檫@個(gè)命令不需要參數(shù),所以可以聲明成模版類(lèi)。
? ? 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í)行多條命令的復(fù)合命令
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);
}
轉(zhuǎn)載于:https://www.cnblogs.com/boydfd/p/4983124.html
總結(jié)
以上是生活随笔為你收集整理的设计模式 笔记 命令模式 Command的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: [ZT]图像处理库的比较:OpenCV,
- 下一篇: asp.net使用My97 Date P