定义:

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

结构:(书中图,侵删)

一个简洁易用的外观类
一个复杂的子系统
 

实例:

书中提到了理财的例子,找理财经理就不用自己研究各种股票债券什么了;致使我一度脑子里只想到了房屋中介,感觉跳不出这个框架了。
最后,终于让我想到了别的例子:有困难找警察。
我们只需要记住“110”这个电话号码就完事了,具体问题怎么处理就辛苦警察同志了。
接下来代码实现:
外观类:打110

package designpattern.facade;

public class HandleTrouble {
public void call110(String trouble) {
System.out.println(trouble);
// 模拟接警员处理来电
if (trouble.indexOf("抢劫") > 0 || trouble.indexOf("杀人") > 0) {
CriminalPolice criminalPolice = new CriminalPolice();
criminalPolice.handleIt();
} else if (trouble.indexOf("追尾") > 0 || trouble.indexOf("撞车") > 0) {
TrafficPolice trafficPolice = new TrafficPolice();
trafficPolice.handleIt();
} else if (trouble.indexOf("起火") > 0 || trouble.indexOf("烧起来") > 0) {
System.out.println("转接火警...");
FirePolice firePolice = new FirePolice();
firePolice.handleIt();
} else {
PeoplePolice peoplePolice = new PeoplePolice();
peoplePolice.handleIt();
}
}
}
复杂的警察子系统:各个部门
package designpattern.facade;

public class CriminalPolice {
public void handleIt() {
System.out.println("刑警出动...");
}
}
package designpattern.facade;

public class TrafficPolice {
public void handleIt() {
System.out.println("交警出动...");
}
}
package designpattern.facade;

public class FirePolice {
public void handleIt() {
System.out.println("火警出动...");
}
}
package designpattern.facade;

public class PeoplePolice {
public void handleIt() {
System.out.println("民警出动...");
}
}
客户端:
package designpattern.facade;

public class Client {
public static void main(String[] args) {
HandleTrouble handleTrouble = new HandleTrouble();
handleTrouble.call110("救命啊,杀人啦,快来人啊~~~~~");
System.out.println("-------------------");
handleTrouble.call110("XX大楼起火了");
System.out.println("-------------------");
handleTrouble.call110("有人打架了,快来人");
System.out.println("-------------------");
}
}

输出结果:

救命啊,杀人啦,快来人啊~~~~~
刑警出动...
-------------------
XX大楼起火了
转接火警...
火警出动...
-------------------
有人打架了,快来人
民警出动...
-------------------

总结:

上面的例子有一点策略模式的影子,不过两个设计模式的侧重点不一样。
策略模式侧重的是将具体算法和客户端分离,使得易于扩展且算法之前可以互相替换。
外观模式侧重的是减少各个模块之间的耦合,使代码满足迪米特法则/最少知识法则,使不需要互相通信的双方都不必"认识"对方,不需要知道对方的任何细节,甚至可以不知道对方的存在,只需要通过中间方——即这里所指的外观类/门面类通信即可,
这个模式感觉也很常见。像我们去调用腾讯阿里的接口的时候都是不知道他们内部是怎么具体处理的。
书中也说到何时使用外观模式,下面整理一下:
首先,在设计初期阶段,应该要有意识的将不同的两层分离。(比如我们熟悉的MVC,业务逻辑层就是另外双方的Facade)
其次,在开发阶段,子系统往往因为不断的重构演化而变得越来越复杂,大多数的模式使用时也都会产生很多很小的类,这本是好事,但是给外部调用他们的用户程序带来了使用上的困难,增加外观Facade可以提供一个简单的接口,减少他们之间的依赖。
第三,在维护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展了,但因为它包含非常重要的功能,新的需求开发必须要依赖于它。此时可以在新系统和老系统之间建立一个外观Facade类。
 

设计模式 | 外观模式/门面模式(facade)的更多相关文章

  1. 外观模式 门面模式 Facade 结构型 设计模式(十三)

    外观模式(FACADE) 又称为门面模式   意图 为子系统中的一组接口提供一个一致的界面 Facade模式定义了一个高层接口,这一接口使得这一子系统更加易于使用. 意图解析 随着项目的持续发展,系统 ...

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

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

  3. 大熊君说说JS与设计模式之(门面模式Facade)迪米特法则的救赎篇------(监狱的故事)

    一,总体概要 1,笔者浅谈 说起“门面”这个设计模式其实不论新老程序猿都是在无意中就已经运用到此模式了,就像我们美丽的JS程序员一样不经意就使用了闭包处理问题, function Employee(n ...

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

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

  5. 【读书笔记】读《JavaScript设计模式》之门面模式

    一.前言 门面模式,也称Facade(外观)模式.核心的两点作用—— 1> 简化类的接口(让接口变得更加容易理解.容易应用.更加符合对应业务),来掩盖一个非常不同或者复杂的实现 2> 消除 ...

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

    外观模式主要应用场景在于为复杂的子系统提供一个简单的接口,提高子系统的独立性. 创建DrawerOne类: package facade; public class DrawerOne { publi ...

  7. 设计模式之——外观or门面模式

    1.概念 定义一个高层的统一的外观接口类,该接口用于客户端调用,和一个实现类用来包装子系统中多个类,客户端可以通过客户端完成对子系统的方法调用. 2.适用场景 2.1 代码移植,降低了现有系统的复杂度 ...

  8. Facade 门面模式 外观模式

    简介 作用: (1)封装一组交互类,一致地对外提供接口 (2)封装子系统,简化子系统调用 JDK中体现:java.util.logging包 java.lang.Class javax.faces.w ...

  9. NET设计模式 第二部分 结构性模式(11):外观模式(Façade Pattern)

    外观模式(Façade Pattern) ——.NET设计模式系列之十二 Terrylee,2006年3月 概述 在软件开发系统中,客户程序经常会与复杂系统的内部子系统之间产生耦合,而导致客户程序随着 ...

随机推荐

  1. MicroService 微服务架构模式简述

    开源地址: https://github.com/TheCodeCleaner/MicroService4Net 本文内容 微服务 微服务风格的特性 组件化(Componentization )与服务 ...

  2. DX11 Without DirectX SDK--03 渲染一个立方体

    回到 DirectX11--使用Windows SDK来进行开发 一个立方体有8个顶点,然而绘制一个立方体需要画12个三角形,如果按照前面的方法绘制的话,则需要提供36个顶点,而且这里面的顶点数据会重 ...

  3. Linux设置开放一个端口

    修改防火墙配置需要修改 /etc/sysconfig/iptables 这个文件,如果要开放哪个端口,在里面添加一条. -A RH-Firewall-1-INPUT -m state --state ...

  4. Zookeeper vs etcd vs Consul

    Zookeeper vs etcd vs Consul [编者的话]本文对比了Zookeeper.etcd和Consul三种服务发现工具,探讨了最佳的服务发现解决方案,仅供参考. 如果使用预定义的端口 ...

  5. 20个大大节省你时间的HTML5开发工具

    Rendera 如果你希望有个环境可以测试.浏览和体验各种不同的 CSS/HTML 和 JavaScript 代码,Rendera 为你提供了实时的运行结果.类似 RunJS. Patternizer ...

  6. forwardPort.go

    packagemain import(     "encoding/json"     "flag"     "fmt"     " ...

  7. ASP.NET Core Identity Hands On(2)——注册、登录、Claim

    上一篇文章(ASP.NET Core Identity Hands On(1)--Identity 初次体验)中,我们初识了Identity,并且详细分析了AspNetUsers用户存储表,这篇我们将 ...

  8. MFC中ComboBox控件用法

    MFC ComboBox 一.入门篇 ComboBox (组合框)控件很简单,可以节省空间.从用户角度来看,这个控件是由一个文本输入控件和一个下拉菜单组成的.用户可以从一个预先定义的列表里选择一个选项 ...

  9. 【线段树】Bzoj1230 [Usaco2008 Nov]lites 开关灯

    Description Farmer John尝试通过和奶牛们玩益智玩具来保持他的奶牛们思维敏捷. 其中一个大型玩具是牛栏中的灯. N (2 <= N <= 100,000) 头奶牛中的每 ...

  10. vue iview UPload,但文件上传是,clearFiles的使用方法

    <template> <div> <button @click="clearUploadedImage">重新上传</button> ...