设计模式:外观(Facade)模式
设计模式:外观(Facade)模式
一、前言
外观模式是一种非常简单的模式,简单到我们经常都会使用,比如对于类A和B,如果两者需要交互,经过一定的处理过程才能实现某一个具体的功能,那么我们可以将这个处理的过程定义为一个新的类,然后在这个类里面将类A和B的处理步骤整合在一起,对于外界我们只暴露新的类中的这个接口,这样代码的复用性就非常的好了,可以将这些代码作为组件去让其他程序去使用,这在我们的开发之中是非常常见的。甚至我们可以将抽象工厂模式中创建产品的接口当做外观模式的一种应用,这也是一种整合。对于模板方法,其实我们也是在父类之中面向抽象编程的,将一些关系整合起来,不过差别还是非常明显的,在外观模式中没有继承关系,是新建一个类来整合其它类之间复杂的相互依赖,调用等关系,因此外观模式比较直观。

二、代码
DataBase 类:
package zyr.dp.facade; import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties; public class DataBase {
private DataBase(){
}
public static Properties getProperties(String dbName){
Properties pro=new Properties(); try {
pro.load(new FileInputStream(dbName+".txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return pro;
} }
HTMLWriter类:
package zyr.dp.facade; import java.io.IOException;
import java.io.Writer; public class HTMLWriter { private Writer writer;
public HTMLWriter(Writer writer){
this.writer=writer;
}
public void title(String theTitle){
try {
writer.write("<html><head><title>"+theTitle+"</title></head><body>\n");
writer.write("<h1>"+theTitle+"</h1>\n");
} catch (IOException e) {
e.printStackTrace();
}
}
public void paragraph(String msg){
try {
writer.write("<p>"+msg+"</p>\n");
} catch (IOException e) {
e.printStackTrace();
}
}
public void link(String href,String caption){
paragraph("<a href=\""+href+"\" >"+caption+"</a>");
}
public void mailTo(String mailAddr,String username) {
link("mailto:"+mailAddr,username);
}
public void close() {
try {
writer.write("</body></html>\n");
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
PageMaker类:
package zyr.dp.facade; import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties; public class PageMaker {
private PageMaker(){
}
public static void makePage(String mailAddr,String filename) throws IOException{
Properties pro=DataBase.getProperties("mailData");
String username=pro.getProperty(mailAddr);
HTMLWriter html=new HTMLWriter(new FileWriter(filename));
html.title("编程之美");
html.paragraph("欢迎 "+username+" 来到我的程序空间!");
html.paragraph("这里有你想要的一切~~");
html.mailTo(mailAddr, username);
html.close();
System.out.println("为"+username+"创建"+filename+"文件成功!");
} }
main类:
package zyr.dp.facade;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try {
PageMaker.makePage("2655100328@qq.com", "my_html.html");
} catch (IOException e) {
e.printStackTrace();
}
}
}
mailData存放的位置和内容:(注意如果使用相对地址,对于java程序来说src的上一级就是相对地址的起始地址,如果要放到src里面可以使用“./src/...”)。

运行结果:



虽然程序很简单,但是要注意的地方一点也不少,首先就是我们要将外观模式的接口对应的类(pageMaker)以及一些不用生成对象的工具类的构造函数设为私有,不让外部类去创建实例,其次,我们要注意properties读取文件的时候使用相对路径应该从哪个地方开始读写,另外当我们的程序变得复杂的时候,如果将这些类封装成一个模块,如何防止类外的对象访问我们的类呢,可以将除了facade类之外的类的属性设为默认的,这样就能很好的实现高内聚低耦合的设计思想了。这些类本来没关系,但是通过一个整合之后,产生了一定的关联,在实际开发中可能形成递归结构,那就是一个facade模式中使用了很多其他的facade模式,这样不断地实现下去,形成一个facade模式树,因此灵活使用设计模式至关重要。
三、总结
facade外观模式是一种非常常用的模式,特别是在组织一些复杂的相互调用的逻辑的时候,为外界提供统一的接口(API),可以看到在设计模式中,最常用的应该就是模板方法和facade模式了,很多时候很多需求需要我们认真的取舍,人无远虑必有近忧,同样的,只有为以后的可复用性、可扩展性来考虑,我们的代码才是好的代码。
设计模式:外观(Facade)模式的更多相关文章
- 设计模式--外观(Facade)模式
Insus.NET在去年有写过一篇<软件研发公司,外观设计模式(Facade)>http://www.cnblogs.com/insus/archive/2013/02/27/293606 ...
- 一天学习两个设计模式之Facade模式(外观模式,结构型模式)
程序这东西随着时间推移,程序会越来越大,程序中的类越来越多,而且他们之间相互关联,这会导致程序结构变得越来越复杂.因此我们在使用他们时候,必须要弄清楚他们之间的关系才能使用他们. 特别是在调用大型程序 ...
- 设计模式C++描述----14.外观(Facade)模式
一. 举例说明 还以我以前做的文件系统(FileSys)为例: 文件系统是一个独立的系统,它提供一套核心的文件操作. 除了文件系统,还有四个子系统,分别是杀毒子系统(KillVirus),压缩子系统( ...
- 设计模式之Facade模式
Facade(外观)模式为子系统中的各类(或结构与方法)提供一个简明一致的界面,隐藏子系统的复杂性,使子系统更加容易使用.他是为子系统中的一组接口所提供的一个一致的界面. 在遇到以下情况使用Facad ...
- 外观(Facade)模式
外观模式:为子系统中的一组接口提供一个一致的界面.此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用 在软件开发中,有时候为了完成一项较为复杂的功能,一个客户类需要和多个业务类交互,而这些需 ...
- Python笔记:设计模式之facade模式
facade模式,即门面模式,也称外观模式,这个模式的核心思想是使用facade对象为外部客户端提供一个统一的访问一组子系统的接口,即客户端不会直接与各个子系统交互,而是通过facade对象与各个子系 ...
- 十一、外观(Facade)模式--结构模式(Structural Pattern)
外部与一个子系统的通信必须通过一个统一的门面(Facade)对象进行,这就是门面模式.门面模式要求一个子系统的外部与其内部的通信必须通过一个统一的门面(Facade)对象进行. 门面模式提供一个高层次 ...
- Head First 设计模式 —— 08. 外观 (Facade) 模式
思考题 想想看,你在 JavaAPI 中遇到过哪些外观,你还希望 Java 能够新增哪些外观? P262 println.log 日志接口.JDBC 接口 突然让想感觉想不出来,各种 API 都用得挺 ...
- 设计模式 外观 Facade
外观模式的作用是简化接口.它提供一个统一的接口用来访问子系统的一群接口.通过这个高层接口使子系统更容易使用. 同时,通过外观将客户从组件的子系统中解耦. Head 1st中使用了家庭影院的例子来说明外 ...
- 设计模式——外观模式(Facade)
1. 概述 外观模式,我们通过外观的包装,使应用程序只能看到外观对象,而不会看到具体的细节对象,这样无疑会降低应用程序的复杂度,并且提高了程序的可维护性. 例子1:一个电源总开关可以控制四盏灯 ...
随机推荐
- centos 7编译安装mysql 5.7.17
1.进入MySQL官网下载MySQL源代码 依次点击Downloads -> Community -> MySQL Community Server 源代码1.Select Operati ...
- Servlet用户登录功能实现
需求:完成用户登录页面校验 第一步:创建一个用户登录的html页面 <!DOCTYPE html> <html> <head> <meta charset=& ...
- 获取两个数之间的随机数-java
start=25 end=30 (int)(Math.random()*(end-start)+start)
- 【Lua】Lua + openresty遍历文件目录
OpenResty (也称为 ngx_openresty)是一个全功能的 Web 应用服务器,它打包了标准的 Nginx 核心,很多的常用的第三方模块,以及它们的大多数依赖项. 今天用OpenRest ...
- 【随笔】Win7下GVIM的安装与配置
针对各种语言的编辑器千千万万,最好的就是最适合自己的,这句话一点没错. 偶然间,需要在Windows上编写代码,MyEclipse等太大,完全没有必要,所以就想起来了vim这个神器.个子小,功能强,就 ...
- ZOJ 3769 Diablo III
描述 Diablo III is an action role-playing video game. A few days ago, Reaper of Souls (ROS), the new e ...
- leetcode_787【K 站中转内最便宜的航班】
有 n 个城市通过 m 个航班连接.每个航班都从城市 u 开始,以价格 w 抵达 v. 现在给定所有的城市和航班,以及出发城市 src 和目的地 dst,你的任务是找到从 src 到 dst 最多经过 ...
- 清除SQL Server内存
数据库进行查询时,会缓存结果集,当查询结果过大时会出现内存爆满的情况,如果手动清除SQL所占用的内存呢,在网上搜索一下,把结果贴下面: --强制释放内存 Create procedure [dbo]. ...
- TortoiseGit记住用户名&密码
配置并安装好git之后鼠标右键: 在全局配置文件末尾添加一行: [credential] helper = store *主意保存时以utf-8格式保存,否则中文可能会乱码,这样下次只需输入一次用户名 ...
- C#学习笔记15
1.平台互操作性和不安全的代码:C#功能强大,但有些时候,它的表现仍然有些“力不从心”,所以我们只能摒弃它所提供的所有安全性,转而退回到内存地址和指针的世界. C#通过3种方式对此提供支持. (1)第 ...