》》使用Facade 模式可以为互相关联在一起的错综复杂的类整理出高层接口(API)。
其中的 Facade 角色可以让系统外只有一个简单的接口(API)。而且,Facade
角色还会考虑到系统内部各个类之间的责任关系和依赖关系,按照正确的顺序调
用各个类。
----------------下面的示例程序中:只考虑一个由3个简单的类构成的系统。也就是一个
用于从邮件地址中获取用户名字的数据库类(Database) ,一个用于编写HTML
文件的类(HtmlWriter),以及一个扮演 Facade 角色并提供高层接口API的类
(PageMaker)
--------------------------------------------
《在浏览器中查看到的使用示例程序编写出的Web页面》
------------------------------------------------
《示例程序的类图》
--------------------------------------------------------------------
《Database类》
package pagemaker;
import java.util.Properties;
import java.io.FileInputStream;
import java.io.IOException;
public class Database {
//防止外部 new 出 Database 的实例,所以要声明为 private
private Database(){
}
public static Properties getProperties(String dbname){ //根据数据库名获取 Properties
String filename = dbname+".txt";
Properties prop = new Properties();
try{
prop.load(new FileInputStream("E:/Java基础练习/Java/src/"+filename));
}catch(IOException e){
System.out.println("Waring"+filename+"is not found");
}
return prop;
}
}
----------------------------------------------------------
《maildata.txt》----------》数据文件
hyuki@hyuki.com=Hiroshi Yuki
hanako@hyuki.com=Hanako Sato
tomura@hyuki.com=Tomura
mamoru@hyuki.com=Mamoru Takahashi
---------------------------------------------------------
《HtmlWriter类》
package pagemaker;
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>\n");
writer.write("<head>\n");
writer.write("<title>"+title+"</title>\n");
writer.write("</head>\n");
writer.write("<body>\n");
writer.write("<h1>"+title+"</h1>");
}
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>\n");
writer.write("</html>\n");
writer.close();
}
}
----------------------------------------------------
《PageMaker类》
package pagemaker;
import java.io.IOException;
import java.util.Properties;
import java.io.FileWriter;
public class PageMaker {
//防止外部new 出 PageMaker 的实例,所以声明为 private
private PageMaker(){
}
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();
}
}
}
----------------------------------------------------
《Main类》---------》测试程序
package pagemaker;
public class Main {
public static void main(String[] args){
PageMaker.makeWelcomePage("hyuki@hyuki.com", "welcome.html");
}
}
---------------------------------------------------
《Facade 模式中的登场角色》
**** Facade (窗口)
Facade 角色是代表构成系统的许多其他角色的“简单窗口”。Facade 角色
向系统外部提供高层接口 (API)。在示例程序中,由PageMaker 类扮演此角
色。
**** 构成系统的许多其他角色
这些角色各自完成自己的工作,它们并不知道 Facade 角色。Facade 角色
调用其他角色进行工作,但是其他角色不会调用 Facade 角色。在示例程序中,
Database 和 HtmlWriter 扮演此角色。
**** Client (请求者)
Client 角色负责调用 Facade 角色。在示例程序中,由 Main 类扮演此角色。
-----------------------------------------------------
《扩展思路的要点》
1. Facade 角色到底做什么工作
接口变少了。接口变少了还意味着程序与外部关联关系弱化了,这样更容易
使我们的包(类的集合)作为组件被复用。
与设计类一样,在设计包时,需要考虑类的可见性。如果让外部(包的外部)
看到了类,包内部代码的修改就会变得困难。
2.递归地使用 Facade 模式
假设现在有几个持有 Facade 角色类的集合。那么,我们可以通过整合这几
个集合来引入新的 Facade 角色。也就是说,我们可以递归地使用 Facade 模式。
在超大系统中,往往都含有非常多的类和包。如果我们在每个关键的地方使用
Facade 模式,那么系统的维护就会变得轻松得多。
3.开发人员不愿意创建 Facade 角色的原因-----心理原因
当某个程序员得意地说“在调用那个类之前需要先调用这个类。在调用那个方法
之前需要先在这个类中注册一下”的时候,就意味者我们需要引入 Facade 角色了。
------------------------------------------------------
《相关的设计模式》
**** Abstract Factory 模式
**** Singleton 模式
**** Mediator 模式