定义:

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

结构:(书中图,侵删)

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

实例:

书中提到了理财的例子,找理财经理就不用自己研究各种股票债券什么了;致使我一度脑子里只想到了房屋中介,感觉跳不出这个框架了。
最后,终于让我想到了别的例子:有困难找警察。
我们只需要记住“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. Setting up Latex-vim (or Latex-suite) plugin within macVim under Mac OSX Yosemite 2015-1-20 by congliu

    1. Overview: Vim是命令行下的文本编辑程序,gVim是Vim的Linux下的图形化版本,macVim是Mac下的图形化版本 Latex-vim是vim写Latex文件时的插件 Skim是 ...

  2. DX11 Without DirectX SDK--使用Windows SDK来进行开发

    在看龙书(Introduction to 3D Game Programming with Directx 11)的时候,里面所使用的开发工具包为Microsoft DirectX SDK(June ...

  3. post 和 get 的区别,直指本质

    在我们初入java编程之路的时候,面试往往会有一个面试题:get和post的区别是什么?那么你真的知道他们的区别吗?接下来抽丝剥茧,让我们看看get和post到底什么东西,首先从本质的角度看get和p ...

  4. 不使用JavaScript实现菜单的打开和关闭

    我在写有菜单栏的网页时,基本都会用响应式设计来适配移动端,例如把不重要的菜单选项隐藏,或者创建一个菜单按钮来控制的菜单的打开和关闭之类的.而我之前一直是使用JavaScript来实现菜单的打开和关闭的 ...

  5. 【转】sentry 实时事件日志聚合平台

    1.install postgreSQL(v9.6)2.pip install sentry(v8.13.0)3.sentry init #初始化配置文件 4.配置好postgreSQL 需要连接re ...

  6. mybatis的sqlmapper详解

    http://blog.csdn.net/u012302681/article/details/46326877

  7. python之@property

    在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改: s = Student() s.score = 9999 这显然不合逻辑.为了限制score的 ...

  8. Quartz简单案例

    需求需要开发一个每天定时推送消息给微信用户,第一次接触quartz,简单案例 1. 先编辑要执行的任务 测试类代码 package com.wqq.test.quartz; import org.sp ...

  9. segmenter_worker.go

    package; ; i < engine.initOptions.NumShards; i++ {                 if i == shard {                ...

  10. 【gcd+stl】UVa1642 Magical GCD

    Description 一个长度为n的数列,选一个连续子序列,使得子序列的公约数*长度最大,求这个最大值.n<=1e5. Solution 连续子序列一般都要用滑动窗口是吧(固定r,快速计算最优 ...