架构师内功心法,外界访问系统内部唯一通道的门面模式详解
时间:2020-05-30
本文章向大家介绍架构师内功心法,外界访问系统内部唯一通道的门面模式详解 ,主要包括架构师内功心法,外界访问系统内部唯一通道的门面模式详解 使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
一、门面模式的应用场景
门面模式(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 类,感兴趣的小伙伴可以去深入了解一下。
三、门面模式的优缺点
优点:
- 简化了调用过程,无需深入了解子系统,以防给子系统带来风险;
- 减少系统依赖、松散耦合;
- 更好地划分访问层次,提高了安全性;
- 遵循迪米特法则,即最少知道原则。
缺点:
- 当增加子系统和扩展子系统行为时,可能容易带来未知风险;
- 不符合开闭原则;
- 某些情况下可能违背单一职责原则。.
来源:迅闻网
原文地址:https://www.cnblogs.com/1994july/p/12994247.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- ELK-elasticsearch-6.3.2部署
- Real World CTF 2018 bookhub 总结
- python http.server open redirect vulnerability
- ELK-elasticsearch-6.3.2插件【head,bigdesk,cerebro[kopf]】安装
- ELK-kibana-6.3.2部署
- node.js + postgres 从注入到Getshell
- ELK-logstash-6.3.2部署
- K8S节点异常怎么办?TKE"节点健康检查和自愈"来帮忙
- ELK-logstash-6.3.2-常用配置
- ELK-elkstack-使用消息队列
- kafka_2.11-2.0.0_安装部署
- 谈escapeshellarg绕过与参数注入漏洞
- Django debug page XSS漏洞(CVE-2017-12794)分析
- kafka_2.11-2.0.0_常用操作
- shell脚本:通过域名获取证书的过期时间