一、定义

外观模式提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。

外观模式不只是简化了接口,也将客户从组件的子系统中解耦。

外观和适配器可以包装许多类,但是外观强调的是简化接口,而适配器是为了将接口转换成不同的接口。

二、结构

外观角色(Facade):是模式的核心,他被客户client角色调用,知道各个子系统的功能。同时根据客户角色已有的需求预订了几种功能组合
子系统角色(Subsystem classes):实现子系统的功能,并处理由Facade对象指派的任务。对子系统而言,facade和client角色是未知的,没有Facade的任何相关信息;即没有指向Facade的实例。
客户角色(client):调用facade角色获得完成相应的功能。

三、实现

 class Program
{
static void Main(string[] args)
{
//----晚上下班回到家----
//开灯光
ILight light = new Light();
light.On();
//看电视
ITV tv = new TV();
tv.On();
//-----睡觉-----
//关灯光
light.Off();
//关电视
tv.Off(); Console.WriteLine("==== 最近有钱换智能家居了 ===="); ISmartHome smarthome = new SmartHome();
//----晚上下班回到家----
smarthome.On();
//-----睡觉-----
smarthome.Off();
}
} /// <summary>
/// 灯光接口
/// </summary>
public interface ILight
{
/// <summary>
/// 开灯
/// </summary>
void On();
/// <summary>
/// 关灯
/// </summary>
void Off();
} /// <summary>
/// 灯光接口实现类
/// </summary> public class Light : ILight
{
public void On()
{
Console.WriteLine("打开灯");
} public void Off()
{
Console.WriteLine("关闭灯");
}
} /// <summary>
/// 电视接口
/// </summary>
public interface ITV
{
/// <summary>
/// 开机
/// </summary>
void On();
/// <summary>
/// 关机
/// </summary>
void Off();
} /// <summary>
/// 智能家居总开关接口
/// </summary>
public interface ISmartHome
{
/// <summary>
/// 开灯
/// </summary>
void On();
/// <summary>
/// 关灯
/// </summary>
void Off();
}
public class TV : ITV
{
public void On()
{
Console.WriteLine("打开电视");
} public void Off()
{
Console.WriteLine("关闭电视");
}
} public class SmartHome : ISmartHome
{
private ILight light = new Light();
private ITV tv = new TV(); public void On()
{
light.On();
tv.On();
}
public void Off()
{
light.Off();
tv.Off();
}
}

四、适用场景

在以下情况下可以考虑使用外观模式:
(1)设计初期阶段,应该有意识的将不同层分离,层与层之间建立外观模式。
(2) 开发阶段,子系统越来越复杂,增加外观模式提供一个简单的调用接口。
(3) 维护一个大型遗留系统的时候,可能这个系统已经非常难以维护和扩展,但又包含非常重要的功能,为其开发一个外观类,以便新系统与其交互。

五、优缺点

优点:

1)对客户屏蔽子系统组件,减少了客户处理的对象数目并使得子系统使用起来更加容易。通过引入外观模式,客户代码将变得很简单,与之关联的对象也很少。
2)实现了子系统与客户之间的松耦合关系,这使得子系统的组件变化不会影响到调用它的客户类,只需要调整外观类即可。
3)降低了大型软件系统中的编译依赖性,并简化了系统在不同平台之间的移植过程,因为编译一个子系统一般不需要编译所有其他的子系统。一个子系统的修改对其他子系统没有任何影响,而且子系统内部变化也不会影响到外观对象。
4)只是提供了一个访问子系统的统一入口,并不影响用户直接使用子系统类。

缺点:

1) 不能很好地限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性。
2) 在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。

六、模式扩展

一个系统有多个外观类:

在外观模式中,通常只需要一个外观类,并且此外观类只有一个实例,换言之它是一个单例类。在很多情况下为了节约系统资源,一般将外观类设计为单例类。当然这并不意味着在整个系统里只能有一个外观类,在一个系统中可以设计多个外观类,每个外观类都负责和一些特定的子系统交互,向用户提供相应的业务功能。

不要试图通过外观类为子系统增加新行为:
       不要通过继承一个外观类在子系统中加入新的行为,这种做法是错误的。外观模式的用意是为子系统提供一个集中化和简化的沟通渠道,而不是向子系统加入新的行为,新的行为的增加应该通过修改原有子系统类或增加新的子系统类来实现,不能通过外观类来实现。
外观模式与迪米特法则:
       外观模式创造出一个外观对象,将客户端所涉及的属于一个子系统的协作伙伴的数量减到最少,使得客户端与子系统内部的对象的相互作用被外观对象所取代。外观类充当了客户类与子系统类之间的“第三者”,降低了客户类与子系统类之间的耦合度,外观模式就是实现代码重构以便达到“迪米特法则”要求的一个强有力的武器。

抽象外观类的引入:

外观模式最大的缺点在于违背了“开闭原则”,

当增加新的子系统或者移除子系统时需要修改外观类,可以通过引入抽象外观类在一定程度上解决该问题,客户端针对抽象外观类进行编程。对于新的业务需求,不修改原有外观类,而对应增加一个新的具体外观类,由新的具体外观类来关联新的子系统对象,同时通过修改配置文件来达到不修改源代码并更换外观类的目的。

UML:

参考:

http://blog.csdn.net/hguisu/article/details/7533759

http://www.cnblogs.com/JsonShare/p/7121383.html

欢迎阅读本系列文章:Head First设计模式之目录

Head First设计模式之外观模式的更多相关文章

  1. 每天一个设计模式-2 外观模式(Facade)

    每天一个设计模式-2  外观模式(Facade) 1.生活中的示例 客户想要购买一台电脑,一般有两种方法: 1.自己DIY,客户需要知道组成电脑的所有电子器件,并且需要熟悉那些配件,对客户要求较高. ...

  2. C#设计模式(11)——外观模式(Facade Pattern)

    一.引言 在软件开发过程中,客户端程序经常会与复杂系统的内部子系统进行耦合,从而导致客户端程序随着子系统的变化而变化,然而为了将复杂系统的内部子系统与客户端之间的依赖解耦,从而就有了外观模式,也称作 ...

  3. 乐在其中设计模式(C#) - 外观模式(Facade Pattern)

    原文:乐在其中设计模式(C#) - 外观模式(Facade Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 外观模式(Facade Pattern) 作者:webabcd 介绍 ...

  4. 设计模式之 外观模式详解(Service第三者插足,让action与dao分手)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 各位好,LZ今天给各位分享一 ...

  5. 8.4 GOF设计模式三: 外观模式 Facade

    GOF设计模式三: 外观模式 Facade  “现有系统”功能强大.复杂,开发“新系统”需要用到其中一部分,但又要增加一部 分新功能,该怎么办?4.1 Facade Pattern: Key Fea ...

  6. 北风设计模式课程---外观模式(Facade)总结

    北风设计模式课程---外观模式(Facade)总结 一.总结 一句话总结: 不仅要通过视频学,还要看别的博客里面的介绍,搜讲解,搜作用,搜实例 设计模式都是对生活的抽象,比如用户获得装备,我可以先装备 ...

  7. js设计模式——2.外观模式

    js设计模式——2.外观模式

  8. python设计模式之外观模式

    python设计模式之外观模式 系统会随着演化变得非常复杂,最终形成大量的(并且有时是令人迷惑的)类和交互,这种情况并不少见.许多情况下,我们并不想把这种复杂性暴露给客户端.外观设计模式有助于隐藏系统 ...

  9. java设计模式之外观模式(门面模式)

    针对外观模式,在项目开发和实际运用中十分频繁,但是其极易理解,下面就简要介绍一下. 一.概念介绍 外观模式(Facade),他隐藏了系统的复杂性,并向客户端提供了一个可以访问系统的接口.这种类型的设计 ...

  10. 【GOF23设计模式】外观模式

    来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_外观模式.公司注册流程.迪米特法则 package com.test.facade; public interface 工 ...

随机推荐

  1. 将DLL文件直接封装进exe执行文件中(C#)

    前言:由于项目需要,需制作一个注册机,将个人PC的MAC值和硬盘序列号与软件进行绑定,由于笔者的C++不是很好,所以采用C#进行开发.但在采用C#的时候,获取硬盘的MAC值和序列号的时候又不是很准确, ...

  2. Python爬虫学习之使用beautifulsoup爬取招聘网站信息

    菜鸟一只,也是在尝试并学习和摸索爬虫相关知识. 1.首先分析要爬取页面结构.可以看到一列搜索的结果,现在需要得到每一个链接,然后才能爬取对应页面. 关键代码思路如下: html = getHtml(& ...

  3. 打印杨辉三角 --JS

    var arr = new Array(); for(var i = 0 ;i < 6 ; i++){ if(i == 0){arr.push(1);} else if(i == 1){arr ...

  4. 中国十大B2C电商站点开发语言调查

    中国B2C电商站点市场占有率排名例如以下 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I ...

  5. File attachment or query results size exceeds allowable value of 1000000 bytes.

    今天早晨,收到了作业执行失败的邮件(前几天还能正常执行该作业.不知为何今天出错) 邮件显示,作业的第三个步骤报错. step3内容: msdb.dbo.sp_send_dbmail     @prof ...

  6. SYSAUX表空间使用率高问题处理

    SYSAUX表空间做为SYSTEM表空间的辅助表空间,主要存放EM相关的内容以及表统计信息,AWR快照,审计信息等,而假设SYSAUX表空间在默认条件下你假设不做不论什么配置,随着时间的推移.会膨胀的 ...

  7. 柯塔娜(Cortana):从科幻虚构到真实人生

    依照商业法理.7月29日.随着Win10公布的东风."小娜"与"小冰"两姊妹相会于中国北京. 在"小娜"眼中,"小冰"仅 ...

  8. 一 、Spring Boot 学习之项目搭建

    一.简介 spring 官方网站本身使用Spring 框架开发,随着功能以及业务逻辑的日益复杂,应用伴随着大量的XML配置文件以及复杂的Bean依赖关系. 随着Spring 3.0的发布,Spring ...

  9. nginx配置(windows配置)

    以下是我的项目用到的一份配置文件#user  nobody;worker_processes  4; #进程数,一般cpu是几核就写多少#error_log  logs/error.log;#erro ...

  10. 【转载】Spring AOP详解 、 JDK动态代理、CGLib动态代理

    Spring AOP详解 . JDK动态代理.CGLib动态代理  原文地址:https://www.cnblogs.com/kukudelaomao/p/5897893.html AOP是Aspec ...