定义:

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

结构:(书中图,侵删)

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

实例:

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

    VMware workstation的安装和使用教程 一.VMware 安装 1.从网上找到VMware的安装包以及要安装的映像文件,下载到本地,然后备份一份存储到百度云盘. 链接:http://pa ...

  2. 洛谷 P1430 解题报告

    P1430 序列取数 题目描述 给定一个长为\(n\)的整数序列\((n<=1000)\),由\(A\)和\(B\)轮流取数(\(A\)先取).每个人可从序列的左端或右端取若干个数(至少一个), ...

  3. 写XML

    //创XML建对象 XmlDocument doc = new XmlDocument(); //bool a = false; //声明根节点 XmlElement books; //判断文件是否存 ...

  4. JaveScript基础(1)之变量和数据类型

    1.JaveScript变量的定义方式: A:隐式定义:直接给变量赋值: temp='hello'; alert(temp); PS:使用变量前要先进行初始化工作,否则会报变量未被定义的错误; B:显 ...

  5. 基于Spring的RPC通讯模型.

    一.概念和原理 RPC(remote procedure call),远程过程调用,是客户端应用和服务端之间的会话.在客户端,它所需要的一些功能并不在该应用的实现范围之内,所以应用要向提供这些功能的其 ...

  6. mysql中如何处理字符

    concat函数 使用方法: CONCAT(str1,str2,…) 返回结果为连接参数产生的字符串.如有任何一个参数为NULL ,则返回值为 NULL. 注意: 如果所有参数均为非二进制字符串,则结 ...

  7. vi/vim操作

    vi/vim是unix/linux操作系统下的文本编辑器. 由于unix/linux万物届文件的特性,vi/vim可以编辑任何格式的文件. 下面是常见的知识点,仅供参考: 编辑方式:vi/vim + ...

  8. Linux时间子系统之三:时间的维护者:timekeeper

    专题文档汇总目录 Notes: 原文地址:Linux时间子系统之三:时间的维护者:timekeeper 本系列文章的前两节讨论了用于计时的时钟源:clocksource,以及内核内部时间的一些表示方法 ...

  9. 使用Maven+Nexus+Jenkins+Svn+Tomcat+Sonar搭建持续集成环境

    前言 但凡一个略有规模的项目都需要一个持续集成环境的支撑,为什么需要持续集成环境,我们来看一个例子.假如一个项目,由A.B两位程序员来协作开发,A负责前端模块,B负责后端模块,前端依赖后端.A和B都习 ...

  10. linux 安装 PHP fileinfo 扩展

    将windows解压Linux服务器 1.错误: PHP Fileinfo extension must be installed/enabled to use Intervention Image. ...