Facade (外观)模 式
一、简介
Façade (外观)模式(有些人又称:门面模式)。
GoF : 为子系统 中的一组接口提供一个一致的界面, Facade 模式定义了一个高层接口,这个接口使得这一子系统 更加容易使用。
二、学习 Façade (外观)模式
GoF 定义中的“子系统 ”是指:在你的系统中为了降低复杂度而遵循 一定规则(比如说:实现的功能、或同类的操作)划分出来的某(几)个归类。(也就是说,这些归类各自的功能不同,将它们划分开有效的降低了系统的复杂 性),这(些)个归类中封装了若干个类。当某一个模块调用它们的时候会非常的混乱,而由于混乱造成了新的复杂:如下图所示:
在上图中其他模块为了相应的实现必须调用每个类,当被调用的类特 别多而且每个类因为设计的原因有分成若干小类的时候,那么调用模块的实现是非常复杂的。解决的办法就是用一个类,在这里我们假设叫 FacadeP 类来对那些小类再封装。让调用模块通过再封装的 FacadeP 类来统一管理那些小类。从而使得系统简单。这就是 Façade 模式。如下图所示:
三、适用 性:
l 当你要为一个复杂子系统提供一个简单接口时候。就像我上面说的子系统也会根据需求不断演化而变得复杂,这是单纯的 用调用模块来管理这些类会使系统重新变得复杂,这时需要一个统一的管理接口。
l 调用模块和子系统之间存在着很大的依赖性。利用 Façade 模式将这个子系统与其他系统分离,这样提高了子系统得独立性和可 移植性。
l 当需要建立一个层次结构的子系统时,适用 Façade 模式定义子系统中每层的入口点。如果子系统之间是相互依赖的,也 可以通过 Façade 模式进行通讯,从而简化了它们之间的依赖关系。
四、关键 特征
l 意图 :希望简化现有系统的使用方法。你需要定义自己的接口。
l 问题 :只需要使用一个复杂系统的一个子集。或者,需要用一种特殊的方 式与系统交互。
l 解决方案 : Façade 模式向客户展现使用现有系统得一个新接口。
l 参与者与协作者 :向客户展现一个定制的接口,让客户更容易地使用现有系统。
l 效果 : Façade 模式简化了对所需子系统得使用。但是,由于 Façade 模式并不完整,因此某些功能对客户可能是不可用的。
l 实现 : 1 )定义一个(或一组)新的类来提供所需的接口。 2 )让新的类使用现有的系统。
五、举例
一个典型的应用就是数据库的连接:
在我封装了一个数据库连接类后,我还没有意识到我使用了 Façade 模式,直到对 Façade 模式有了了解后我才知道,现在贴出部分代码(完整的程序见我的 Blog : http://blog.donews.com/qutr/archive/2005/07/06/455743.aspx ):
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class DbConnect
{
/----------->>> 数据成员 and 构造函数
private Connection dbConnection = null;
private Statement selectPro = null; // 用于 select 操作
private Statement insertPro = null; // 用于 insert 操作
private Statement updatePro = null; // 用于 update 操作
private Statement deletePro = null; // 用于 delete 操作
private ResultSet dbResultSet = null; // 操作 select 结果集
/**
* 连接 MySql 数据库
* @param host MySql 数据库主机
* @param port MySql 数据库端口
* @param dbaName MySql 数据库名称
* @param usName MySql 数据库用户名
* @param psw MySql 数据库密码
* @return bool 值,连接成功返回真,失败返回假
*/
public boolean dbConnection(String host, String port, String dbaName, String usName, String psw)
{
String driverName = "com.mysql.jdbc.Driver";//"org.gjt.mm.mysql.Driver"
String dbHost = host;
String dbPort = port;
String dbName = dbaName;
String enCoding = "?useUnicode=true&characterEncoding=gb2312&autoReconnect=true"; // 处理 MySql 中文问题 & 解决数据库长连问题
String userName = usName;
String Psw = psw;
String url = "jdbc:mysql://" + dbHost + ":" + dbPort + "/" + dbName + enCoding;
try
{
Class.forName(driverName).newInstance();
dbConnection = DriverManager.getConnection(url, userName, Psw);
return true;
}catch(Exception e){
print("url = " + url); // 发生错误时,将连接数据库信息打印出来
print("userName = " + userName);
print("Psw = " + Psw);
e.printStackTrace(); // 得到详细的出错消息
return false;
}
}// end boolean dbConnection(...)
}//end class
上面是残缺的代码,但是已经能说明问题了。
六、总结
Façade 模式之所以被这样命名,因为它在原始系统得前面建造了一个新的 前端接口。这样在使用这个原始系统时候就显得非常简单、清晰。
不足之处,还请指教!