定义:

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

结构:(书中图,侵删)

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

实例:

书中提到了理财的例子,找理财经理就不用自己研究各种股票债券什么了;致使我一度脑子里只想到了房屋中介,感觉跳不出这个框架了。
最后,终于让我想到了别的例子:有困难找警察。
我们只需要记住“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. va_start,va_arg,va_end的使用

    一.在C中,当我们无法列出传递函数的所有实参的类型和数目时,可以用省略号指定参数表. void fun(...); void fun(parm_list,...); #include <stdi ...

  2. pandas用法小结

    前言 个人感觉网上对pandas的总结感觉不够详尽细致,在这里我对pandas做个相对细致的小结吧,在数据分析与人工智能方面会有所涉及到的东西在这里都说说吧,也是对自己学习的一种小结! pandas用 ...

  3. Flask信号和wtforms

    一.信号 1.1.所有内置信号 request_started = _signals.signal('request-started') # 请求到来前执行 request_finished = _s ...

  4. 再探Circuit Breaker之使用Polly

    前言 上一篇介绍了使用Steeltoe来处理服务熔断,这篇我们将用Polly来处理服务熔断. 不废话了,直接进正题. 简单的例子 同样先定义一个简单的服务. [Route("api/[con ...

  5. 微信授权、获取用户openid-纯前端实现——jsonp跨域访问返回json数据会报错的纯前端解决办法

    近来,倒霉的后台跟我说让我拿个openid做微信支付使用,寻思很简单,开始干活. 首先引导用户打开如下链接,只需要将appid修改为自己的就可以,redirect_url写你的重定向url https ...

  6. java客户端调用webService

    啥也不想说,以前使用的方法突然不行了.各种网搜(记得别忘记到jar包哦:axis.jar) 看代码,第一种方式,也就是以前的方式: 改方式不用表名参数名称 public static String i ...

  7. Netty_TCP拆包粘包解决方案

    一.问题 熟悉tcp编程的可能都知道,无论是服务器端还是客户端,当我们读取或者发送数据的时候,都需要考虑TCP底层的粘包/拆包机制. TCP是一个“流”协议,所谓流就是没有界限的遗传数据,大家可以想象 ...

  8. Vlan 原理

    VLAN(Virtual LAN),翻译成中文是"虚拟局域网".LAN可以是由少数几台家用计算机构成的网络,也可以是数以百计的计算机构成的企业网络.VLAN所指的LAN特指使用路由 ...

  9. SSM-SpringMVC-03:SpringMVC执行流程一张有意思的图

     ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 上次的图也不全,这次的图也不是完整版,但是多了一个拦截器,我觉得挺有意思的,我就放上来了 他Handler ...

  10. Go笔记之二:一个完整的播放器示例

    Go笔记之二:一个完整的播放器示例 该示例从命令行运行一个播放器示例,可进行添加.删除.浏览和模拟播放,其内容是对 Go 语言接口使用的良好展示 源码及可执行文件 参考书籍<Go语言编程> ...