代理模式
代理模式的定義:為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問(wèn)
。在某些情況下,一個(gè)對(duì)象不適合 或不能直接引用另一個(gè)對(duì)象,而代理對(duì)象可以在客戶端和目標(biāo)對(duì)象之間起到中介的作用。
代理模式有以下三種角色:Subject(抽象主題角色)
:真實(shí)主題與代理主題的共同接口。RealSubject(真實(shí)主題角色)
:定義了代理角色所代表的真實(shí)對(duì)象。Proxy(代理主題角色)
:含有對(duì)真實(shí)主題角色的引用,代理角色通常在將客戶端調(diào)用傳遞給真實(shí)主題對(duì)象之前或者之后執(zhí)行某些操作,而不是單純返回真實(shí)的對(duì)象。
代碼演示:
//抽象主題角色
//抽象的公共接口
class AbstractCommonInterface
{
public:
virtual void run() = 0;
virtual ~AbstractCommonInterface() {};
};
//真實(shí)主題角色
//真實(shí)的系統(tǒng)
class MySystem :public AbstractCommonInterface
{
public:
void run() override
{
cout << "系統(tǒng)啟動(dòng)....." << endl;
}
};
在這里插入代碼片
//代理主題角色
//必須要有權(quán)限驗(yàn)證,不是所有人都能來(lái)啟動(dòng)我的系統(tǒng),提供用戶名和密碼
class MySystemProxy :public AbstractCommonInterface
{
public:
MySystemProxy(string mUserName, string mPassword) : mySystem(new MySystem){
this->mUserName = mUserName;
this->mPassword = mPassword;
};
~MySystemProxy(){
if (mySystem != nullptr) {
delete mySystem;
}
};
bool checkUserNameAndPassword() {
if (mUserName == "admin" && mPassword == "123")
{
return true;
}
else {
return false;
}
}
void run() override
{
if (checkUserNameAndPassword())
{
this->mySystem->run();//調(diào)真實(shí)的服務(wù)系統(tǒng)
}else {
cout << "accout or password is error!" << endl;
}
}
private:
MySystem* mySystem;//真實(shí)系統(tǒng)的指針
string mUserName; //賬號(hào)
string mPassword; //密碼
};
測(cè)試調(diào)用:
int main(int argc, char* argv[])
{
AbstractCommonInterface* mySystemProxy = new MySystemProxy("admin","123");
mySystemProxy->run();
delete mySystemProxy;
return 0;
}
輸出結(jié)果:
代理模式類的UML圖如下:
外觀模式
根據(jù)迪米特法則,如果兩個(gè)類不必彼此直接通信,那么這兩個(gè)類就不應(yīng)當(dāng)發(fā)生直接的相互作用。
Facade模式也叫外觀模式,是由GoF提供的23種設(shè)計(jì)模式中的一種。
Facade模式為一組有類似功能的類群,比如類庫(kù),子系統(tǒng)等待,提供一個(gè)一致的簡(jiǎn)單界面。這個(gè)一致的簡(jiǎn)單界面被稱作Facade。外觀模式就是將復(fù)雜的子類系統(tǒng)抽象到同一個(gè)接口進(jìn)行管理,外界只需要通過(guò)此接口與子類系統(tǒng)進(jìn)行交互,而不必要直接與復(fù)雜的子類系統(tǒng)進(jìn)行交互
。
角色和職責(zé)
Facade(外觀角色)
:為調(diào)用方,定義簡(jiǎn)單的調(diào)用接口。SubSystem(子系統(tǒng)角色)
:功能提供者。指提供功能的類群(模塊或子系統(tǒng))。
代碼演示一:
子系統(tǒng)代碼
:
//子系統(tǒng) 1
class SubSystem1
{
public:
void run() {
cout << "子系統(tǒng)一運(yùn)行..." << endl;
}
};
//子系統(tǒng) 2
class SubSystem2
{
public:
void run() {
cout << "子系統(tǒng)二運(yùn)行..." << endl;
}
};
//子系統(tǒng) 3
class SubSystem3
{
public:
void run() {
cout << "子系統(tǒng)三運(yùn)行..." << endl;
}
};
//子系統(tǒng) 4
class SubSystem4
{
public:
void run() {
cout << "子系統(tǒng)四運(yùn)行..." << endl;
}
};
外觀類代碼
:
class Facade
{
public:
Facade() {
pSystem1 = new SubSystem1;
pSystem2 = new SubSystem2;
pSystem3 = new SubSystem3;
pSystem4 = new SubSystem4;
}
~Facade() {
delete pSystem1;
delete pSystem2;
delete pSystem3;
delete pSystem4;
}
void runSystem(){
pSystem1->run();
pSystem2->run();
pSystem3->run();
pSystem4->run();
}
private:
SubSystem1* pSystem1;
SubSystem2* pSystem2;
SubSystem3* pSystem3;
SubSystem4* pSystem4;
};
注意
:因?yàn)镕acade類的成員變量SubSystem1/2/3/4類型的指針,而不是SubSystem1類型的實(shí)例是其成員變量,
所以這里Facade類和SubSystem1/2/3/4都不能稱為關(guān)聯(lián)。又因?yàn)镕acade類的構(gòu)造函數(shù)中,用到了SubSystem1/2/3/4類。
所以Facade類依賴于SubSystem1/2/3/4類。Facade類和SubSystem1/2/3/4類是依賴關(guān)系。拓展
:關(guān)聯(lián)是“HAS”關(guān)系,依賴是“USE”關(guān)系 。A類關(guān)聯(lián)B類,指的是B類對(duì)象作為A類的屬性存在,稱為“has”關(guān)系。
A類依賴B類,指的是B的對(duì)象作為A類的方法參數(shù)或者在A類的方法內(nèi) 存在,稱為“use”關(guān)系 。測(cè)試調(diào)用代碼
:
void test(){
Facade* facade = new Facade;
facade->runSystem();
}
int main(int argc, char *argv[])
{
test()
return 0;
}
針對(duì)上例的外觀模式UML類圖:
代碼演示二:
根據(jù)類圖,實(shí)現(xiàn)家庭影院外觀模式
實(shí)現(xiàn)KTV模式:
開啟時(shí):電視打開,燈關(guān)掉,音響打開,麥克風(fēng)打開,dvd打開。
關(guān)閉時(shí):電視關(guān)掉,燈打開,音響關(guān)掉,麥克風(fēng)關(guān)掉,dvd關(guān)掉。
實(shí)現(xiàn)游戲模式:
開啟時(shí):電視打開,音響打開,游戲機(jī)打開。
關(guān)閉時(shí):電視關(guān)掉,音響關(guān)掉,游戲機(jī)關(guān)掉。
子系統(tǒng)角色:
//電視機(jī)
class Television
{
public:
void On(){
cout << "電視機(jī)打開...." << endl;
}
void Off(){
cout << "電視機(jī)關(guān)閉...." << endl;
}
};
//燈
class Light
{
public:
void On(){
cout << "燈打開...." << endl;
}
void Off(){
cout << "燈關(guān)閉...." << endl;
}
};
//音箱
class Audio
{
public:
void On(){
cout << "音箱打開...." << endl;
}
void Off(){
cout << "音箱關(guān)閉...." << endl;
}
};
//麥克風(fēng)
class Microphone
{
public:
void On(){
cout << "麥克風(fēng)打開...." << endl;
}
void Off(){
cout << "麥克風(fēng)關(guān)閉...." << endl;
}
};
//DVD播放器
class DVDPlayer
{
public:
void On(){
cout << "DVD播放器打開...." << endl;
}
void Off(){
cout << "DVD播放器關(guān)閉...." << endl;
}
};
//游戲機(jī)
class Gamemachine
{
public:
void On(){
cout << "游戲機(jī)打開...." << endl;
}
void Off(){
cout << "游戲機(jī)關(guān)閉...." << endl;
}
};
外觀角色:
//KTV模式
class KTVMode
{
public:
KTVMode(){
pTv = new Television;
pLight = new Light;
pAudio = new Audio;
pMicrophone = new Microphone;
pDvd = new DVDPlayer;
}
~KTVMode(){
delete pTv;
delete pLight;
delete pAudio;
delete pMicrophone;
delete pDvd;
}
void OnKTV(){
pTv->On();
pLight->Off();
pAudio->On();
pMicrophone->On();
pDvd->On();
}
void OffKTV(){
pTv->Off();
pLight->On();
pAudio->Off();
pMicrophone->Off();
pDvd->Off();
}
private:
Television* pTv;
Light* pLight;
Audio* pAudio;
Microphone* pMicrophone;
DVDPlayer* pDvd;
};
//游戲模式
class GameMode
{
public:
GameMode(){
pTv = new Television;
pAudio = new Audio;
pGamemachine = new Gamemachine;
}
~GameMode(){
delete pTv;
delete pAudio;
delete pGamemachine;
}
void OnGame(){
pTv->On();
pAudio->On();
pGamemachine->On();
}
void OffGame(){
pTv->Off();
pAudio->Off();
pGamemachine->Off();
}
private:
Television* pTv;
Audio* pAudio;
Gamemachine* pGamemachine;
};
測(cè)試調(diào)用:
//測(cè)試KTV模式
void testKTVMode()
{
KTVMode* pKTVMode = new KTVMode;
pKTVMode->OnKTV();//開啟KTV模式
//pKTVMode->OffKTV();//關(guān)閉KTV模式
}
//測(cè)試游戲模式
void testGameMode()
{
GameMode* pGameMode = new GameMode;
pGameMode->OnGame();//開啟游戲模式
//pGameMode->OffGame();//關(guān)閉游戲模式
}
int main(int argc, char *argv[])
{
testKTVMode();
//testGameMode();
return 0;
}
針對(duì)上例的外觀模式UML類圖:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-796418.html
外觀模式適用場(chǎng)景
1.復(fù)雜系統(tǒng)需要簡(jiǎn)單入口使用。
2.客戶端程序與多個(gè)子系統(tǒng)之間存在很大的依賴性。
3.在層次化結(jié)構(gòu)中,可以使用外觀模式定義系統(tǒng)中每一層的入口,
層與層之間不直接產(chǎn)生聯(lián)系,而通過(guò)外觀類建立聯(lián)系,降低層之間的耦合度。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-796418.html
到了這里,關(guān)于C++設(shè)計(jì)模式-- 2.代理模式 和 外觀模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!