《設計模式》學習筆記——命令模式
阿新 • • 發佈:2018-12-17
命令模式(Command Pattern)是一種資料驅動的設計模式,它屬於行為型模式。 請求以命令的形式包裹在物件中,並傳給呼叫物件。呼叫物件尋找可以處理該命令的合適的物件,並把該命令傳給相應的物件,該物件執行命令。
意圖: 將一個請求封裝成一個物件,從而使您可以用不同的請求對客戶進行引數化。主要解決: 在軟體系統中,行為請求者與行為實現者通常是一種緊耦合的關係. 但某些場合,比如需要對行為進行記錄、撤銷或重做、事務等處理時,這種無法抵禦變化的緊耦合的設計就不太合適。何時使用: 在某些場合,比如要對行為進行"記錄、撤銷/重做、事務"等處理,這種無法抵禦變化的緊耦合是不合適的。 在這種情況下,如何將"行為請求者"與"行為實現者"解耦?將一組行為抽象為物件,可以實現二者之間的鬆耦合。如何解決:
CommandPattern.h
#pragma once #include<iostream> #include<string> #include<list> class Docter { public: void treat_eye() { std::cout << "Docter treat_eye()" << std::endl; } void treat_nose() { std::cout << "Docter treat_nose()" << std::endl; } private: protected: }; // 抽象命令類 class CommandPattern { public: CommandPattern() {}; ~CommandPattern() {}; virtual void docterTreat() = 0; // 抽象介面 }; // 命令類 class CommandDocterTreatEye:public CommandPattern { public: CommandDocterTreatEye(Docter* docter):m_docter(docter){}; // 傳入引數,也叫注入引數 ~CommandDocterTreatEye() {}; virtual void docterTreat() // 抽象介面實現 { docterTreatEye(); // 實際呼叫 } private: Docter * m_docter; // 更好的方法是傳入Docter類的純虛基類做為一層介面,然後利用多型思想解耦和 void docterTreatEye() { m_docter->treat_eye(); } protected: }; // 命令類 class CommandDocterTreatNose :public CommandPattern { public: CommandDocterTreatNose(Docter* docter) :m_docter(docter) {}; // 傳入引數,也叫注入引數 ~CommandDocterTreatNose() {}; virtual void docterTreat() // 抽象介面實現 { docterTreatNose(); // 實際呼叫 } private: Docter * m_docter; // 更好的方法是傳入Docter類的純虛基類做為一層介面,然後利用多型思想解耦和 void docterTreatNose() { m_docter->treat_nose(); } // 實際呼叫 protected: }; // 護士類,命令的發起者 class BeautyNurse { public: BeautyNurse(CommandPattern * commandpattern): m_commandpattern(commandpattern){} ~BeautyNurse() {} void SubmitteCase() // 案例提交,下達命令 { m_commandpattern->docterTreat(); // 讓醫生治療 } private: CommandPattern * m_commandpattern; // 能夠採集命令 protected: }; // 護士長類,命令的批量發起者 class AdvHeadNurse { public: AdvHeadNurse() { m_commandPatternList.clear(); // 初始狀態清空列表 } ~AdvHeadNurse() {} void setCommend(CommandPattern * command) { m_commandPatternList.push_back(command); // 向列表新增命令 } void SubmitteCase() // 案例提交,下達命令 { for (auto it = m_commandPatternList.begin(); it != m_commandPatternList.end(); it++) (*it)->docterTreat(); } private: std::list<CommandPattern *> m_commandPatternList;// 能夠採集一批命令 protected: };
CommandPattern.cpp
#include "CommandPattern.h"
mainTest.cpp
#include<iostream>
#include<string>
#include "CommandPattern.h"
int mainTest1(void)
{
// 建立一個醫生物件
Docter* docter = new Docter;
// 建立一個命令物件
CommandPattern* commandPattern = new CommandDocterTreatNose(docter); // 通過構造注入一個物件
// 執行
commandPattern->docterTreat();
// 執行結束,刪除物件
delete commandPattern;
// 建立一個新命令物件
commandPattern = new CommandDocterTreatEye(docter); // 通過構造注入另一個物件
// 執行
commandPattern->docterTreat();
// 執行結束,刪除物件
delete commandPattern;
// 刪除物件
delete docter;
return 0;
}
int mainTest2()
{
// 建立一個醫生物件
Docter* docter = new Docter;
// 建立一個命令物件
//CommandPattern* commandPattern = new CommandDocterTreatNose(docter); // 通過構造注入一個物件
CommandPattern* commandPattern = new CommandDocterTreatEye(docter); // 通過構造注入一個物件
BeautyNurse* beautynurse = new BeautyNurse(commandPattern); // 建立一個護士物件,命令傳達者
beautynurse->SubmitteCase(); // 護士提交案例,傳達命令
// 執行結束,刪除物件
delete beautynurse;
// 執行結束,刪除物件
delete commandPattern;
// 刪除物件
delete docter;
system("pause");
return 0;
}
int main()
{
//mainTest1();
//mainTest2();
// 建立一個醫生物件
Docter* docter = new Docter;
// 建立一個命令物件
CommandPattern* commandPattern1 = new CommandDocterTreatNose(docter); // 通過構造注入一個物件
CommandPattern* commandPattern2 = new CommandDocterTreatEye(docter); // 通過構造注入一個物件
// 建立一個護士長物件
AdvHeadNurse* advHeadNurse = new AdvHeadNurse(); // 建立一個護士物件,命令傳達者
// 插入命令 插入命令可以修改擴充套件新增對可變引數的支援,能夠更加友好
advHeadNurse->setCommend(commandPattern1);
advHeadNurse->setCommend(commandPattern2);
// 批量傳達命令
advHeadNurse->SubmitteCase(); // 護士提交案例,傳達命令
// 執行結束,刪除物件
delete advHeadNurse;
// 執行結束,刪除物件
delete commandPattern2;
// 執行結束,刪除物件
delete commandPattern1;
// 刪除物件
delete docter;
system("pause");
return 0;
}