门面模式 Facade Pattern

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 主要内容有:该模式的介绍,包括:引子、意图(大白话解释)类图、时序图(理论规范)该模式的代码示例:熟悉该模式的代码长什么样子该模式的优缺点:模式不是万金油,不可以滥用模式该模式的应用案例:了解它在哪些重要的源码中被使用


前言



主要内容有:

  • 该模式的介绍,包括:
  • 引子、意图(大白话解释)
  • 类图、时序图(理论规范)
  • 该模式的代码示例:熟悉该模式的代码长什么样子
  • 该模式的优缺点:模式不是万金油,不可以滥用模式
  • 该模式的应用案例:了解它在哪些重要的源码中被使用


结构型——外观模式、门面模式 Facade Pattern



引子

门面模式便是把一些复杂的流程封装成一个接口供给外部用户更简单的使用。

比如用户是用电脑,电脑有操作:开机关机重启等。每个操作里都有复杂的逻辑,比如开始需要先启动BIOS-引导硬盘—进入系统-初始化桌面等。对于使用者来说,只需要调用开机的方法。

定义


门面模式( Facade Pattern) 也叫做外观模式, 是一种比较常用的封装模式,

Provide a unified interface to a set of interfaces in a subsystem.Facade defines a higher-level interface that makes the subsystem easier to use.( 要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。 门面模式提供一个高层次的接口, 使得子系统更易于使用。 )


类图

如果看不懂UML类图,可以先粗略浏览下该图,想深入了解的话,可以继续谷歌,深入学习:

门面模式类图:

  • 客户角色(Client): 客户通过调用Facede来完成要实现的功能。
  • 门面角色(Facade):它被客户角色调用,并且知道自己管理着的子系统。内部根据客户角色的需求预定了几种功能的组合。
  • 子系统角色(SystemA/B/C):实现了子系统的功能。它对客户角色是完全透明的。它内部可以有系统内的相互交互,也可以由供外界调用的接口。


时序图

时序图(Sequence Diagram)是显示对象之间交互的图,这些对象是按时间顺序排列的。时序图中显示的是参与交互的对象及其对象之间消息交互的顺序。

我们可以大致浏览下时序图,如果感兴趣的小伙伴可以去深究一下:


代码实现

门面Facade:

public class Computer
{
    public static final Logger LOGGER = Logger.getLogger(Computer.class);
    private CPU cpu;
    private Memory memory;
    private Disk disk;
    public Computer()
    {
        cpu = new CPU();
        memory = new Memory();
        disk = new Disk();
    }
    public void start()
    {
        LOGGER.info("Computer start begin");
        cpu.start();
        disk.start();
        memory.start();
        LOGGER.info("Computer start end");
    }
    public void shutDown()
    {
        LOGGER.info("Computer shutDown begin");
        cpu.shutDown();
        disk.shutDown();
        memory.shutDown();
        LOGGER.info("Computer shutDown end...");
    }
}
复制代码

客户端调用Client:

public class Client
{
    public static final Logger LOGGER = Logger.getLogger(Client.class);
    public static void main(String[] args) {
        Computer computer = new Computer();
        computer.start();
        computer.shutdown();
    }
复制代码

对于用户来说,使用Client完全不需要关心底层细节。


使用场景举例


典型例子:SLF4J 中的外观模式

SLF4J 是简单的日志外观模式框架,抽象了各种日志框架例如 Logback、Log4j、Commons-logging 和 JDK 自带的 logging 实现接口。它使得用户可以在部署时使用自己想要的日志框架。

SLF4J 没有替代任何日志框架,它仅仅是标准日志框架的外观模式。如果在类路径下除了 SLF4J 再没有任何日志框架,那么默认状态是在控制台输出日志。


spring jdbc中的外观模式

查看 org.springframework.jdbc.support.JdbcUtils


Mybatis中的外观模式

查看 org.apache.ibatis.session.Configuration 类中以 new 开头的方法

public class Configuration {
    public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
        executorType = executorType == null ? defaultExecutorType : executorType;
        executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
        Executor executor;
        if (ExecutorType.BATCH == executorType) {
          executor = new BatchExecutor(this, transaction);
        } else if (ExecutorType.REUSE == executorType) {
          executor = new ReuseExecutor(this, transaction);
        } else {
          executor = new SimpleExecutor(this, transaction);
        }
        if (cacheEnabled) {
          executor = new CachingExecutor(executor);
        }
        executor = (Executor) interceptorChain.pluginAll(executor);
        return executor;
    }
    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;
    }
    // ...省略...
}
复制代码


Tomcat 中的外观模式

org.apache.catalina.connector.Request 和 org.apache.catalina.connector.RequestFacade 这两个类都实现了 HttpServletRequest 接口


优缺点

优点

  • 松散耦合:使得客户端和子系统之间解耦,让子系统内部的模块功能更容易扩展和维护;
  • 简单易用:客户端根本不需要知道子系统内部的实现,或者根本不需要知道子系统内部的构成,它只需要跟Facade类交互即可。
  • 更好的划分访问层次:有些方法是对系统外的,有些方法是系统内部相互交互的使用的。子系统把那些暴露给外部的功能集中到门面中,这样就可以实现客户端的使用,很好的隐藏了子系统内部的细节。

缺点

  • 在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。


参考



相关实践学习
通过日志服务实现云资源OSS的安全审计
本实验介绍如何通过日志服务实现云资源OSS的安全审计。
相关文章
|
机器学习/深度学习 资源调度 算法
【机器学习基础】多元线性回归(适合初学者的保姆级文章)
【机器学习基础】多元线性回归(适合初学者的保姆级文章)
734 0
|
SQL 数据库
SQL Server下载安装及使用
打开压缩之后的【SQL Server2016】文件夹
|
5月前
|
缓存 开发框架 .NET
一个功能丰富的 .NET 工具库 XiHan.Framework.Utils
XiHan.Framework.Utils 是一个功能全面的 .NET 工具库,包含字符串处理、集合扩展、加密解密、分布式 ID、文件操作、缓存、线程、国际化等模块。设计上注重高内聚、低耦合,适用于各类 .NET 应用开发。支持 AES 加密、树形结构转换、分页过滤、日志输出等功能,提供简单易用的 API。可通过 NuGet 快速安装,源码开放,采用 MIT 协议。
199 56
|
8月前
|
机器学习/深度学习 人工智能 运维
智能调度:自动化运维的"最强大脑"进化论
智能调度:自动化运维的"最强大脑"进化论
491 15
|
10月前
|
人工智能 前端开发 API
鸿蒙开发:简单自定义一个绘制画板
画板,最重要的就是绘制,保证线条绘制的连续性,这一点很重要,还有就是beginPath方法一定要调用,否则更改颜色以及绘制就会出现不连续以及颜色设置错误问题。
180 14
鸿蒙开发:简单自定义一个绘制画板
|
机器学习/深度学习 自然语言处理 物联网
Chronos: 将时间序列作为一种语言进行学习
Chronos框架预训练时间序列模型,将序列值转为Transformer模型的tokens。通过缩放、量化处理,模型在合成及公共数据集上训练,参数量20M至710M不等。优于传统和深度学习模型,展示出色零样本预测性能。使用分类交叉熵损失,支持多模态输出分布学习。数据增强策略包括TSMix和KernelSynth。实验显示大型Chronos模型在概率和点预测上超越多种基线,且微调小型模型表现优异。虽然推理速度较慢,但其通用性简化了预测流程。论文探讨了优化潜力和未来研究方向。
809 3
|
12月前
|
存储 Linux 开发者
熟悉 Docker 命令行工具
【10月更文挑战第6天】
272 3
|
12月前
|
容器
【LVGL快速入门】LVGL开源框架入门教程之框架使用(二)
【LVGL快速入门】LVGL开源框架入门教程之框架使用(二)
679 1
|
Java Maven
maven加入lib然后add as library
maven加入lib然后add as library
199 0