设计模式(十五)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 都用得挺 ...
随机推荐
- C语言入门-函数
一.初见函数 求出1到10.20到30和35到45的三个的和 #include <stdio.h> // 定义一个函数 void sum(int begin, int end) { int ...
- springboot 集成druid
1.druid简介 Druid首先是一个数据库连接池.Druid是目前最好的数据库连接池,在功能.性能.扩展性方面,都超过其他数据库连接池,包括DBCP.C3P0.BoneCP.Proxool.JBo ...
- 003-python函数式编程,模块
1.函数式编程 1.1 高阶函数 把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式 函数名也是变量,函数名其实就是指向函数的变量!对于abs()这个函数,完全可以把函 ...
- AVR单片机教程——数字IO寄存器
前两篇教程中我们学习了LED.按键.开关的基本原理,数字输入输出的使用以及两者之间的关系.我们用到了 pin_mode . pin_read 和 pin_write 这三个函数,实际上它们离最底层(至 ...
- F#周报2019年第40期
新闻 将项目成熟度重新考虑为一个社区过程 介绍.NET Core Windows Form设计器预览1 F# 4.7可以预览新语言特性与语法 视频及幻灯片 DotnetConf2019展示 .NET设 ...
- ThinkPHP5通过composer安装Workerman安装失败问题(避坑指南)
$ composer require topthink/think-workerUsing version ^2.0 for topthink/think-worker./composer.json ...
- 在Linux系统下有一个目录/usr/share/dict/ 这个目录里包含了一个词典的文本文件,我们可以利用这个文件来辨别单词是否为词典中的单词。
#!/bin/bash s=`cat /usr/share/dict/linux.words` for i in $s; do if [ $1 = $i ];then echo "$1 在字 ...
- 58同城AES签名接口分析
背景:需要获取58同城上面发布的职位信息,其中的包括职位的招聘要求,薪资福利,公司的信息,招聘者的联系方式.(中级爬虫的难度系数) 职位详情页分析 某个职位详情页的链接 https://qy.m.58 ...
- MongoDB 学习笔记之 索引选项和重建索引
索引选项: {background:true}在后台创建索引,索引在构建过程中,其他客户端仍然可以查询数据,不会阻塞. db.comments.createIndex({anonymous: 1},{ ...
- 死磕 java线程系列之线程池深入解析——体系结构
(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本. 简介 Java的线程池是块硬骨头,对线程池的源码做深入研究不仅能提高对Java整个并发编程的理解,也能提高自己 ...