外观模式或者门面模式(又是一个奇怪的名字),外观模式用于帮助客户端程序更容易的与系统代码交互。
外观模式隐藏了系统的复杂性,并向客户端提供了一个可以访问的系统的接口。为子系统的一组接口提供了一个统一的访问接口,使子系统更容易被访问或使用。
简单的说,该模式就是把一些复杂的流程封装成一个接口供给外部用户更简单的使用。
假设我们有一个具有很多接口的应用程序,用吧MySql/Oracle等数据库并生成不同类型的报告,例如HTML报告,PDF报告等。
所以我们将有不同的接口来处理不同类型的数据库。现在,客户端应用程序可以使用这些接口来获取所需的数据库连接并生成报告。
但当业务复杂性不断增加或接口的行为命名令人困惑,客户端程序会发现很难管理它。
所以这里我们可以使用外观模式,提供一个顶层接口包装来帮助客户端程序。
Facade Design Pattern – Set of Interfaces
我们可能有两个帮助类MySqlHelper和OracleHelper
public class MySqlHelper {
public static Connection getMySqlDBConnection(){
//get MySql DB connection using connection parameters
return null;
}
public void generateMySqlPDFReport(String tableName, Connection con){
//get data from table and generate pdf report
}
public void generateMySqlHTMLReport(String tableName, Connection con){
//get data from table and generate pdf report
}
}
public class OracleHelper {
public static Connection getOracleDBConnection(){
//get Oracle DB connection using connection parameters
return null;
}
public void generateOraclePDFReport(String tableName, Connection con){
//get data from table and generate pdf report
}
public void generateOracleHTMLReport(String tableName, Connection con){
//get data from table and generate pdf report
}
}
Facade Design Pattern Interface
We can create a Facade pattern interface like below. Notice the use of Java Enum for type safety.
public class HelperFacade {
public static void generateReport(DBTypes dbType, ReportTypes reportType, String tableName){
Connection con = null;
switch (dbType){
case MYSQL:
con = MySqlHelper.getMySqlDBConnection();
MySqlHelper mySqlHelper = new MySqlHelper();
switch(reportType){
case HTML:
mySqlHelper.generateMySqlHTMLReport(tableName, con);
break;
case PDF:
mySqlHelper.generateMySqlPDFReport(tableName, con);
break;
}
break;
case ORACLE:
con = OracleHelper.getOracleDBConnection();
OracleHelper oracleHelper = new OracleHelper();
switch(reportType){
case HTML:
oracleHelper.generateOracleHTMLReport(tableName, con);
break;
case PDF:
oracleHelper.generateOraclePDFReport(tableName, con);
break;
}
break;
}
}
public static enum DBTypes{
MYSQL,ORACLE;
}
public static enum ReportTypes{
HTML,PDF;
}
}
Facade Design Pattern Client Program
测试程序
public class FacadePatternTest {
public static void main(String[] args) {
String tableName="Employee";
//generating MySql HTML report and Oracle PDF report without using Facade
Connection con = MySqlHelper.getMySqlDBConnection();
MySqlHelper mySqlHelper = new MySqlHelper();
mySqlHelper.generateMySqlHTMLReport(tableName, con);
Connection con1 = OracleHelper.getOracleDBConnection();
OracleHelper oracleHelper = new OracleHelper();
oracleHelper.generateOraclePDFReport(tableName, con1);
//generating MySql HTML report and Oracle PDF report using Facade
HelperFacade.generateReport(HelperFacade.DBTypes.MYSQL, HelperFacade.ReportTypes.HTML, tableName);
HelperFacade.generateReport(HelperFacade.DBTypes.ORACLE, HelperFacade.ReportTypes.PDF, tableName);
}
}
正如你所看到的,使用Facade模式避免在客户端拥有大量逻辑,使程序更简单更清晰。 JDBC Driver Manager类获取数据库连接是外观模式的一个很好的例子。
Facade Design Pattern Important Points
- 对客户端程序来说,外观模式更像是一个helper类, 它不会隐藏系统的接口。是否使用外观模式完全取决于客户端代码。
- 外观模式可以应用到开发过程中的任意地方,通常的当接口的数量越来越多系统越来越复杂时考虑使用它。
- 子系统的接口不会意识到Facade的存在,他们也不应该引用Facade类的任何方法。
- 门面设计模式应当尽可能少的提供接口方法,它的目的是提供一个单一的接口而不是多个接口来解决一类问题。
- 通过外观模式可以为客户端提供更友好的接口。
网友评论