Facade模式
当程序中的类越来越多,而且它们之间相互关联,这会导致程序结构也变得越来越复杂。我们在使用这些类之前,必须先弄清楚它们之间的关系,注意正确的调用顺序。这时不如为这个大型程序准备一个“窗口”,这样我们就不必单独地关注每个类,只需简单地对“窗口”提出请求即可。
我的理解:与Decorator模式比较一下,就是装饰者模式是对单个类加以层层包装,增加类的功能或特性;而Facade模式,就是将多个类封装起来,先组织好类之间的关联关系,与方法的调用关系,最后对外只提供一个简单方法来使用。
代码实现
示例程序将要编写简单的Web页面,主要涉及两个类,一个是用以提供url和username映射的properties文件——DataBase;另一个用来生成html页面——HtmlWrite
public class DataBase {
private DataBase() {
}
public static Properties getProperties(String dbname) {
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 {
writer.write("</body>");
writer.write("</html>\n");
writer.close();
}
}
简单窗口——PageMaker,就是将上面两个类的功能结合起来,封装成一个简单方法供用户使用,隐藏了里面的细节,和方法间的调用顺序。
public class PageMaker {
private PageMaker() {}
public static void makeWelcomePage(String mailaddr, String filename) {
try {
Properties mailprop = DataBase.getProperties("maildata");
String username = mailprop.getProperty(mailaddr);
HtmlWriter htmlWriter = new HtmlWriter(new FileWriter(filename));
htmlWriter.title("Welcome to " + username + "'s page!");
htmlWriter.paragraph(username + "欢迎来到" + username + "的主页");
htmlWriter.paragraph("等着你的邮件");
htmlWriter.mailto(mailaddr, username);
htmlWriter.close();
System.out.println(filename + " is create for " + mailaddr + "(" + username + ")");
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用者——Main
public class Main {
public static void main(String[] args) {
PageMaker.makeWelcomePage("www.baidu.com", "welcome.html");
}
}
可以看到,使用窗口类PageMaker后,使用者调用的方式非常简单,隐藏了里面方法调用的细节。
为什么要使用窗口类
使用Facade模式可以为互相关联在一起的错综复杂的类整理出高层接口(API)。其中的Facade角色可以让系统对外只有一个简单的接口(API),而且Facade角色还会考虑到系统内部各个类之间的责任关系和依赖关系,按照正确的顺序调用各个类。