1、引入
facade,译为 外观; (建筑物的)正面,立面; (虚假的)表面,外表
对于一个复杂的系统,往往有多种构件,而对于使用者来说,完全使用基本的构建搭建是困难的,通常我们需要提供更为容易使用的上层API,封装底层的API。
而这种“封装”在软件开发中是经常用到的:
- 从机器语言到低级、中级、高级语言,可以视为一种封装。
- 从语言的基础语法到常用类库,可以视为一种封装
- 从基础语法和常用库到框架,可以视为一种封装
2、示例
在此,给出一个构建欢迎网页的例子。在本例中,网页构建需要数据库与网页搭建API协同,而引入了Facade模式后,只需要传入用户邮箱地址和网页存放位置,即可构建出一个简单的网页。
2.1、数据库
使用txt文本作为数据库,用K-V方式存储
操作数据库的类:
public class Database {
public Database() {
}
public static Properties getProperties(String dbname) {
String filename=dbname+".txt";
Properties properties = new Properties();
try {
properties.load(new FileInputStream(filename));
} catch (IOException e) {
e.printStackTrace();
}
return properties;
}
}
2.2、网页搭建API
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>");
}
public void link(String href,String caption) throws IOException {
paragraph("<a href=""+href+"">"+caption+"</a>");
}
public void mailto(String mailAddress, String username) throws IOException {
link("mailto:"+mailAddress, username);
}
public void close() throws IOException {
writer.write("</body>");
writer.write("</html>\n");
writer.close();
}
}
2.3、上层Facade
public class PageMaker {
private PageMaker() {
}
public static void makeWelcomePage(String mailAddress, String filename) {
try {
Properties properties = Database.getProperties("./src/facade/example/data");
String username = properties.getProperty(mailAddress);
HtmlWriter htmlWriter = new HtmlWriter(new FileWriter(filename));
htmlWriter.title("Welcome to "+username+"'s page");
htmlWriter.paragraph(username+"欢迎来到"+username+"的主页");
htmlWriter.paragraph("等待你的邮件");
htmlWriter.mailto(mailAddress, username);
htmlWriter.close();
System.out.println(filename+"is created for "+mailAddress+"("+username+")");
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.4、测试
public class Main {
public static void main(String[] args) {
PageMaker.makeWelcomePage("kloein@kloein.com", "./src/facade/example/welcome.html");
}
}
运行结果:
3、tips
- 虽然封装方便了我们使用,但是一定程度上牺牲了灵活性,因此完成部分工作时仍然需要使用基础的库。
- 在大型系统中,往往可以使用多级facade,通过层层封装方便系统的使用和维护