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

编程

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

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

门面模式主要有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 类,感兴趣的小伙伴可以去深入了解一下。

三、门面模式的优缺点

优点:

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

缺点:

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

以上是 架构师内功心法,外界访问系统内部唯一通道的门面模式详解 的全部内容, 来源链接: utcz.com/z/514178.html

回到顶部