设计模式(十五)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 都用得挺 ...
随机推荐
- Flask中的路由、实例化参数和config配置文件
Flask中的路由 endpoint 别名不能重复,对应的视图函数,默认是视图函数名.endpoint 才是路由的核心.视图函数与路由的对应关系.可以通过url_for 反向创建url # metho ...
- React + TypeScript 实现泛型组件
泛型类型 TypeScript 中,类型(interface, type)是可以声明成泛型的,这很常见. interface Props<T> { content: T; } 这表明 Pr ...
- Ubuntu18.04安装PHP7.3
因为近期需要做毕业设计,需要用到Linux系统,在此分享一下在Linux-Ubuntu系统下安装PHP环境的一小点知识,如有偏差错误的,请各位学友多多指教哈! sudo apt-get install ...
- hihttps教你在Wireshark中提取旁路https解密源码
大家好,我是hihttps,专注SSL web安全研究,今天本文就是教大家怎样从wireshark源码中,提取旁路https解密的源码,非常值得学习和商业应用. 一.旁路https解密条件 众所周知, ...
- 通过实例快速掌握k8s(Kubernetes)核心概念
容器技术是微服务技术的核心技术之一,并随着微服务的流行而迅速成为主流.Docker是容器技术的先驱和奠基者,它出现之后迅速占领市场,几乎成了容器的代名词.但它在开始的时候并没有很好地解决容器的集群问题 ...
- SQL使用UPDATE和SUBSTRING截取字符串方法,从头截取到某个位置,截取中间片段,字符串中间截取到末尾或删除前面的字符串
//从头截取 update 表名 set 表列名 =SUBSTRING(表列名,1,目标位置数值) //!计数从1开始,从左往右 where 条件 //条件自己选择,不加where条件会更新所有 ...
- jobs后台任务
前台作业:占据了命令提示符,就是你当前可以操作的作业后台作业:启动之后,释放命令提示符,后续的操作在后台完成 前台——>后台 ctrl+z:把正在前台的作业送往后台,这时作业的状态是暂停. CO ...
- JS多线程WebWorker
JS多线程WebWorker 一,介绍与需求 1.1,介绍 Web Worker可以为JavaScript创建多线程,且Web Worker 是运行在后台的 JavaScript,独立于其他脚本,不会 ...
- Redis系列---操作命令及数据类型
本章将简单介绍下,Redis里面常用的数据类型以及我们常用到的一些命令,let's go 准备环境: Redis 详细见上一个章节 我们接下来操作的命令用的是Redis自带的客户端工具,在安装red ...
- IDEA 学习笔记之 Java项目开发
Java项目开发: 新建模块: 添加JDK: 导入本地Jars: 从远程Maven仓库下载: 创建package: 新建类/接口/枚举等: 字体太小,改字体: Duplicate Scheme 修改编 ...