设计模式 自习室

【设计模式自习室】门面模式 Facade Pattern

2020-01-18  本文已影响0人  蛮三刀酱

前言

《设计模式自习室》系列,顾名思义,本系列文章带你温习常见的设计模式。主要内容有:

该系列会逐步更新于我的博客和公众号(博客见文章底部),也希望各位观众老爷能够关注我的个人公众号:后端技术漫谈,不会错过精彩好看的文章。

系列文章回顾

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

引子

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

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

image

定义

门面模式( 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类图,可以先粗略浏览下该图,想深入了解的话,可以继续谷歌,深入学习:

image

门面模式类图:

image

时序图

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

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

image

代码实现

门面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 再没有任何日志框架,那么默认状态是在控制台输出日志。

image

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 接口

优缺点

优点

缺点

参考

上一篇 下一篇

猜你喜欢

热点阅读