Facade模式
一 意圖
為子系統中的一組接口提供一個一致的界面,Facade模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。
二 動機
將一個系統划分成為若干個子系統有利於降低系統的復雜性。一個常見的設計目標是使子系統間的通信和相互依賴關系達到最小。
達到該目標的途徑之一是就是引入一個外觀(Facade)對象,它為子系統中較一般的設施提供了一個單一而簡單的界面。
將各個子系統整合起來作為Facade,提供給客戶端使用。
看下面這樣一個系統:
轉變成:
三 適用性及其結構
- 當你要為一個復雜子系統提供一個簡單接口時。
- 客戶程序與抽象類的實現部分之間存在着很大的依賴性。
- 當你需要構建一個層次結構的子系統時,使用Facade模式定義子系統中每層的入口點。僅通過facade進行通訊。
結構:
Facede:
知道哪些子系統類負責處理請求。
將客戶的請求代理給適當的子系統對象。
Subsystem classes :
實現子系統的功能。
處理由Facade對象指派的任務。
沒有facade的任何相關信息;即沒有指向facade的指針。
客戶程序通過發送請求給Facade的方式與子系統通訊, Facade將這些消息轉發給適當的子系統對象。
盡管是子系統中的有關對象在做實際工作,但Facade模式本身也必須將它的接口轉換成子系統的接口。
Facade模式有助於建立層次結構系統,也有助於對對象之間的依賴關系分層。
Facade模式可以消除復雜的循環依賴關系。降低客戶-子系統之間的耦合度。
使用Facade的客戶程序不需要直接訪問子系統對象。
四 代碼實現
1 subsystemClasses
以三種信息:SMS,MMS,PUSH為例:checkReady,getContent
/*----------------------------------------------------------------*/
/* class Base */
/*----------------------------------------------------------------*/
class Base
{
public:
Base(){};
};
/*----------------------------------------------------------------*/
/* class SmsUtil */
/*----------------------------------------------------------------*/
class SmsUtil: public Base
{
#define SMS_CONTENT "I am sms content"
public:
SmsUtil(){}
bool checkReady()
{
cout<<"SmsUtil checkReady"<<endl;
return true;
}
bool getSmsContent(int msg_id,char* pContent)
{
cout<<"SmsUtil getSmsContent"<<endl;
strcpy(pContent,SMS_CONTENT);
return true;
}
};
/*----------------------------------------------------------------*/
/* class MmsUtil */
/*----------------------------------------------------------------*/
class MmsUtil: public Base
{
#define MMS_CONTENT "I am mms content"
public:
MmsUtil(){}
bool checkReady()
{
cout<<"MmsUtil checkReady"<<endl;
return true;
}
bool getMmsContent(int msg_id,char* pContent)
{
cout<<"MmsUtil getMmsContent"<<endl;
strcpy(pContent,MMS_CONTENT);
return true;
}
};
/*----------------------------------------------------------------*/
/* class PushUtil */
/*----------------------------------------------------------------*/
class PushUtil: public Base
{
#define PUSH_CONTENT "I am push content"
public:
PushUtil(){}
bool checkReady()
{
cout<<"PushUtil checkReady"<<endl;
return true;
}
bool getPushContent(int msg_id,char* pContent)
{
cout<<"PushUtil getPushContent"<<endl;
strcpy(pContent,PUSH_CONTENT);
return true;
}
};
2 Facade ——單例類
/*----------------------------------------------------------------*/
/* class MsgFacade */
/*----------------------------------------------------------------*/
enum MsgType
{
SMS,
MMS,
PUSH,
MSG_ALL
};
class MsgFacade: public Base
{
protected:
MsgFacade()
{
m_sms = new SmsUtil();
m_mms = new MmsUtil();
m_push = new PushUtil();
}
public:
static MsgFacade* getInstance()
{
if (s_instance == NULL)
{
s_instance = new MsgFacade();
}
return s_instance;
}
static void closeInstance()
{
delete s_instance;
}
public:
bool checkReady(int type)
{
bool resutl = false;
resutl = m_sms->checkReady();
resutl &= m_mms->checkReady();
resutl &= m_push->checkReady();
return resutl;
}
bool getMsgContent(int type,int msg_id,char* pContent)
{
switch(type)
{
case SMS:
{
m_sms->getSmsContent(msg_id,pContent);
break;
}
case MMS:
{
m_mms->getMmsContent(msg_id,pContent);
break;
}
case PUSH:
{
m_push->getPushContent(msg_id,pContent);
break;
}
default:
break;
}
return true;
}
private:
SmsUtil* m_sms;
MmsUtil* m_mms;
PushUtil* m_push;
static MsgFacade* s_instance;
};
MsgFacade* MsgFacade::s_instance = NULL;
3 Test
#include "facade.h"
int main()
{
MsgFacade* msg = MsgFacade::getInstance();
msg->checkReady(MSG_ALL);
cout<<endl;
char content[100] = {0};
msg->getMsgContent(SMS,0,content);
cout<<content<<endl;
msg->getMsgContent(MMS,0,content);
cout<<content<<endl;
msg->getMsgContent(PUSH,0,content);
cout<<content<<endl;
return 0;
}
4 Result
SmsUtil checkReady
MmsUtil checkReady
PushUtil checkReady
SmsUtil getSmsContent
I am sms content
MmsUtil getMmsContent
I am mms content
PushUtil getPushContent
I am push content
僅需要一個Facade對象,因此Facade對象通常屬於Singleton 模式