【设计模式】 外观模式(Facade Pattern)

117 阅读4分钟

外观模式(Facade Pattern)

定义

定义了一个高层、统一的接口,外部与通过这个统一的接口对子系统中的一群接口进行访问

结构

  1. 外观(Facade)角色:为多个子系统对外提供一个共同的接口。
  2. 子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色来访问它。
  3. 客户(Client)角色:通过一个外观角色访问各个系统的功能。

类图

image.png

例子

家中有许多电器 每次出门都需要挨个关闭,回来再挨个开启很麻烦。 可以加一个控制器来一键开关

代码

public class Facade{
      
      SubSystemA_Light light;
      SubSystemB_Television television ;
      SubSystemC_Aircondition aircondition;
    

      //传参
    public Facade(SubSystemA_Light light,SubSystemB_Television television,SubSystemC_Aircondition aircondition){  
        this.light = light;  
        this.television  = television ;  
        this.aircondition =aircondition;  
    
    }  
      //起床后一键开电器
      public void on{
        System.out.prinln("起床了"); 
        light.on(); 
        television.on(); 
        aircondition.on();
    
        }

          //睡觉时一键关电器
          System.out.prinln("睡觉了"); 
          light.off(); 
          television.off(); 
          aircondition.off(); 
}

        
      
      }

客户端代码

public class Customer{ 
      public static void main(String[] args){
        {
            //实例化电器类
            SubSystemA_Light light = new SubSystemA_Light();
            SubSystemB_Television television = new SubSystemB_Television();
            SubSystemC_Aircondition aircondition = new SubSystemC_Aircondition();
            
            //传参
            Facade facade = new Facade(light,television,aircondition);
            
            //客户端直接与外观对象进行交互
            facade.on;
            System.out.prinln("可以看电视了"); 
            facade.off;
            System.out.prinln("可以睡觉了"); 


作用

解耦客户类与子系统类,降低原有系统复杂度 提高客户端的便捷性,使其无需关心子系统的工作细节即可调用相关功能

实际应用

Spring Boot WebMvcConfigurer

在Spring Boot中,外观模式(Facade Pattern)通常用于简化与框架或库的交互。

一个典型的例子是Spring Boot的WebMvcConfigurer接口。在使用Spring MVC时,通常需要许多配置和自定义选项,例如添加自定义拦截器、消息转换器、异常处理器等。但是,将这些选项直接添加到WebMvcConfigurer接口中可能会导致代码混乱和难以维护。

因此,Spring Boot使用外观模式,提供了一个WebMvcConfigurerAdapter类,该类允许开发人员通过覆盖一些简单方法来完成配置,而不必直接修改复杂的WebMvcConfigurer接口。

另一个例子是Spring Boot的JdbcTemplate类,该类是用于与数据库交互的简单模板类。JdbcTemplate隐藏了所有与JDBC API相关的细节,并提供了简单的方法来执行SQL查询和更新。通过这种方式,JdbcTemplate充当了一个外观,简化了与数据库的交互。

因此,在Spring Boot中,外观模式被广泛应用于简化与框架和库的交互。

SLf4j

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

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

日志处理框架 Logback 是 Log4j 的改进版本,原生支持SLF4J(因为是同一作者开发的),因此 Logback+SLF4J 的组合是日志框架的最佳选择,比 SLF4J+其它日志框架 的组合要快一些。而且Logback的配置可以是XMLGroovy代码。

image.png

缺点

在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端源代码,违背开闭原则 不能很好地限制客户使用子系统类,如果客户访问子系统类做太多的限制则减少了可变性和灵活性

场景

  • 要为一个复杂的子系统对外提供一个简单的接口
  • 提供子系统的独立性
  • 客户程序与多个子系统时间存在很大的依赖性

与适配器模式的区别 外观模式的实现核心主要是——由外观类去保存各个子系统的引用,实现由一个统一的外观类去包装多个子系统类,然而客户端只需要引用这个外观类,然后由外观类来调用各个子系统中的方法。 这样的实现方式非常类似适配器模式,然而外观模式与适配器模式不同的是:适配器模式是将一个对象包装起来以改变其接口,而外观是将一群对象 ”包装“起来以简化其接口。它们的意图是不一样的,适配器是将接口转换为不同接口,而外观模式是提供一个统一的接口来简化接口。

参考

  1. Carson带你学设计模式:外观模式(Facade Pattern)
  2. Java设计模式(二十一)—— 外观模式
  3. 外观模式