《图解设计模式》读书笔记7-1 facade模式
1. Facade模式简介
开发程序的过程中,随着时间的推移,类会越来越多,调用关系会越来越复杂,还会涉及到调用顺序的问题。此时我们就需要一个“窗口”,把错综复杂的关联关系和调用顺序都写好,整理起来供使用者使用。这个模式最关键的思想就是:降低难度。并由此来提高开发效率,提升程序的可靠性和可维护性。
2. 示例程序
下面一段程序介绍如何生成一个网页:先从数据库里面读取用户信息,再按顺序生成网页的head、body、欢迎词等等。虽然不够“错综复杂”,但也牵涉两个类,有调用顺序。我们要利用这个模式,创建一个窗口,一行代码完成所有调用。
2.1 类图

2.2 程序
如类图所示,Database类负责从数据库(本例中是一个txt文本)里面读取用户信息,HtmlWriter则包含了一个个API,需要按顺序调用它们来生成网页。PageMaker就是窗口,它将最复杂的调用关系和顺序包装好给使用者Main,最终Main只需要一行代码即可完成工作。
public class Database {
private Database() { // 防止外部new出Database的实例,所以声明为private方法
}
public static Properties getProperties(String dbname) { // 根据数据库名获取Properties
String filename = dbname + ".txt";
Properties prop = new Properties();
try {
prop.load(new FileInputStream(filename));
} catch (IOException e) {
System.out.println("Warning: " + filename + " is not found.");
}
return prop;
}
}
public class HtmlWriter {
private Writer writer;
public HtmlWriter(Writer writer) { // 构造函数
this.writer = writer;
}
public void title(String title) throws IOException { // 输出标题
writer.write("<html>");
writer.write("<head>");
writer.write("<title>" + title + "</title>");
writer.write("</head>");
writer.write("<body>\n");
writer.write("<h1>" + title + "</h1>\n");
}
public void paragraph(String msg) throws IOException { // 输出段落
writer.write("<p>" + msg + "</p>\n");
}
public void link(String href, String caption) throws IOException { // 输出超链接
paragraph("<a href=\"" + href + "\">" + caption + "</a>");
}
public void mailto(String mailaddr, String username) throws IOException { // 输出邮件地址
link("mailto:" + mailaddr, username);
}
public void close() throws IOException { // 结束输出HTML
writer.write("</body>");
writer.write("</html>\n");
writer.close();
}
}
public class PageMaker {
private PageMaker() {
}
public static void makeWelcomePage(String mailaddr, String filename) {
try {
//先从数据库中提取出来邮箱信息
Properties mailprop = Database.getProperties("D:\\XXXXXX\\maildata");
String username = mailprop.getProperty(mailaddr);
//按照固定的步骤构造网页并生成文件
HtmlWriter writer = new HtmlWriter(new FileWriter(filename));
writer.title("Welcome to " + username + "'s page!");
writer.paragraph("欢迎来到" + username + "的主页。");
writer.paragraph("等着你的邮件哦!");
writer.mailto(mailaddr, username);
writer.close();
System.out.println(filename + " is created for " +
mailaddr + " (" + username + ")");
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class Main {
public static void main(String[] args) {
PageMaker.makeWelcomePage("XXX@XXX.com","test.html");
}
}
//“数据库”
XXX@XXX.com=username
3.角色和类图
- Facade(窗口):向下调用各种复杂的类和接口,向上提供简单的API。由PageMaker扮演此角色。
- 构成系统的其他角色:各自完成自己工作的角色,他们不知道窗口的存在,但窗口角色会调用他们。比如本例中的HtmlWriter和Database类。
- Client(请求者):负责调用Facade角色,本例中Main扮演此角色。

4.思路拓展
- Facade角色的好处
关键在于降低复杂度,如果一个程序员,既要关心业务逻辑,又要关心底层API的各种复杂的组合调用方式——由此带来的只会是开发效率低,出错概率高。有句名言,应该不是鲁迅说的:在计算机世界,没有加一个中间层解决不了的问题,如果有,那就递归的加。Facade就是中间层。中间层还有一个好处:降低耦合。
- 递归使用Facade模式
即上文所说,递归的加中间层。
《图解设计模式》读书笔记7-1 facade模式的更多相关文章
- HeadFirst设计模式读书笔记(3)-装饰者模式(Decorator Pattern)
装饰者模式:动态地将责任附件到对象上.若要扩展功能,装饰者提东了比继承更有弹性的替代方案. 装饰者和被装饰对象有相同的超类型 你可以用一个或者多个装饰者包装一个对象. 既然装饰者和被装饰对象有相同的超 ...
- HeadFirst设计模式读书笔记--目录
HeadFirst设计模式读书笔记(1)-策略模式(Strategy Pattern) HeadFirst设计模式读书笔记(2)-观察者模式(Observer Pattern) HeadFirst设计 ...
- Head First 设计模式读书笔记(1)-策略模式
一.策略模式的定义 策略模式定义了算法族,分别封装起来,让它们之间可以互换替换,此模式让算法的变化独立使用算法的客户. 二.使用策略模式的一个例子 2.1引出问题 某公司做了一套模拟鸭子的游戏:该游戏 ...
- JavaScript设计模式:读书笔记(未完)
该篇随我读书的进度持续更新阅读书目:<JavaScript设计模式> 2016/3/30 2016/3/31 2016/4/8 2016/3/30: 模式是一种可复用的解决方案,可用于解决 ...
- C#设计模式学习笔记:(10)外观模式
本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7772184.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲结构型设计模式的第五个模式--外 ...
- 图解http读书笔记
以前对HTTP协议一知半解,一直不清楚前端需要对于HTTP了解到什么程度,知道接触的东西多了,对于性能优化.服务端的配合和学习中也渐渐了解到了HTTP基础的重要性,看了一些大神对HTTP书籍的推荐,也 ...
- Java设计模式学习笔记(二) 简单工厂模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 正文开始... 1. 简介 简单工厂模式不属于GoF23中设计模式之一,但在软件开发中应用也较为 ...
- Java设计模式学习笔记(三) 工厂方法模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 简介 上一篇博客介绍了简单工厂模式,简单工厂模式存在一个很严重的问题: 就是当系统需要引入 ...
- Java设计模式学习笔记(四) 抽象工厂模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 抽象工厂模式概述 工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问 ...
- C#设计模式学习笔记:(23)解释器模式
本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/8242238.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第十一个模式-- ...
随机推荐
- Netty入门搭建
什么是Netty Netty 是一个基于 JAVA NIO 类库的异步通信框架,它的架构特点是:异步非阻塞.基于事件驱动.高性能.高可靠性和高可定制性. 为什么选择netty而不是使用NIO 1.使用 ...
- Vue中如何引入第三方icon库(阿里巴巴矢量图标库)
1.进入阿里巴巴矢量图标库: 2.新建项目 3.前缀注意不要跟element-ui自带的icon(el-icon)重名就ok 4.创建完成后,去阿里选自己要使用的图标,加入购物车 ...
- HTML第一课(前期知识准备)
在正式的学习之前,我们先了解一些前端方面的常识. 一.前端是做什么? 如果有认真看过我写的预备程序员不得不知道的事儿这篇文章的同学应该清楚,前端的工作在整个项目开发中处于代码编写阶段,主要是用来做界面 ...
- 第八讲 shiro 整合 ssm
1.整合ssm并且实现用户登录和菜单权限 2.将shiro整合到ssm中 (1)添加shiro相关jar包 (2)在web.xml中添加shiro配置 <!-- 新增shiro配置 --> ...
- Codeforces 954 dijsktra 离散化矩阵快速幂DP 前缀和二分check
A B C D 给你一个联通图 给定S,T 要求你加一条边使得ST的最短距离不会减少 问你有多少种方法 因为N<=1000 所以N^2枚举边数 迪杰斯特拉两次 求出Sdis 和 Tdis 如果d ...
- LeetCode--617--合并二叉树(python)
给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠. 你需要将他们合并为一个新的二叉树.合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 ...
- Spring AOP expose-proxy
写在前面 expose-proxy.为是否暴露当前代理对象为ThreadLocal模式. SpringAOP对于最外层的函数只拦截public方法,不拦截protected和private方法(后续讲 ...
- Android App学习计划
模块化 Json Gson Fastjson Jackson EventBus GreenDao Flutter ButterKnife Dagger okhttp Rxjava/Rxandroid ...
- 从1G到5G,移动通信发展之路
2G取代1G是历史的必然,诺基亚是2G时代的领航者. 3G是个“半吊子”系统,2G手机只能打电话.发短信,上网很困难.3G的通信标准将信息的传输率提高了一个数量级,这是一个飞跃,它使得移动互联网得以实 ...
- linux运维、架构之路-禅道环境搭建
一.介绍 禅道项目管理软件是国产的开源项目管理软件,专注研发项目管理,内置需求管理.任务管理.bug管理.缺陷管理.用例管理.计划发布等功能,实现了软件的完整生命周期管理. 禅道 ...