门面模式 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类交互即可。
  • 更好的划分访问层次:有些方法是对系统外的,有些方法是系统内部相互交互的使用的。子系统把那些暴露给外部的功能集中到门面中,这样就可以实现客户端的使用,很好的隐藏了子系统内部的细节。

缺点

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


参考



相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
设计模式 算法
设计模式7 - 门面模式【Facade Pattern】
设计模式7 - 门面模式【Facade Pattern】
58 1
|
设计模式 Java uml
中介者模式(Mediator Pattern)
中介者模式(Mediator Pattern)是一种行为型设计模式,它用于降低多个对象之间的耦合度,通过引入一个中介者对象,将对象之间的交互转化为中介者和对象之间的交互,从而避免了对象之间的直接耦合。
93 1
|
应用服务中间件 智能硬件 容器
结构型模式 - 外观模式(Facade Pattern)
结构型模式 - 外观模式(Facade Pattern)
|
Java 程序员 API
结构型模式 - 适配器模式(Adapter Pattern)
结构型模式 - 适配器模式(Adapter Pattern)
结构型模式 - 装饰器模式(Decorator Pattern)
结构型模式 - 装饰器模式(Decorator Pattern)
|
设计模式 Java
Java设计模式——装饰模式(Decorator Pattern)
Java设计模式——装饰模式(Decorator Pattern)
204 0
Java设计模式——装饰模式(Decorator Pattern)
|
设计模式 JSON Java
【愚公系列】2021年12月 二十三种设计模式(十)-外观模式(Facade Pattern)
【愚公系列】2021年12月 二十三种设计模式(十)-外观模式(Facade Pattern)
127 0
【愚公系列】2021年12月 二十三种设计模式(十)-外观模式(Facade Pattern)
门面模式(Facade)
Facade模式的几个要点 从客户程序的角度来看,Facade模式不仅简化了整个组件系统的接口,同时对于组件内部与外部客户程序来说,从某种程度上也达到了一种“解耦”的效果——内部子系统的任何变化不会影响到Facade接口的变化。
891 0