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

意图

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

意图解析

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

代码示例

“关好门窗,防火防盗”这句话有没有听过?
回想一下,当你早上准备出门离开家时,你会做什么?
假设你会关水、关灯、关门窗。
我们创建三个类,水 灯 窗,模拟离开家的场景  
  1. package facade;
  2. public class Water {
  3. public void turnOn() {
  4. System.out.println("打开水龙头...");
  5. }
  6. public void turnOff() {
  7. System.out.println("关闭水龙头...");
  8. }
  9. }
  1. package facade;
  2. public class Light {
  3. public void turnOn() {
  4. System.out.println("开灯...");
  5. }
  6. public void turnOff() {
  7. System.out.println("关灯...");
  8. }
  9. }
  1. package facade;
  2.  
  3. public class Window {
  4. public void open() {
  5. System.out.println("开窗...");
  6. }
  7. public void close() {
  8. System.out.println("关窗...");
  9. }
  10. }
测试代码
 
上面的测试代码Test作为客户端程序,可以看得出来,他直接跟Water Light Window三个类的对象进行交互
他需要调用相关的方法
也就是说Test 作为客户端对于“离家”这一系统的内部逻辑是了如指掌的--->需要断水、关灯、关窗
他也清楚每个类的方法
一方面增加了耦合性,另一方面将子系统的内部细节暴露出来

优化重构

试想下,如果你家是智能家居,有一个控制台Facade,或者说有一个手机App
他可以控制整个家庭的设备
  1. package facade;
  2.  
  3. public class Facade {
  4. private Water water = new Water();
  5. private Light light = new Light();
  6. private Window window = new Window();
  7.  
  8. public void leaveHome(){
  9. water.turnOff();
  10. light.turnOff();
  11. window.close();
  12. }
  13.  
  14. public void backHome(){
  15. light.turnOn();
  16. window.open();
  17. }
  18.  
  19. }
 
通过这个控制台,客户端程序不再需要了解子系统的内部细节,他也不清楚每个类到底有哪些方法
所有的交互都是通过Facade来完成的

结构

Facade 外观角色
客户端调用角色,知晓子系统的所有功能与职责
通常,Facade会将所有的请求转发委派到子系统中去,也就是说该角色没有实际的业务、
 
SubSystem子系统角色
可以同时有一个或者多个子系统
注意   :子系统并不是说一个单独的类,而是一个类的集合,这些类根据逻辑功能点被组织在一起  
子系统并不知道Facade的存在,对于子系统来说,Facade也就只是一个客户端程序
 
外观模式的结构比较简单,类似一个“封装”提取的过程
他的根本原则为迪米特法则,也就是“不要和陌生人说话”,尽可能少的与其他的对象进行交互
通过外观模式,做到了子系统只与外观对象交互
 
门面类个数
在门面模式中,通常只需要一个门面类,并且这个门面类只有一个实例
换句话说他很可能是一个单例
但是并不是说整个系统中只能有一个门面类
门面类的个数要根据系统中子系统的个数以及业务逻辑的情况

总结

当你需要为一个复杂的子系统提供一个简单的接口时或者希望子系统能够更加独立时,可以考虑使用外观模式
借助于外观模式,可以实现客户端与子系统的解耦,减少客户端对子系统的依赖性
一旦完成解耦,就意味着子系统有良好的独立性,也能拥有更好的扩展性
因为独立了,就意味着单独的子系统修改不会影响其他系统
而且,在多层次结构的系统中,可以使用Facade模式进行层与层之间的交互,将层与层之间的耦合性降低,使他们仅仅通过facade进行交互
总之一句话,降低了使用子系统的复杂程度,降低了耦合程度,满足迪米特法则----不要和陌生人说话 
对客户端屏蔽了子系统的组件
仅仅通过Facade,大大减少了客户端所需要处理的对象的数目
对于外观模式,如果是子系统发生变化,Facade则极有可能需要面临修改,这不符合开闭原则 
外观模式(门面模式)就如同我们开篇的图片一样,作为公司前台
接待来访宾客,一切事宜都有她来协调安排组织。
在OOP中,这个“前台”不仅是一个子系统的“正面”看到的样子,而且还强调了她的全权负责
她提供所有的业务需要的相关方法,尽管内部调用都是子系统中的方法,她提供简单一致的交流沟通形式 
理解了迪米特法则,那么就比较容易理解外观模式
外观模式重点在于提供一个“简化”“封装”后的操作控制台,让你更容易操作整个系统,他几乎不会涉及子系统的内部逻辑
否则,门面对象将与子系统的业务逻辑耦合,增加了耦合度。
 

外观模式 门面模式 Facade 结构型 设计模式(十三)的更多相关文章

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

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

  2. 设计模式在实际业务应用中的介绍之3——外观或门面模式Facade对AOP装配业务工厂的应用

    在C#中实现的基于外观或门面模式打造的业务应用案例 以前一直没有想过写一些东西来把项目中用到的知识点及技术实现做一个归纳整理并分享出来.现在打算逐渐的把项目中的一些东西整理并分享出来,与大家共勉! 外 ...

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

    享元模式(FlyWeight)  “享”取“共享”之意,“元”取“单元”之意. 意图 运用共享技术,有效的支持大量细粒度的对象. 意图解析 面向对象的程序设计中,一切皆是对象,这也就意味着系统的运行将 ...

  4. 代理模式 PROXY Surrogate 结构型 设计模式(十四)

    代理模式 PROXY 别名Surrogate 意图 为其他的对象提供一种代理以控制对这个对象的访问. 代理模式含义比较清晰,就是中间人,中介公司,经纪人... 在计算机程序中,代理就表示一个客户端不想 ...

  5. 桥接模式 桥梁模式 bridge 结构型 设计模式(十二)

      桥接模式Bridge   Bridge 意为桥梁,桥接模式的作用就像桥梁一样,用于把两件事物连接起来   意图 将抽象部分与他的实现部分进行分离,使得他们都可以独立的发展.  意图解析 依赖倒置原 ...

  6. 组合模式 合成模式 COMPOSITE 结构型 设计模式(十一)

    组合模式(合成模式 COMPOSITE) 意图 将对象组合成树形结构以表示“部分-整体”的层次结构. Composite使得用户对单个对象和组合对象的使用具有一致性.   树形结构介绍 为了便于理解, ...

  7. 设计模式 | 外观模式/门面模式(facade)

    定义: 为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 结构:(书中图,侵删) 一个简洁易用的外观类 一个复杂的子系统   实例: 书中提到了理 ...

  8. 享元模式/Flyweight模式/对象结构型/设计模式

    flyweight 享元模式(对象结构型) Flyweight在拳击比赛中指最轻量级,即"蝇量级"或"雨量级",这里选择使用"享元模式"的意 ...

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

    一. 定义与类型 定义:门面模式,提供一个统一的接口,用来访问子系统中的一群接口,门面模式定义了一个高层接口,让子系统更容易使用 类型:结构性 二. 使用场景 子系统越来越复杂,增加外观模式提供简单调 ...

随机推荐

  1. eShopOnContainers 知多少[8]:Ordering microservice

    1. 引言 Ordering microservice(订单微服务)就是处理订单的了,它与前面讲到的几个微服务相比要复杂的多.主要涉及以下业务逻辑: 订单的创建.取消.支付.发货 库存的扣减 2. 架 ...

  2. 浏览器插件使用socks5代理

    服务端测试,经常会遇到需要通过代理访问的情景,比如公司内网不能访问测试环境,这时可以通过socks5代理来解决. 一.使用Chrome浏览器访问   1. 下载并安装SwitchyOmega插件   ...

  3. Electron学习笔记(一)

    Electron是使用Javascript.HTML5技术构建跨平台桌面应用的技术,是目前非常活跃的一项技术,其中比较有名气的应用有微软的VS Code. 创建一个Electron应用的方式有很多,G ...

  4. Python:游戏:300行代码实现俄罗斯方块

    本文代码基于 python3.6 和 pygame1.9.4. 俄罗斯方块是儿时最经典的游戏之一,刚开始接触 pygame 的时候就想写一个俄罗斯方块.但是想到旋转,停靠,消除等操作,感觉好像很难啊, ...

  5. SpringBoot | 第六章:常用注解介绍及简单使用

    前言 之前几个章节,大部分都是算介绍springboot的一些外围配置,比如日志配置等.这章节开始,开始总结一些关于springboot的综合开发的知识点.由于SpringBoot本身是基于Sprin ...

  6. 解决ruby安装后无法添加淘宝gem源------------学习记录

    使用sass ,需要安装ruby,会建议移除gem源,添加淘宝的gem源,但是淘宝的镜像源已经停止维护啦!!用https://gems.ruby-china.com 代替即可. 操作如下: 1)删除原 ...

  7. oppo5.0以上系统怎么样不Root激活Xposed框架的经验

    在非常多单位的引流或者业务操作中,基本上都需要使用安卓的黑高科技术Xposed框架,前几天我们单位购来了一批新的oppo5.0以上系统,基本上都都是基于7.0以上版本,基本上都不能够获取root超级权 ...

  8. 我的Windows日常——鼠标无法进行拖拽的解决方法

    方法1: 鼠标右键单击任务栏 选择属性,进入任务栏和开始菜单属性 点击「开始」菜单  进入分页,单击自定义 找到并勾选启用上下文菜单和拖放 一路确定.... --------------------- ...

  9. 排错:Windows系统异常导致Filebeat无法正常运行

    Windows 下Filebeat排错Case实例一份,请查收. 问题描述: Windows Server下Filebeat Agent服务无法正常启动,导致网络数据打点无法正常进行,影响大范围用户网 ...

  10. 开源的类似于Apache ab的压力测试命令行工具SuperBenchmarker

    SuperBenchmarker 是ㄧ个开源的类似于Apache ab的压力测试命令行工具.可以在 .NET 4.52+ 或者 .NET Core 2.0+ 平台上运行. 可支持Get.Post.Pu ...