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模式的更多相关文章

  1. 【转】设计模式 ( 十五 ) 中介者模式Mediator(对象行为型)

    设计模式 ( 十五 ) 中介者模式Mediator(对象行为型) 1.概述 在面向对象的软件设计与开发过程中,根据"单一职责原则",我们应该尽量将对象细化,使其只负责或呈现单一的职 ...

  2. 设计模式 ( 十五 ) 中介者模式Mediator(对象行为型)

    设计模式 ( 十五 ) 中介者模式Mediator(对象行为型) 1.概述 在面向对象的软件设计与开发过程中,根据“单一职责原则”,我们应该尽量将对象细化,使其只负责或呈现单一的职责,即将行为分布到各 ...

  3. 【转】设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

    设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成 ...

  4. 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

    设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也经常遇到类似的情况,实现某一个功能有多种算法或者策略,我们能够依据环境或者条件的不同选择不同的算法或者策略来完毕 ...

  5. 设计模式 ( 十九 ) 模板方法模式Template method(类行为型)

      设计模式 ( 十九 ) 模板方法模式Template method(类行为型) 1.概述 在面向对象开发过程中,通常我们会遇到这样的一个问题:我们知道一个算法所需的关键步骤,并确定了这些步骤的执行 ...

  6. 设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型)

      设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型) 1.概述 类中的面向对象编程封装应用逻辑.类,就是实例化的对象,每个单独的对象都有一个特定的身份和状态.单独的对象是一种组织代码的 ...

  7. C#设计模式之十五命令模式(Command Pattern)【行为型】

    一.引言   今天我们开始讲"行为型"设计模式的第二个模式,该模式是[命令模式],又称为行动(Action)模式或交易(Transaction)模式,英文名称是:Command P ...

  8. C#设计模式之十五迭代器模式(Iterator Pattern)【行为型】

    一.引言 今天我们开始讲“行为型”设计模式的第三个模式,该模式是[迭代器模式],英文名称是:Iterator Pattern.还是老套路,先从名字上来看看.“迭代器模式”我第一次看到这个名称,我的理解 ...

  9. Java设计模式菜鸟系列(十五)建造者模式建模与实现

    转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/39863125 建造者模式(Builder):工厂类模式提供的是创建单个类的模式.而建造者模 ...

  10. Head First 设计模式 —— 08. 外观 (Facade) 模式

    思考题 想想看,你在 JavaAPI 中遇到过哪些外观,你还希望 Java 能够新增哪些外观? P262 println.log 日志接口.JDBC 接口 突然让想感觉想不出来,各种 API 都用得挺 ...

随机推荐

  1. 2015年蓝桥杯java b组第十题

    10. 生命之树 在X森林里,上帝创建了生命之树. 他给每棵树的每个节点(叶子也称为一个节点)上,都标了一个整数,代表这个点的和谐值. 上帝要在这棵树内选出一个非空节点集S,使得对于S中的任意两个点a ...

  2. electron教程(一): electron的安装和项目的创建

    我的electron教程系列 electron教程(一): electron的安装和项目的创建 electron教程(二): http服务器, ws服务器, 进程管理 electron教程(三): 使 ...

  3. FastDfs之StorageServer的详细配置介绍

    #这个配置文件是否失效 disabled=false #false为有效 true为无效 # 本storage server所属的group名 group_name=group1 # 可以版定一个ip ...

  4. 夯实Java基础系列13:深入理解Java中的泛型

    目录 泛型概述 一个栗子 特性 泛型的使用方式 泛型类 泛型接口 泛型通配符 泛型方法 泛型方法的基本用法 类中的泛型方法 泛型方法与可变参数 静态方法与泛型 泛型方法总结 泛型上下边界 泛型常见面试 ...

  5. python 写入txt的新方法

    最新发现有新方法可以对txt等进行操作,比较有意思,之前没见过,故记录下 传统方法 with open(ur'D:\Desktop\a123.txt', 'a') as f: #以写的方式打开 f.w ...

  6. 鱼和熊掌可兼得?一文看懂又拍云 SCDN

    转眼已是 9102 年,参与工作多年的二狗子凭借他聪明的脑瓜和孜孜不倦的钻研精神,成为了某中型企业的资深网站管理员.不同于一般的"网管",二狗子自然是业内最优秀的那一类. 但是,最 ...

  7. Egret资源跨域问题

    在服务器上配置了允许跨域还不够,还需要在引擎配置允许跨域,不然texture无法在webgl上下文中渲染 会报一个类似于The cross-origin image at 的错误, 只需要在egret ...

  8. 解决MVC中Model上的特性在EF框架刷新时清空的问题

    MVC中关于前端数据的效验一般都是通过在Model中相关的类上打上特性来实现. 但是在我们数据库发生改变,EF框架需要刷新时会把我们在Model上的特性全部清除,这样的话,我们前端的验证就会失效. 因 ...

  9. 关于padding被计算在width中问题——box-sizing相关

    目录 盒子模型 与box-sizing有什么关系 我们为什么要开历史的"倒车" bootstrap怎么解决的 控件的box-sizing 注意甄别 前一阵子遇到一个小问题,在同样的 ...

  10. Java的Object类

    (1)Object是类层次结构的根类,所有的类都直接或者间接的继承自Object类. (2)Object类的构造方法有一个,并且是无参构造 这其实就是理解当时我们说过,子类构造方法默认访问父类的构造是 ...