Facade模式

一 意图

  为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

二 动机

  将一个系统划分成为若干个子系统有利于降低系统的复杂性。一个常见的设计目标是使子系统间的通信和相互依赖关系达到最小。

达到该目标的途径之一是就是引入一个外观(Facade)对象,它为子系统中较一般的设施提供了一个单一而简单的界面。

将各个子系统整合起来作为Facade,提供给客户端使用。

  看下面这样一个系统:

  

    

  转变成:

  

    

三 适用性及其结构

  1. 当你要为一个复杂子系统提供一个简单接口时。
  2. 客户程序与抽象类的实现部分之间存在着很大的依赖性。
  3. 当你需要构建一个层次结构的子系统时,使用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 模式

 

Facade模式——设计模式学习(转载)的更多相关文章

  1. C#命令模式-设计模式学习

    命令模式(Command Pattern) 概述   在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”.但在某些场合,比如要对行为进行“记录.撤销/重做.事务”等处理,这种无法抵御变 ...

  2. (转载)设计模式学习笔记(十一)——Facade外观模式

    (转载)http://www.cnblogs.com/kid-li/archive/2006/07/10/446904.html Facade外观模式,是一种结构型模式,它主要解决的问题是:组件的客户 ...

  3. 设计模式学习之路——Facade 外观模式(结构型模式)

    动机: 组件的客户和组件中各种复杂的子系统有了过多的耦合,随着外部客户程序和各子系统的演化,这种过多的耦合面临很多变化的挑战.如何简化外部客户程序和系统间的交互接口?如何将外部客户程序的演化和内部子系 ...

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

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

  5. 设计模式学习之外观模式(Facade,结构型模式)(8)

    1.什么是外观模式为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用 2.为什么要使用外观模式在软件开发系统中,客户程序经常会与复杂系统的内 ...

  6. Java设计模式学习记录-外观模式

    前言 这次要介绍的是外观模式(也称为门面模式),外观模式也属于结构型模式,其实外观模式还是非常好理解的,简单的来讲就是将多个复杂的业务封装成一个方法,在调用此方法时可以不必关系具体执行了哪些业务,而只 ...

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

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

  8. 设计模式学习系列6 原型模式(prototype)

    原型模式(prototype)用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.允许一个对象再创建另外一个新对象的时候根本无需知道任何创建细节,只需要请求圆形对象的copy函数皆可. 1 ...

  9. php设计模式之Proxy(代理模式)和Facade(外观)设计模式

    Proxy(代理模式)和Facade(外观)设计模式它们均为更复杂的功能提供抽象化的概念,但这两种实现抽象化的过程大不相同 Proxy案例中,所有的方法和成员变量都来自于目标对象,必要时,该代理能够对 ...

随机推荐

  1. Linux之例行(任务调度)

    一. 例行命令之at 1.1 at 仅执行一次就从Linux任务中取消  1.2 at 指令可以将工作命令写入工作记录文件,工作记录文件默认存放在/var/spool/at目录内  1.3 at 工作 ...

  2. servlet与jsp的区别(转)

    一.基本概念 1.1 Servlet Servlet是一种服务器端的Java应用程序,具有独立于平台和协议的特性,可以生成动态的Web页面.它担当客户请求(Web浏览器或其他HTTP客户程序)与服务器 ...

  3. Lvs工作原理

    DR模式的工作过程: 当一个client发送一个WEB请求到VIP,LVS服务器根据VIP选择对应的real-server的Pool,根据算法,在Pool中选择一台Real-server,LVS在ha ...

  4. Itext中 根据html生成Word文件,包含图片

    package cn.com.wzf; import java.io.FileOutputStream; import java.io.OutputStream; import java.io.Str ...

  5. Visual Studio Code 使用Chrome Debug 代码

    一.添加插件 Debugger for Chrome,点击安装,安装完成之后,启动 二.配置启动参数 1.按 F5,出现界面如图,选择 Chrome 2.然后会打开配置文件 launch.json 3 ...

  6. Flash加载ini文件!

    这个帖子里有解决方案: http://bbs.9ria.com/thread-405128-1-1.html

  7. webService请求方式快速生成代码 (Postman)

    Postman 这个东西只能在外网下载,是Goole一个插件. 1.FQ到外网,这里就不具体介绍怎么FQ了 2.上到谷歌浏览器,找到更过工具--->扩张程序--->获取更多扩张程序 3.在 ...

  8. display与visibility的使用(区别)

    display:none;隐藏元素,且此元素无物理位置: visibility:hidden;隐藏元素,但元素的物理位置依然存在: 因为display:none导致页面上无此元素的空间,js就获取不到 ...

  9. Git与Github的使用学习

    摘要 本文讲解下Git的使用,包括使用Git上传项目工程到Github,文末有彩蛋哦. 1.安装Git 使用apt-get安 sudo apt-get update sudo apt-get inst ...

  10. windows系统System32中各种实用的工具

    工具类 这些工具可以直接打开运行  输入名字就可以调出来了 我还会上传一个java程序,运行后会显示一个界面,直接调用这些工具 1.SnippingTool.exe   截图 2.calc.exe   ...