外观模式(FACADE)
又称为门面模式

意图

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

意图解析

随着项目的持续发展,系统基本上都是会往功能更全面的方向发展,那么也就意味着我们的系统将会变得更加复杂。
系统会被划分为多个单独的子系统,每个子系统完成一部分功能,通过分工协作完成全部功能。
一个子系统也可能进一步拆分为更小的几个子系统。
程序中的文件将会越来越多,相互关联也会变得更加复杂
当使用一个功能的时候,作为客户端
你需要弄清楚相关类之间的关系,以及正确的调用顺序。
比如下图中
你需要自己识别有哪些子系统,涉及哪些相关的类和方法,你需要自己保证顺序(如果功能调用依赖顺序的话)
如同在医院里面,病人需要自己去排队挂号化验,跟每个流程的工作人员进行协作
如同在工厂里面,需要生产一个桌子,你亲自用机器生产桌子腿,自己使用机器生产桌面...
如同你去其他公司洽谈业务,你单独跟每个相关业务的人员进行联系沟通
你肯定想得到,如果有一个中间人为你代劳
不需要面对林林总总的子系统、部门、人员...
当你需要某种服务时,只需要告诉这个中间人就好了
这个想法就是外观模式
有了facade,你就不需要跟每个子系统进行单独的交流了
如同在医院里面,对于VIP,有专人代替你挂号.....
如同在工厂里面,有一个控制台机器,你选择产品,控制台下发命令安排其他的机器生产具体产品
如同你去其他公司洽谈业务,有一个接口人负责与你对接,他们那边的事情都通过这个人进行安排
外观模式的意图含义,如同他的名字一样,“建筑物的正面”
面对一个复杂的大楼,当你在正面远远望去,也就只能看到正面
在外观模式中,形容一个庞大的复杂的系统的一个直观的界面
借助于Facade模式
从原来的“客户端需要跟多个子系统进行交互”,转变为“只与Facade进行交互”
将客户端与子系统进行解耦,降低了耦合性,也降低了使用的复杂度

代码示例

“关好门窗,防火防盗”这句话有没有听过?
回想一下,当你早上准备出门离开家时,你会做什么?
假设你会关水、关灯、关门窗。
我们创建三个类,水 灯 窗,模拟离开家的场景  

package facade;
public class Water {
public void turnOn() {System.out.println("打开水龙头...");}   public void turnOff() {System.out.println("关闭水龙头...");}
}

package facade;
public class Light {public void turnOn() {System.out.println("开灯...");} public void turnOff() {System.out.println("关灯...");}
}

package facade;public class Window {public void open() {System.out.println("开窗...");} public void close() {System.out.println("关窗...");}
}

测试代码

上面的测试代码Test作为客户端程序,可以看得出来,他直接跟Water Light Window三个类的对象进行交互
他需要调用相关的方法
也就是说Test 作为客户端对于“离家”这一系统的内部逻辑是了如指掌的--->需要断水、关灯、关窗
他也清楚每个类的方法
一方面增加了耦合性,另一方面将子系统的内部细节暴露出来

优化重构

试想下,如果你家是智能家居,有一个控制台Facade,或者说有一个手机App
他可以控制整个家庭的设备
package facade;public class Facade {private Water water = new Water();private Light light = new Light();private Window window = new Window();public void leaveHome(){water.turnOff();light.turnOff();window.close();}public void backHome(){light.turnOn();window.open();}}

通过这个控制台,客户端程序不再需要了解子系统的内部细节,他也不清楚每个类到底有哪些方法
所有的交互都是通过Facade来完成的

结构

Facade 外观角色
客户端调用角色,知晓子系统的所有功能与职责
通常,Facade会将所有的请求转发委派到子系统中去,也就是说该角色没有实际的业务、
SubSystem子系统角色
可以同时有一个或者多个子系统
注意   :子系统并不是说一个单独的类,而是一个类的集合,这些类根据逻辑功能点被组织在一起  
子系统并不知道Facade的存在,对于子系统来说,Facade也就只是一个客户端程序

外观模式的结构比较简单,类似一个“封装”提取的过程
他的根本原则为迪米特法则,也就是“不要和陌生人说话”,尽可能少的与其他的对象进行交互
通过外观模式,做到了子系统只与外观对象交互
门面类个数
在门面模式中,通常只需要一个门面类,并且这个门面类只有一个实例
换句话说他很可能是一个单例
但是并不是说整个系统中只能有一个门面类
门面类的个数要根据系统中子系统的个数以及业务逻辑的情况

总结

当你需要为一个复杂的子系统提供一个简单的接口时或者希望子系统能够更加独立时,可以考虑使用外观模式
借助于外观模式,可以实现客户端与子系统的解耦,减少客户端对子系统的依赖性
一旦完成解耦,就意味着子系统有良好的独立性,也能拥有更好的扩展性
因为独立了,就意味着单独的子系统修改不会影响其他系统
而且,在多层次结构的系统中,可以使用Facade模式进行层与层之间的交互,将层与层之间的耦合性降低,使他们仅仅通过facade进行交互
总之一句话,降低了使用子系统的复杂程度,降低了耦合程度,满足迪米特法则----不要和陌生人说话 
对客户端屏蔽了子系统的组件
仅仅通过Facade,大大减少了客户端所需要处理的对象的数目

对于外观模式,如果是子系统发生变化,Facade则极有可能需要面临修改,这不符合开闭原则 
外观模式(门面模式)就如同我们开篇的图片一样,作为公司前台
接待来访宾客,一切事宜都有她来协调安排组织。
在OOP中,这个“前台”不仅是一个子系统的“正面”看到的样子,而且还强调了她的全权负责
她提供所有的业务需要的相关方法,尽管内部调用都是子系统中的方法,她提供简单一致的交流沟通形式 
理解了迪米特法则,那么就比较容易理解外观模式
外观模式重点在于提供一个“简化”“封装”后的操作控制台,让你更容易操作整个系统,他几乎不会涉及子系统的内部逻辑
否则,门面对象将与子系统的业务逻辑耦合,增加了耦合度。
原文地址:外观模式 门面模式 Facade 创建型 设计模式(十三)

转载于:https://www.cnblogs.com/noteless/p/10058164.html

外观模式 门面模式 Facade 结构型 设计模式(十三)相关推荐

  1. OOAD-设计模式(四)结构型模式之适配器、装饰器、代理模式

    前言 前面我们学习了创建型设计模式,其中有5中,个人感觉比较重要的是工厂方法模式.单例模式.原型模式.接下来我将分享的是结构型模式! 一.适配器模式 1.1.适配器模式概述 适配器模式(Adapter ...

  2. JavaScript设计模式(三):结构型设计模式-外观模式、适配器模式、代理模式、装饰者模式、桥接模式、组合模式、享元模式

    JavaScript设计模式 - 结构型设计模式 套餐服务-外观模式 外观模式(Facade) 水管弯弯-适配器模式 适配器模式(Adapter) 适配异类框架 参数适配 牛郎织女-代理模式 代理模式 ...

  3. 享元模式 FlyWeight 结构型 设计模式(十五)

    享元模式(FlyWeight)  "享"取"共享"之意,"元"取"单元"之意. 意图 运用共享技术,有效的支持大量细粒度 ...

  4. 结构型设计模式之组合模式

    结构型设计模式之组合模式 组合模式 应用场景 优缺点 主要角色 组合模式结构 分类 透明组合模式 创建抽象根节点 创建树枝节点 创建叶子节点 客户端调用 安全组合模式 创建抽象根节点 创建树枝节点 创 ...

  5. 结构型设计模式(二) 之 装饰者模式可给对象一层层加工

    1 定义 装饰者模式(Decorator Pattern)又叫包装模式属于结构型设计模式之一,它主要用于动态地给一个对象增加一些额外扩展的功能,它是继承关系的一个替代方案,且在特定场景中比使用继承生成 ...

  6. 设计模式-外观模式(门面模式)

    外观模式(门面模式) 外观模式介绍 定义 通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式. 该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体细节,这样会大大 ...

  7. 结构型设计模式(五) 之 享元模式是池技术的表现

    1 定义 享元模式(Flyweight Pattern)属于结构型设计模式之一,它主要是使用共享对象有效地避免了创建过多的性质相近的对象,从而降低内存的占用,提高程序的性能.它也是池技术的重要实现方式 ...

  8. 技术图文:03 结构型设计模式(上)

    结构型设计模式(上) 本教程主要介绍一系列用于如何将现有类或对象组合在一起形成更加强大结构的经验总结. 知识结构: 享元模式 – 实现对象的复用 Sunny 软件公司欲开发一个围棋软件,其界面效果如下 ...

  9. 从框架源码中学习结构型设计模式

    文章目录 从框架源码学习结构型设计模式 适配器模式 应用实例 案例一:dubbo框架日志适配器 Logger接口 日志实现类 Logger适配器接口 LoggerAdapter实现类 Logger日志 ...

最新文章

  1. 后台开发经典书籍--linux性能优化
  2. 电大工商管理计算机考试,东方电大工商管理专科计算机期末复习EXCEL五题.docx...
  3. 【论文解读】GCN论文总结
  4. bzoj2753: [SCOI2012]滑雪与时间胶囊
  5. nginx ngx_http_mirror_module模块
  6. 【转】C#命名空间与java包的区别分析
  7. 华为这个事,是不是刷KPI?
  8. matlab的精度变量,MatLab - 变量精度算术
  9. 2012.4.10 全球IPv6暨下一代互联网高峰会议 日程表
  10. three轨迹线在mapbox地图上显示
  11. windows版本和Linux版本的ffmpeg下载使用方法
  12. php大文件去重,详细解说PHP多个进程配合redis的有序集合实现大文件去重
  13. 紫微斗数飞星派排盘批处理
  14. 计算机毕业设计android的学生考勤请假app(源码+系统+mysql数据库+Lw文档)
  15. Python技术项目实践
  16. mysql记录到毫秒,记录到微妙
  17. Windows操作系统+朝鲜红星+国产麒麟+红旗+渗透专用系统+Oracle专用+技术专栏【资源大合集】 | 寻找C站宝藏
  18. 18位身份证号码编码标准
  19. 储能逆变器,储能系统,soc均衡控制,soc均衡,蓄电池充放电控制
  20. 基于DOA联合TDOA时间积累的二维GDOP仿真分析

热门文章

  1. Android用第三方jar包ClassNotFoundException:XXX in loader dalvik.system.PathClassLoader[/app/XX.apk]...
  2. WSUS客户端无法发现
  3. centOS 7下安装与配置heartbeat高可用集群
  4. Android gradlew 多渠道打包
  5. Jquery根据JSON生成Table
  6. 10月25日学习内容整理:数据操作:增加更新删除,单表查询操作
  7. 未来数据中心核心技术:RDMA在京东的应用
  8. 性能调优的方法及概念
  9. android for vs (三)visual studio android 发布为 apk
  10. 解决Word 2007中更新整个目录后分节符消失问题