外观设计模式

GoF

Provide a unified interface to a set of interfaces in a subsystem.Facade definesa higher-level interface that makes the subsystem easier to use.

在这里插入图片描述
Facade design pattern is used to help client applications to easily interact with the system.
Facade设计模式用于帮助客户端应用程序轻松地与系统交互。

外观模式也叫门面模式。在日常生活中,门面模式也是很常见的。比如,我们去医院就诊,很多医院都设置了导诊台,这个导诊台就好比一个门面。有了这个导诊台,我们全程就诊都不需要到处乱转,就诊路线变得非常清楚。

外观模式的应用场景

在软件系统中,门面模式适用于以下应用场景。
(1)为一个复杂的模块或子系统提供一个简洁的供外界访问的接口。
(2)希望提高子系统的独立性时。
(3)当子系统由于不可避免的暂时原因导致可能存在Bug或性能相关问题时,可以通过门面模式提供一个高层接口,隔离客户端与子系统的直接交互,预防代码污染。

在这里插入图片描述
举例说明:
假设我们有一个应用程序,它有一组接口,不同的接口集来处理不同类型的数据库。并生成不同类型的报告,如HTML报告、PDF报告等。当 接口复杂性增加接口名字起不好看不懂时,会很令人困惑,客户端应用程序会发现很难管理它。

Set of Interfaces

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
		System.out.println("生成  MySql PDF"+tableName +"Report");
	}

	public void generateMySqlHTMLReport(String tableName, Connection con) {
		// get data from table and generate html report
		System.out.println("生成  MySql HTML"+tableName +"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
		System.out.println("生成  Oracle PDF"+tableName +"Report");
	}
	
	public void generateOracleHTMLReport(String tableName, Connection con){
		//get data from table and generate html report
		System.out.println("生成  Oracle PDF"+tableName +"Report");
	}
}

Facade

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);
                    case PDF -> mySqlHelper.generateMySqlPDFReport(tableName, con);
                }
            }
            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;
                }
            }
        }

    }

    public enum DBTypes {
        MYSQL, ORACLE;
    }

    public enum ReportTypes {
        HTML, PDF;
    }
}

使用

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);
System.out.println("**************************");
//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);

结构

生成  MySql HTMLEmployeeReport
生成  Oracle PDFEmployeeReport
**************************
生成  MySql HTMLEmployeeReport
生成  Oracle PDFEmployeeReport

避免在客户端有 大量逻辑更简单更清晰的方法。
JDBC Driver Manager类获得数据库连接是外观设计模式的一个很好的例子

在这里插入图片描述

门面模式在Spring源码中的应用

先来看Spring JDBC模块下的JdbcUtils类,它封装了与JDBC相关的所有操作,代码片段如下。

public abstract class JdbcUtils {
...
	public static void closeConnection(Connection con) {
		if (con != null) {
			try {
				con.close();
			}
			catch (SQLException ex) {
				logger.debug("Could not close JDBC Connection", ex);
			}
			catch (Throwable ex) {
				// We don't trust the JDBC driver: It might throw RuntimeException or Error.
				logger.debug("Unexpected exception on closing JDBC Connection", ex);
			}
		}
	}
	public static void closeStatement(Statement stmt) {
		if (stmt != null) {
			try {
				stmt.close();
			}
			catch (SQLException ex) {
				logger.trace("Could not close JDBC Statement", ex);
			}
			catch (Throwable ex) {
				// We don't trust the JDBC driver: It might throw RuntimeException or Error.
				logger.trace("Unexpected exception on closing JDBC Statement", ex);
			}
		}
	}
	public static void closeResultSet(ResultSet rs) {
		if (rs != null) {
			try {
				rs.close();
			}
			catch (SQLException ex) {
				logger.trace("Could not close JDBC ResultSet", ex);
			}
			catch (Throwable ex) {
				// We don't trust the JDBC driver: It might throw RuntimeException or Error.
				logger.trace("Unexpected exception on closing JDBC ResultSet", ex);
			}
		}
	}
...

具体的操作会由具体的数据库去实现,这里只是统一调用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值