外观模式(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 结构型 设计模式(十三)的更多相关文章

  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. 重磅!!!微软发布.NET Core 2.2

    我们很高兴地宣布发布.NET Core 2.2.它包括对运行时的诊断改进,对ARM32 for Windows和Azure Active Directory for SQL Client的支持.此版本 ...

  2. Eclipse 出现项目没有错但是项目名称却有红色感叹号或者红叉的解决办法

    错误的起因是本人因为一不小心点了下面圈出来的某一个按钮,具体记不清楚了(好像是"remove from build path"),然后整个项目变得很奇怪了,所有的包都变成了一个普通 ...

  3. Java核心技术梳理-集合

    一.前言 在日常开发中,我们经常会碰到需要在运行时才知道对象个数的情况,这种情况不能使用数组,因为数组是固定数量的,这个时候我们就会使用集合,因为集合可以存储数量不确定的对象. 集合类是特别有用的工具 ...

  4. Shell学习心得(一):变量

     1.begin #!/bin/bash echo "Hello World !" #! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell. ec ...

  5. 从零单排学Redis【白银】

    前言 只有光头才能变强 今天继续来学习Redis,上一篇从零单排学Redis[青铜]已经将Redis常用的数据结构过了一遍了.如果还没看的同学可以先去看一遍再回来~ 这篇主要讲的内容有: Redis服 ...

  6. Data Lake Analytics的Geospatial分析函数

    0. 简介 为满足部分客户在云上做Geometry数据的分析需求,阿里云Data Lake Analytics(以下简称:DLA)支持多种格式的地理空间数据处理函数,符合Open Geospatial ...

  7. C#中关于表达式与委托在EF中的不同表现总结

    Func<Invoice, bool> func = x => x.State == InvoiceState.Created; Expression<Func<Invo ...

  8. [转]微信小程序实现图片上传功能

    本文转自:http://blog.csdn.net/feter1992/article/details/77877659 前端: 微信开发者工具 后端:.Net 服务器:阿里云 这里介绍微信小程序如何 ...

  9. MySQL教程之concat以及group_concat的用法

    本文中使用的例子均在下面的数据库表tt2下执行: 一.concat()函数 1.功能:将多个字符串连接成一个字符串. 2.语法:concat(str1, str2,...) 返回结果为连接参数产生的字 ...

  10. dropload.js(上拉加载插件使用过程中遇到的坑)

    dropload.js相关介绍和使用以及demo下载详见:https://github.com/ximan/dropload (原文出处) 之前因为项目需要一个上拉加载的效果,然后无意中看到了此插件, ...