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. 【转】PV3D的小练习~太阳系八大行星

    转自:http://hi.baidu.com/boycy/item/70d1ba53bc8c3a958c12eddf http://www.cnblogs.com/flash3d/archive/20 ...

  2. 手机自动化测试:appium源码分析之bootstrap五

    手机自动化测试:appium源码分析之bootstrap五   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.poptest测试 ...

  3. 老李分享:DBA

    poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:908821478,咨询电话010-845052 ...

  4. `define、parameter、localparam三者的区别

    `define: 可以跨模块的定义,写在模块名称上面,在整个设计工程都有效.一旦'define指令被编译,其在整个编译过程中都有效.例如,通过另一个文件中的`define指令,定义的常量可以被其他文件 ...

  5. 关于ARM内核与架构的解释

    本文摘自某论坛某位大神的一段回复,经典至极,copy来己用! 只要你玩过ARM内核的芯片,那么关于内核和架构,我想应该或多或少的困惑过你,看了下面的介绍,你应该会清楚很多! 好比你盖房子,刚开始因为水 ...

  6. 【G】开源的分布式部署解决方案文档 - 部署Console & 控制负载均衡 & 跳转持续集成控制台

    G.系列导航 [G]开源的分布式部署解决方案 - 导航 设置项目部署流程 项目类型:选择Console,这个跟功能无关,只是做项目分类,后面会有后续功能 宿主:选择Console 部署方式:选择原始, ...

  7. AOP杂谈

    1.什么是AOP? Spring 2大特性: IOC (Inverse of Control)和 AOP(Aspect Oriented Programming) PS: AOP:面向切面编程  设计 ...

  8. 什么是javascript中的静态方法?一个例子让你懂~!

    function Foo(){ this.age = 28};var a = new Foo();alert(a.age);//28alert(a.name);//undifined Foo.name ...

  9. 【Spark2.0源码学习】-2.一切从脚本说起

    从脚本说起      在看源码之前,我们一般会看相关脚本了解其初始化信息以及Bootstrap类,Spark也不例外,而Spark我们启动三端使用的脚本如下: %SPARK_HOME%/sbin/st ...

  10. [.NET] 《C# 高效编程》(一) - C# 语言习惯

    C# 语言习惯 目录 一.使用属性而不是可访问的数据成员 二.使用运行时常量(readonly)而不是编译时常量(const) 三.推荐使用 is 或 as 操作符而不是强制类型转换 四.使用 Con ...