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。如果公开的方法过多,那么类的内部的修改会变得困难。如果公开了某个字段,那么其他类可能会读取或是修改这个字段,导致难以修改该类。如果公开了包,那么让外部看到了类,包内的代码的修改就会变得困难。

最新文章

  1. 不下载SDK启动Android Studio
  2. Mysql命令行中文乱码的解决方法
  3. unity scroolView 和 groupview
  4. js屏弊错误
  5. javascript——马步之Array篇
  6. bzoj1415
  7. Android 隐藏输入软键盘
  8. Unity strip engine code可能会使程序崩溃
  9. 第2章KNN算法笔记_函数classify0
  10. Struts-ValueStack和OGNL总结
  11. Implement int sqrt(int x).
  12. 《CSS世界》读书笔记(八)
  13. eclipse maven Errors while generating javadoc on java8
  14. MySql and Oracle Data Type Mappings
  15. UVA 11881 - Internal Rate of Return - [二分]
  16. sql根据某一个字段重复只取第一条数据
  17. bzoj3196: Tyvj 1730 二逼平衡树 树套树
  18. UISlider设置按钮透明
  19. Kali-linux测试网络范围
  20. OSG学习:转动的小汽车示例

热门文章

  1. 暑期——第三周总结(Ubuntu系统安装eclipse问题【已解决】)
  2. Merge into 语句实例
  3. SUSE CaaS Platform 4 - 安装部署
  4. linux目录化结构
  5. 集合线性表--List之ArrayList
  6. Docker 本地私有仓库搭建:
  7. Linux下beego及beego相关插件安装
  8. ASP.NET Web API 2系列(一):初识Web API及手动搭建基本框架
  9. GUI tkinter (bind)事件篇
  10. [网络流 24 题] luoguP2763 试题库问题