架构师内功心法,外界访问系统内部唯一通道的门面模式详解

Posted 1994july

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了架构师内功心法,外界访问系统内部唯一通道的门面模式详解相关的知识,希望对你有一定的参考价值。

一、门面模式的应用场景

门面模式(Facade Pattern)又叫外观模式,提供了一个统一的接口,用来访问子系统中的一群接口。主要特征是定义了一个高层接口,让子系统更容易使用。在我们的日常工作中,都在有意无意大量使用门面模式,但凡只要高层模块需要调度多个子系统,我们都会封装一个新类,提供精简接口,让高层模块很容易的间接调用这些子系统的功能。尤其是现阶段各种第三方API,各种开源类库,很大概率都会使用门面模式。

技术图片

门面模式适用于以下几种场景:

  • 子系统越来越复杂,增加门面模式提供简单接口;
  • 构建多层系统结构,利用门面对象作为每层的入口,简化层间调用。

门面模式主要有2种角色:

  • 外观角色(Facade):也成为门面角色,系统对外的统一接口;
  • 子系统角色(SubSystem):可以有一个或者多个子系统角色。

1.1 门面模式的通用写法

下面是门面模式的通用代码,首先分别创建 3 个子系统的业务逻辑 SubSystemA、SubSystemB、SubSystemC

public class SubSystemA {
    public void doA() {
        System.out.println("doing A stuff");
    }
}

public class SubSystemB {
    public void doB() {
        System.out.println("doing B stuff");
    }
}

public class SubSystemC {
    public void doC() {
        System.out.println("doing C stuff");
    }
}

然后,创建外观角色 Facade 类:

public class Facade {
    private SubSystemA a = new SubSystemA();
    private SubSystemB b = new SubSystemB();
    private SubSystemC c = new SubSystemC();
    // 对外接口
    public void doA() {
        this.a.doA();
    }
    // 对外接口
    public void doB() {
        this.b.doB();
    }
    // 对外接口
    public void doC() {
        this.c.doC();
    }
}

测试main方法:

 public static void main(String[] args) {
    Facade facade = new Facade();
    facade.doA();
    facade.doB();
    facade.doC();
}

二、门面模式在源码中的体现

2.1 Spring JDBC中的JdbcUtils

JdbcUtils封装了和JDBC 相关的所有操作,它一个代码片段:

public abstract class JdbcUtils {
    public static final int TYPE_UNKNOWN = -2147483648;
    private static final Log logger = LogFactory.getLog(JdbcUtils.class);
    public JdbcUtils() {
    }
    public static void closeConnection(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(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);
            }
        }
    }
    public static void closeResultSet(ResultSet rs) {
        if(rs != null) {
            try {
                rs.close();
            } catch (SQLException var2) {
                logger.trace("Could not close JDBC ResultSet", var2);
            } catch (Throwable var3) {
                logger.trace("Unexpected exception on closing JDBC ResultSet", var3);
            }
        }
    }
...
}

2.2 Tomcat 的源码中的RequestFacade 类

public class RequestFacade implements HttpServletRequest {
...
    @Override
    public String getContentType() {
        if (request == null) {
            throw new IllegalStateException(
                sm.getString("requestFacade.nullRequest"));
        }
        return request.getContentType();
    }
    @Override
    public ServletInputStream getInputStream() throws IOException {
        if (request == null) {
            throw new IllegalStateException(
                sm.getString("requestFacade.nullRequest"));
        }
        return request.getInputStream();
    }
    @Override
    public String getParameter(String name) {
        if (request == null) {
            throw new IllegalStateException(
                sm.getString("requestFacade.nullRequest"));
        }
        if (Globals.IS_SECURITY_ENABLED){
            return AccessController.doPrivileged(
            new GetParameterPrivilegedAction(name));
        } else {
            return request.getParameter(name);
        }
    }
...
}

我们看名字就知道它用了门面模式。它封装了非常多的request的操作,也整合了很多 servlet-api 以外的一些内容,给用户使用提供了很大便捷。同样,Tomcat 对 Response 和 Session 当也封装了ResponseFacade 和 StandardSessionFacade 类,感兴趣的小伙伴可以去深入了解一下。

三、门面模式的优缺点

优点:

  • 简化了调用过程,无需深入了解子系统,以防给子系统带来风险;
  • 减少系统依赖、松散耦合;
  • 更好地划分访问层次,提高了安全性;
  • 遵循迪米特法则,即最少知道原则。

缺点:

  • 当增加子系统和扩展子系统行为时,可能容易带来未知风险;
  • 不符合开闭原则;
  • 某些情况下可能违背单一职责原则。.

来源:迅闻网

以上是关于架构师内功心法,外界访问系统内部唯一通道的门面模式详解的主要内容,如果未能解决你的问题,请参考以下文章

架构师内功心法,参与富文本编辑器开发的备忘录模式详解

架构师内功心法,参与富文本编辑器开发的备忘录模式详解

架构师内功心法,经典高频面试的单例模式详解

架构师内功心法,经典高频面试的单例模式详解

二架构师内功心法之设计模式

架构师内功心法,属于游戏设计模式的策略模式详解