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 ;
  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[] = {};
  10.  
  11. msg->getMsgContent(SMS,,content);
  12. cout<<content<<endl;
  13.  
  14. msg->getMsgContent(MMS,,content);
  15. cout<<content<<endl;
  16.  
  17. msg->getMsgContent(PUSH,,content);
  18. cout<<content<<endl;
  19.  
  20. return ;
  21. }

4 Result

  1. SmsUtil checkReady
  2. MmsUtil checkReady
  3. PushUtil checkReady
  4.  
  5. SmsUtil getSmsContent
  6. I am sms content
  7. MmsUtil getMmsContent
  8. I am mms content
  9. PushUtil getPushContent
  10. I am push content

仅需要一个Facade对象,因此Facade对象通常属于Singleton 模式

C++设计模式-Facade模式的更多相关文章

  1. 设计模式--外观(Facade)模式

    Insus.NET在去年有写过一篇<软件研发公司,外观设计模式(Facade)>http://www.cnblogs.com/insus/archive/2013/02/27/293606 ...

  2. 设计模式之Facade模式

    Facade(外观)模式为子系统中的各类(或结构与方法)提供一个简明一致的界面,隐藏子系统的复杂性,使子系统更加容易使用.他是为子系统中的一组接口所提供的一个一致的界面. 在遇到以下情况使用Facad ...

  3. 设计模式——外观模式(Facade)

    1. 概述     外观模式,我们通过外观的包装,使应用程序只能看到外观对象,而不会看到具体的细节对象,这样无疑会降低应用程序的复杂度,并且提高了程序的可维护性. 例子1:一个电源总开关可以控制四盏灯 ...

  4. 一天学习两个设计模式之Facade模式(外观模式,结构型模式)

    程序这东西随着时间推移,程序会越来越大,程序中的类越来越多,而且他们之间相互关联,这会导致程序结构变得越来越复杂.因此我们在使用他们时候,必须要弄清楚他们之间的关系才能使用他们. 特别是在调用大型程序 ...

  5. Java设计模式(11)外观模式(Facade模式)

    外观模式(Facade)的定义:为子系统中的一组接口提供一个一致的界面. Facade一个典型应用就是数据库JDBC的应用,如下例对数据库的操作: public class DBCompare { C ...

  6. 设计模式——门面模式(Facade)

    要想正确理解设计模式,首先必须明白它是为了解决什么问题而提出来的. 设计模式学习笔记 --Shulin 转载请注明出处:http://blog.csdn.net/zhshulin 1.概念 门面模式是 ...

  7. Facade模式——设计模式学习(转载)

    Facade模式 一 意图 为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 二 动机 将一个系统划分成为若干个子系统有利于降低系统的复 ...

  8. java的设计模式 - 外观模式(Facade)

    目的 看脸模式目的很简单,就是给用户留个好印象,不想让用户关注系统中的具体细节,关注系统的外表(暴露出来的接口)就好了.一些 GUI 的菜单也好,SDK 也好或多或少也会用到这种思想.这更多的是一种思 ...

  9. 设计模式(十五)Facade模式

    Facade模式可以为相互关联在一起的错综复杂的类整理出高层接口,可以让系统对外只有一个简单的接口,而且还会考虑到系统内部各个类之间的责任关系和依赖关系,按照正常的顺序调用各个类. 还是先看一下示例程 ...

随机推荐

  1. 初步认知java的方法

    1.正确区分函数和方法: 面向对象的语言叫做方法,面向过程的语言叫做函数,两者的意义是一样的,只是叫法不同.java是面向对象的语言,所以用方法. 2.方法的定义: 就是有名字的代码段 3.方法的目的 ...

  2. 转:StrictMode使用

    最新的Android平台中(Android 2.3起),新增加了一个新的类,叫StrictMode(android.os.StrictMode).这个类可以用来帮助开发者改进他们编写的应用,并且提供了 ...

  3. music player界面

    public class SoundPlayerGUI extends JFrame implements ChangeListener, ActionListener { private stati ...

  4. 2016 、12 、11<本周>

    翻了翻记录 想把上周没搞出来的1159和day2T2搞出来.

  5. string.join(iterable)

    str.join(iterable) Return a string which is concatenation the  of the strings in the iterable iterab ...

  6. webpack 编译完成执行代码

    接收一个项目,由于目录结构的问题,每次编译完成后就需要去修改编译后的 HTML 文件中引用的其它文件的路径. 所以想在编译完成后使用 node 来操作文件修改路径. 然后在 webpack 官网找到了 ...

  7. 从返回值未报错得到的对于java finally理解

    不多说了,直接看图 这个代码来自<深入理解java虚拟机(第二版)>,我在eclipse中编辑的,但是没有报错,一般来说,没有返回值,eclipse都会有个提示或者报错啥的,但是这个没有, ...

  8. 获取贴图及IES文件

    最近看了一下以前写的关于收集贴图的函数...又完善了一下,老链接:http://www.cnblogs.com/3dxy/p/3988751.html fn saveusedmaps spath se ...

  9. Java中的构造代码块

    代码块 ----a静态代码块 ----b构造代码块 ----c普通代码块 执行顺序:(优先级从高到低.)静态代码块>mian方法>构造代码块>构造方法. a.静态代码块: 静态代码块 ...

  10. Win10下SQLServer2000的安装

    Win10的技术预览版已经发布近两个星期了,我也迫不及待地装上尝鲜,发现SQLServer2000在Win10上无法安装,在翻遍网上资料和经过无数次尝试后得到了一种安装方法,希望能够帮助遇到类似问题的 ...