设计模式(十五)Facade模式
Facade模式可以为相互关联在一起的错综复杂的类整理出高层接口,可以让系统对外只有一个简单的接口,而且还会考虑到系统内部各个类之间的责任关系和依赖关系,按照正常的顺序调用各个类。
还是先看一下示例程序的类图。

接下来根据示例程序代码理解一下Facade模式。
package bigjunoba.bjtu.facade; import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties; public class Database { private Database(){ //防止外部new出Database的实例,所以声明为private
} public static Properties getProperties(String dbname) {
String filename = dbname + ".txt";
Properties properties = new Properties();
try {
properties.load(new FileInputStream(filename));
} catch (IOException e) {
System.out.println("找不到文件" + filename);
}
return properties;
} }
Database类就一个getProperties方法,使用这个方法可以通过传入的dbname来获取对应的Properties实例,properties字段保存的就是读取到的.txt文件。这里要注意的是getProperties是一个静态方法。
package bigjunoba.bjtu.facade; import java.io.Writer;
import java.io.IOException; 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();
}
}
HtmlWriter类用于编写简单的web页面。在构造HtmlWriter类的实例时赋予其Writer,然后使用该Writer输出HTML。
package bigjunoba.bjtu.facade; import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties; public class PageMaker {
private PageMaker() { // 防止外部new出PageMaker的实例,所以声明为private方法
}
public static void makeWelcomePage(String mailaddr, String filename) {
try {
Properties mailprop = Database.getProperties("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();
}
}
}
PageMaker类使用Database类和HtmlWriter类来生成指定用户的Web页面。makeWelcomePage方法会根据指定的邮件地址和文件名生成相应的Web页面。PageMaker类一手包办了调用HTMLWriter类的方法这一工作。对外部,它只提供了makeWelcomePage接口,这就是一个简单窗口。实现过程是,首先调用Database的getProperties方法读取.txt文件,然后生成一个Properties实例,将读取文件的结果保存在mailprop字段中,然后根据输入的邮箱地址通过getProperty方法获取对应的用户名。然后输出一系列Web页面的各个代码部分。
package bigjunoba.bjtu.facade;
public class Main {
public static void main(String[] args) {
PageMaker.makeWelcomePage("sjy534948129@sina.com", "welcome.html");
}
}
Main类输入文件中保存的邮箱地址和输出文件名来生成一个Web页面。
sjy534948129@sina.com=BigJunOba
17125031@bjtu.edu.cn=Lianjiang
maildate.txt保存了两条数据。
<html><head><title>Welcome to BigJunOba's page!</title></head><body>
<h1>Welcome to BigJunOba's page!</h1>
<p>欢迎来到BigJunOba的主页。</p>
<p>等着你的邮件哦!</p>
<p><a href="mailto:sjy534948129@sina.com">BigJunOba</a></p>
</body></html>
welcome.html输出文件。

Facade模式类图。
解释一下这些部分:
Facade:代表构成系统的许多其他部分的“简单窗口”。向外部提供高层接口。示例程序中的PageMaker就是这个。
其他类:这些类各自完成自己的工作,但是只能是Facade来调用这些其他类工作。示例程序中Database和HtmlWriter类就是这个情况。
Client:示例程序中的Main只能调用Facade的一个接口,这样就减少了接口的数量。
接口变少的优势:
程序中如果有很多类和方法,那么在决定到底应该使用哪个类或方法时就会很容易迷茫。类和方法的调用顺序也很容易弄错。然后接口变少可以解决这个问题。
同时,接口变少还意味着程序与外部的关联关系弱化了,这样更容易使我们的包作为组件被复用。
还要尤其注意的是,在设计类时,要将哪些方法的可见性设为public。如果公开的方法过多,那么类的内部的修改会变得困难。如果公开了某个字段,那么其他类可能会读取或是修改这个字段,导致难以修改该类。如果公开了包,那么让外部看到了类,包内的代码的修改就会变得困难。
设计模式(十五)Facade模式的更多相关文章
- 【转】设计模式 ( 十五 ) 中介者模式Mediator(对象行为型)
设计模式 ( 十五 ) 中介者模式Mediator(对象行为型) 1.概述 在面向对象的软件设计与开发过程中,根据"单一职责原则",我们应该尽量将对象细化,使其只负责或呈现单一的职 ...
- 设计模式 ( 十五 ) 中介者模式Mediator(对象行为型)
设计模式 ( 十五 ) 中介者模式Mediator(对象行为型) 1.概述 在面向对象的软件设计与开发过程中,根据“单一职责原则”,我们应该尽量将对象细化,使其只负责或呈现单一的职责,即将行为分布到各 ...
- 【转】设计模式 ( 十八 ) 策略模式Strategy(对象行为型)
设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成 ...
- 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)
设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也经常遇到类似的情况,实现某一个功能有多种算法或者策略,我们能够依据环境或者条件的不同选择不同的算法或者策略来完毕 ...
- 设计模式 ( 十九 ) 模板方法模式Template method(类行为型)
设计模式 ( 十九 ) 模板方法模式Template method(类行为型) 1.概述 在面向对象开发过程中,通常我们会遇到这样的一个问题:我们知道一个算法所需的关键步骤,并确定了这些步骤的执行 ...
- 设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型)
设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型) 1.概述 类中的面向对象编程封装应用逻辑.类,就是实例化的对象,每个单独的对象都有一个特定的身份和状态.单独的对象是一种组织代码的 ...
- C#设计模式之十五命令模式(Command Pattern)【行为型】
一.引言 今天我们开始讲"行为型"设计模式的第二个模式,该模式是[命令模式],又称为行动(Action)模式或交易(Transaction)模式,英文名称是:Command P ...
- C#设计模式之十五迭代器模式(Iterator Pattern)【行为型】
一.引言 今天我们开始讲“行为型”设计模式的第三个模式,该模式是[迭代器模式],英文名称是:Iterator Pattern.还是老套路,先从名字上来看看.“迭代器模式”我第一次看到这个名称,我的理解 ...
- Java设计模式菜鸟系列(十五)建造者模式建模与实现
转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/39863125 建造者模式(Builder):工厂类模式提供的是创建单个类的模式.而建造者模 ...
- Head First 设计模式 —— 08. 外观 (Facade) 模式
思考题 想想看,你在 JavaAPI 中遇到过哪些外观,你还希望 Java 能够新增哪些外观? P262 println.log 日志接口.JDBC 接口 突然让想感觉想不出来,各种 API 都用得挺 ...
随机推荐
- 略学扩展Eculid算法
扩展 Euclid 算法 Euclid 算法 辗转相除法 计算两个数最大公因数 \(\text{gcd}(a,\,b) = \text{gcd}(b,\,a\%b)\) exEuclid 算法 裴蜀定 ...
- 环境搭建-Hadoop集群搭建
环境搭建-Hadoop集群搭建 写在前面,前面我们快速搭建好了centos的集群环境,接下来,我们就来开始hadoop的集群的搭建工作 实验环境 Hadoop版本:CDH 5.7.0 这里,我想说一下 ...
- Spring MVC-从零开始-view-直接返回页面不传data
1.applicationContext配置 <?xml version="1.0" encoding="UTF-8"?> <beans xm ...
- Cisco交换机基本使用命令
作者:小啊博 QQ:762641008 转载请声明URL:https://www.cnblogs.com/-bobo/ 一.进入命令行 switch> ...
- PSSH工具
目录 PSSH工具 参考 PSSH工具的介绍 PSSH工具的使用 PSSH工具
- element取表格对应id数据
<el-button size="mini" type="danger" @click="editor(scope.row)"> ...
- [docker swarm] 从单容器走向负载均衡部署
背景 之前写过<<docker-compose真香>> 和<docker-compose.docker stack前世今生>两篇博客, 回顾一下思路: ① dock ...
- poll(2) 源码分析
poll(2) poll(2) 系统调用的功能和 select(2) 类似:等待一个文件集合中的文件描述符就绪进行I/O操作. 使用 实现 select(2) 的局限性: 关注的文件描述符集合大小最大 ...
- spring5 源码深度解析----- 事务的回滚和提交(100%理解事务)
上一篇文章讲解了获取事务,并且通过获取的connection设置只读.隔离级别等,这篇文章讲解剩下的事务的回滚和提交 回滚处理 之前已经完成了目标方法运行前的事务准备工作,而这些准备工作最大的目的无非 ...
- asp.net core 3.0 中使用 swagger
asp.net core 3.0 中使用 swagger Intro 上次更新了 asp.net core 3.0 简单的记录了一下 swagger 的使用,那个项目的 api 比较简单,都是匿名接口 ...