设计模式--门面模式

简介

门面模式(Facade Pattern)又叫外观模式,提供了一个统一的接口,用来访问子系统中的一群接口。其主要特征是定义了一个高层接口,让子系统更容易使用,属于结构型模式。

我们在生活中有很多地方也是用到了门面模式,但凡只要高层模块需要调用多个系统(2个以上类对象),我们都会自觉地创建一个新类封装这些子系统,提供精简接口,让高层模块可以更加容易间接调用这些子系统的功能。尤其是现阶段各种第三方SDK,更种开源类库,很大概率都会使用门面模式。

门面模式的应用场景

1、子系统越来越复杂,增加门面模式提供简单接口

2、构建多层系统结构,利用门面对象呢作为每层的入口,简化层间调用。

门面模式的UML图:

门面模式主要包含2种角色:

外观角色(Facade):也称门面角色,系统对外的统一接口;

子系统角色(SubSystem):可以同时有一个或多个SubSystem。每个SubSystem都不是一个单独的类,而是一个类的集合。SubSystem并不知道Facade的存在,对于SubSystem而言,Facade只是另一个客户端而已(即Facade对SubSystem透明)。

门面模式在源码中的应用

1、Spring JDBC模块下的JdbcUtils类

public abstract class JdbcUtils {
    public static final int TYPE_UNKNOWN = -2147483648;
    private static final Log logger = LogFactory.getLog(JdbcUtils.class);
    private static final Map<Integer, String> typeNames = new HashMap();

    public JdbcUtils() {
    }

    public static void closeConnection(@Nullable Connection con) {
        if (con != null) {
            try {
                con.close();
            } catch (SQLException var2) {
                logger.debug("Could not close JDBC Connection", var2);
            } catch (Throwable var3) {
                logger.debug("Unexpected exception on closing JDBC Connection", var3);
            }
        }

    }

    public static void closeStatement(@Nullable Statement stmt) {
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException var2) {
                logger.trace("Could not close JDBC Statement", var2);
            } catch (Throwable var3) {
                logger.trace("Unexpected exception on closing JDBC Statement", var3);
            }
        }

    }
    ...
}

其他的方法:

2、Mybatis类中的Configuration类

public MetaObject newMetaObject(Object object) {
    return MetaObject.forObject(object, objectFactory, objectWrapperFactory, reflectorFactory);
}

public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
    ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql);
    parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);
    return parameterHandler;
}

public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, RowBounds rowBounds, ParameterHandler parameterHandler,
                                            ResultHandler resultHandler, BoundSql boundSql) {
    ResultSetHandler resultSetHandler = new DefaultResultSetHandler(executor, mappedStatement, parameterHandler, resultHandler, boundSql, rowBounds);
    resultSetHandler = (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler);
    return resultSetHandler;
}

public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
    StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds, resultHandler, boundSql);
    statementHandler = (StatementHandler) interceptorChain.pluginAll(statementHandler);
    return statementHandler;
}

public Executor newExecutor(Transaction transaction) {
    return newExecutor(transaction, defaultExecutorType);
}

3、在Tomcat源码中也有使用,RequestFacade类、ResponseFacade类、StandardSessionFacade

门面模式的优缺点

优点:

1、简化了调用过程,无需深入了解子系统,以防给子系统带来风险

2、减少系统依赖、松散耦合

3、更好的划分访问层次,提高了安全性

4、遵守迪米特法则,即最少知道原则

缺点:

1、当增加子系统和扩展子系统行为时,可能容易带来未知风险

2、不符合开闭原则

3、某些情况下可能违背单一职责原则

代码链接

门面模式

posted @ 2021-07-27 21:59  snail灬  阅读(319)  评论(0编辑  收藏  举报