设计模式学习笔记——外观(Facade)模式
@(设计模式)[设计模式, 外观模式, facade]
基本介绍
外观模式其作用可以简单的理解为,为子模块(底层)抽出一个统一访问的接口,供父模块(上层)使用。
使用外观模式,调用者不需要知道底层的具体实现、逻辑是什么,只需要使用暴露出的接口就行了。使用外观模式并没有强制隐藏掉底层具体实现,也就是说,我们也可以直接调用底层的功能。
外观案例
类图
实现代码
Database类
package com.pc.facade.example;
import java.io.FileInputStream;
import java.util.Properties;
/**
* 数据库类
* Created by Switch on 2017/3/30.
*/
public final class Database {
private Database() {
}
/**
* 根据数据哭名获取Properties
*
* @param dbName 数据库名
* @return Properties对象
*/
public static Properties getProperties(String dbName) {
String fileName = dbName + ".txt";
Properties prop = new Properties();
try {
prop.load(new FileInputStream(fileName));
} catch (Exception e) {
System.out.println("Warning: " + fileName + " is not found.");
}
return prop;
}
}
maildata.txt
switchvov@163.com=Switch
bob@163.com=Bob
HtmlWriter类
package com.pc.facade.example;
import java.io.IOException;
import java.io.Writer;
/**
* Html编写类
* Created by Switch on 2017/3/30.
*/
public class HtmlWriter {
/**
* 编写器
*/
private Writer writer;
/**
* 构造方法,设置编写器
*
* @param writer 编写器
*/
public HtmlWriter(Writer writer) {
this.writer = writer;
}
/**
* 输出标题
*
* @param title 标题
* @throws IOException IO异常
*/
public void title(String title) throws IOException {
writer.write("<html>");
writer.write("<head>");
writer.write("<title>" + title + "</title>");
writer.write("<meta charset='UTF-8'/>");
writer.write("</head>");
writer.write("<body>\n");
writer.write("<h1>" + title + "</h1>\n");
}
/**
* 输出段落
*
* @param msg 信息
* @throws IOException IO异常
*/
public void paragraph(String msg) throws IOException {
writer.write("<p>" + msg + "</p>\n");
}
/**
* 输出超链接
*
* @param href 链接
* @param caption 标题
* @throws IOException IO异常
*/
public void link(String href, String caption) throws IOException {
this.paragraph("<a href=\"" + href + "\">" + caption + "</a>");
}
/**
* 输出邮件地址
*
* @param mailAddress 邮件地址
* @param userName 用户名
* @throws IOException IO异常
*/
public void mailto(String mailAddress, String userName) throws IOException {
link("mailto:" + mailAddress, userName);
}
/**
* 结束输出HTML
*
* @throws IOException IO异常
*/
public void close() throws IOException {
writer.write("</body>");
writer.write("</html>\n");
writer.close();
}
}
PageMaker类
package com.pc.facade.example;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
/**
* 页面Maker类
* Created by Switch on 2017/3/30.
*/
public final class PageMaker {
/**
* 防止外部new出PageMaker的实例,所以声明为private方法
*/
private PageMaker() {
}
/**
* 创建欢迎页
*
* @param mailAddress 邮箱地址
* @param filename 文件名
*/
public static void makeWelcomePage(String mailAddress, String filename) {
try {
Properties mailprop = Database.getProperties(System.getProperty("user.dir") + "/src/main/java/com/pc/facade/example/maildata");
String username = mailprop.getProperty(mailAddress);
HtmlWriter writer = new HtmlWriter(new FileWriter("D://" + filename));
writer.title("Welcome to " + username + "'s page!");
writer.paragraph("欢迎来到" + username + "的主页。");
writer.paragraph("等着你的邮件哦!");
writer.mailto(mailAddress, username);
writer.close();
System.out.println(filename + " is created for " + mailAddress + " (" + username + ")");
} catch (IOException e) {
e.printStackTrace();
}
}
}
测试类
package com.pc.facade.example.test;
import com.pc.facade.example.PageMaker;
import org.junit.Test;
/**
* PageMaker Tester.
*
* @author Switch
* @version 1.0
*/
public class PageMakerTest {
/**
* 测试外观模式
*/
@Test
public void testPageMaker() {
PageMaker.makeWelcomePage("switchvov@163.com", "welcome.html");
}
}
运行结果
控制台输出
welcome.html is created for switchvov@163.com (Switch)
D盘下welcome.html的内容
<html><head><title>Welcome to Switch's page!</title><meta charset='UTF-8'/></head><body>
<h1>Welcome to Switch's page!</h1>
<p>欢迎来到Switch的主页。</p>
<p>等着你的邮件哦!</p>
<p><a href="mailto:switchvov@163.com">Switch</a></p>
</body></html>
浏览器中运行结果
外观模式中的角色
Facade(窗口)
Facade
角色是代表构成系统的许多其他角色的“简单窗口” 。Facade
角色向系统外部提供高层接口(API
)。在案例中,由PageMaker
类扮演此角色。
构成系统的许多其他角色
这些角色各自完成自己的工作,它们并不知道Facade
角色。Facade
角色调用其他角色进行工作,但是其他角色不会调用Facade
角色。在案例中,由Database
类和HtmlWriter
类扮演此角色。
Client(请求者)
Client
角色负责调用Facade
角色(在GoF
书(请参见附录E[GoF])中,Client
角色并不包含在Facade
模式中)。在案例中,由Main
类扮演此角色。
类图
GitHub:DesignPatternStudy
——————参考《图解设计模式》