Facade模式
作用:为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
动机
将一个系统划分成为若干个子系统有利于降低系统的复杂性。一个常见的设计目标是使子系统间的通信和相互依赖关系达到最小。
达到该目标的途径之一是就是引入一个外观(Facade)对象,它为子系统中较一般的设施提供了一个单一而简单的界面。
将各个子系统整合起来作为Facade,提供给客户端使用。
适用性
1.当你要为一个复杂子系统提供一个简单接口时。
2.客户程序与抽象类的实现部分之间存在着很大的依赖性。
3.当你需要构建一个层次结构的子系统时,使用Facade模式定义子系统中每层的入口点。仅通过facade进行通讯。
UML图如下:
Facade:
知道哪些子系统类负责处理请求。
将客户的请求代理给适当的子系统对象。
Subsystem classes :
实现子系统的功能。
处理由Facade对象指派的任务。
没有facade的任何相关信息;即没有指向facade的指针。
客户程序通过发送请求给Facade的方式与子系统通讯, Facade将这些消息转发给适当的子系统对象。
尽管是子系统中的有关对象在做实际工作,但Facade模式本身也必须将它的接口转换成子系统的接口。
Facade模式有助于建立层次结构系统,也有助于对对象之间的依赖关系分层。
Facade模式可以消除复杂的循环依赖关系。降低客户-子系统之间的耦合度。
使用Facade的客户程序不需要直接访问子系统对象。
代码如下:
Facade.h
1 #ifndef _FACADE_H_ 2 #define _FACADE_H_ 3 4 class Subsystem1 5 { 6 public: 7 Subsystem1(); 8 ~Subsystem1(); 9 void Operation(); 10 }; 11 12 class Subsystem2 13 { 14 public: 15 Subsystem2(); 16 ~Subsystem2(); 17 void Operation(); 18 }; 19 20 class Facade 21 { 22 public: 23 Facade(); 24 ~Facade(); 25 void OperationWrapper(); 26 private: 27 Subsystem1* _subsys1; 28 Subsystem2* _subsys2; 29 }; 30 31 #endif
Facade.cpp
1 #include "Facade.h" 2 #include <iostream> 3 4 using namespace std; 5 6 Subsystem1::Subsystem1() 7 {} 8 9 Subsystem1::~Subsystem1() 10 {} 11 12 void Subsystem1::Operation() 13 { 14 cout << "Subsystem1::Operation" << endl; 15 } 16 17 Subsystem2::Subsystem2() 18 {} 19 20 Subsystem2::~Subsystem2() 21 {} 22 23 void Subsystem2::Operation() 24 { 25 cout << "Subsystem2::Operation" << endl; 26 } 27 28 Facade::Facade() 29 { 30 this->_subsys1 = new Subsystem1(); 31 this->_subsys2 = new Subsystem2(); 32 } 33 34 Facade::~Facade() 35 { 36 delete this->_subsys1; 37 delete this->_subsys2; 38 39 this->_subsys1 = NULL; 40 this->_subsys2 = NULL; 41 } 42 43 void Facade::OperationWrapper() 44 { 45 this->_subsys1->Operation(); 46 this->_subsys2->Operation(); 47 }
main.cpp
1 #include "Facade.h" 2 3 int main() 4 { 5 Facade* pFacade = new Facade(); 6 pFacade->OperationWrapper(); 7 return 0; 8 }
另一个例子,转自http://www.cnblogs.com/bastard/archive/2012/02/03/2336706.html:
1 subsystemClasses
以三种信息:SMS,MMS,PUSH为例:checkReady,getContent
1 /*----------------------------------------------------------------*/ 2 /* class Base */ 3 /*----------------------------------------------------------------*/ 4 class Base 5 { 6 public: 7 Base(){}; 8 };
1 /*----------------------------------------------------------------*/ 2 /* class SmsUtil */ 3 /*----------------------------------------------------------------*/ 4 class SmsUtil: public Base 5 { 6 #define SMS_CONTENT "I am sms content" 7 public: 8 SmsUtil(){} 9 bool checkReady() 10 { 11 cout<<"SmsUtil checkReady"<<endl; 12 return true; 13 } 14 bool getSmsContent(int msg_id,char* pContent) 15 { 16 cout<<"SmsUtil getSmsContent"<<endl; 17 strcpy(pContent,SMS_CONTENT); 18 return true; 19 } 20 }; 21 22 /*----------------------------------------------------------------*/ 23 /* class MmsUtil */ 24 /*----------------------------------------------------------------*/ 25 class MmsUtil: public Base 26 { 27 #define MMS_CONTENT "I am mms content" 28 public: 29 MmsUtil(){} 30 bool checkReady() 31 { 32 cout<<"MmsUtil checkReady"<<endl; 33 return true; 34 } 35 bool getMmsContent(int msg_id,char* pContent) 36 { 37 cout<<"MmsUtil getMmsContent"<<endl; 38 strcpy(pContent,MMS_CONTENT); 39 return true; 40 } 41 }; 42 43 /*----------------------------------------------------------------*/ 44 /* class PushUtil */ 45 /*----------------------------------------------------------------*/ 46 class PushUtil: public Base 47 { 48 #define PUSH_CONTENT "I am push content" 49 public: 50 PushUtil(){} 51 bool checkReady() 52 { 53 cout<<"PushUtil checkReady"<<endl; 54 return true; 55 } 56 bool getPushContent(int msg_id,char* pContent) 57 { 58 cout<<"PushUtil getPushContent"<<endl; 59 strcpy(pContent,PUSH_CONTENT); 60 return true; 61 } 62 };
2 Facade ——单例类
1 /*----------------------------------------------------------------*/ 2 /* class MsgFacade */ 3 /*----------------------------------------------------------------*/ 4 enum MsgType 5 { 6 SMS, 7 MMS, 8 PUSH, 9 MSG_ALL 10 }; 11 12 class MsgFacade: public Base 13 { 14 protected: 15 MsgFacade() 16 { 17 m_sms = new SmsUtil(); 18 m_mms = new MmsUtil(); 19 m_push = new PushUtil(); 20 } 21 public: 22 static MsgFacade* getInstance() 23 { 24 if (s_instance == NULL) 25 { 26 s_instance = new MsgFacade(); 27 } 28 29 return s_instance; 30 } 31 static void closeInstance() 32 { 33 delete s_instance; 34 } 35 public: 36 bool checkReady(int type) 37 { 38 bool resutl = false; 39 40 resutl = m_sms->checkReady(); 41 resutl &= m_mms->checkReady(); 42 resutl &= m_push->checkReady(); 43 44 return resutl; 45 } 46 bool getMsgContent(int type,int msg_id,char* pContent) 47 { 48 switch(type) 49 { 50 case SMS: 51 { 52 m_sms->getSmsContent(msg_id,pContent); 53 break; 54 } 55 case MMS: 56 { 57 m_mms->getMmsContent(msg_id,pContent); 58 break; 59 } 60 case PUSH: 61 { 62 m_push->getPushContent(msg_id,pContent); 63 break; 64 } 65 default: 66 break; 67 } 68 69 return true; 70 } 71 private: 72 SmsUtil* m_sms; 73 MmsUtil* m_mms; 74 PushUtil* m_push; 75 76 static MsgFacade* s_instance; 77 }; 78 MsgFacade* MsgFacade::s_instance = NULL;
3 Test
1 #include "facade.h" 2 3 int main() 4 { 5 MsgFacade* msg = MsgFacade::getInstance(); 6 msg->checkReady(MSG_ALL); 7 8 cout<<endl; 9 char content[100] = {0}; 10 11 msg->getMsgContent(SMS,0,content); 12 cout<<content<<endl; 13 14 msg->getMsgContent(MMS,0,content); 15 cout<<content<<endl; 16 17 msg->getMsgContent(PUSH,0,content); 18 cout<<content<<endl; 19 20 return 0; 21 }
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 模式