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模式

即上文所说,递归的加中间层。

最新文章

  1. 浅谈Hibernate入门
  2. ReactiveCocoa的一些使用
  3. CSS的一些简单概念
  4. [HDOJ5451]Best Solver(乱搞)
  5. SAM4E单片机之旅——20、DMAC之使用Multi-buffer进行内存拷贝
  6. linux工具之putty
  7. UrlRewriter.dll伪静态实现二级域名泛解析
  8. 剖析并利用Visual Studio Code在Mac上编译、调试c#程序【转】
  9. [转] 深入剖析 linux GCC 4.4 的 STL string
  10. 绘制一个绿色矩形平面((50, 50)-&gt;(350, 350))
  11. 即时通信系统Openfire分析之八:集群管理
  12. JPA实体的常用注解
  13. 源码包安装php7.2
  14. HTML和CSS初级前端面试题汇总(持续补充)
  15. 一道有意思的找规律题目 --- CodeForces - 964A
  16. learn python the hard way 习题18~25总结
  17. AngularJS2.0教程(一)快速上手之基础知识
  18. NoSQL数据库的分布式算法
  19. Solidworks如何打开swb文件
  20. 【F12】九个Console命令,让js调试更简单

热门文章

  1. 使用css3的repeating-linear-gradient画虚线
  2. es5继承和es6类和继承
  3. MySQL索引面试题分析(索引分析,典型题目案例)
  4. 工具使用——IDEA常用的几种插件
  5. ElasticSearch - 解决ES的深分页问题 (游标 scroll)
  6. libevent 网络库安装
  7. ACM/IOI 国家队集训队论文集锦
  8. JavaScript自增和自减
  9. ViewContainerRef 动态创建视图
  10. PHP开发工具PHP基础教程