12.设计模式之门面模式

门面模式提供了一个统一的接口来访问多个子系统的功能,简化了客户端的调用过程,降低了系统间的耦合度。文中通过Java代码示例展示了如何创建和使用门面模式,并提到其在slf4J日志框架等场景中的应用。该模式的优点包括简化调用、减少依赖,但可能不符合开闭原则。常见使用场景包括复杂子系统的简化接口和系统层次划分。
摘要由CSDN通过智能技术生成

前言

门面模式,是指提供一个统一的接口去访问多个子系统的多个不同的接口,它为子系统中的一组接口提供一个统一的高层接口。使得子系统更容易使用。日志框架slf4J是门面模式最经典的应用场景

本节,我们就门面模式,展开详细介绍。

1. 门面模式中的角色

1.1 门面角色(Facade)

客户端可以调用这个角色的方法。此角色知晓相关的(一个或多个)子系统的的功能和责任。在正常情况下,本角色会将所有从客户端发来的请求委派到相应的子系统去。

1.2 子系统角色(Subsystem)

可以同时有一个或者多个子系统。每一个子系统都不是一个单独的类,而是一个类的集合。每一个子系统都可以被客户端直接调用,或者被门面角色调用。子系统并不知道门面的存在,对于子系统而言,门面仅仅是另一个客户端而已。

2. 代码示例

2.1 定义门面角色

package com.wanlong.design_pattern.structure.facade;

/**
 * @author wanlong
 * @version 1.0
 * @description: 门面角色
 * @date 2022/9/19 16:31
 */
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();
    }
}

2.2 定义子系统角色

2.2.1 定义子系统A

package com.wanlong.design_pattern.structure.facade;

/**
 * @author wanlong
 * @version 1.0
 * @description:
 * @date 2022/9/19 16:30
 */
public class SubSystemA {

    public void doA(){
        System.out.println("doing A stuff");
    }
}

2.2.2 定义子系统B

package com.wanlong.design_pattern.structure.facade;

/**
 * @author wanlong
 * @version 1.0
 * @description:
 * @date 2022/9/19 16:30
 */
public class SubSystemB {

    public void doB() {
        System.out.println("doing B stuff");
    }
}

2.2.3 定义子系统C

package com.wanlong.design_pattern.structure.facade;

/**
 * @author wanlong
 * @version 1.0
 * @description:
 * @date 2022/9/19 16:30
 */
public class SubSystemC {

    public void doC(){
        System.out.println("doing C stuff");
    }
}

2.4 客户端调用

@Test
public void testFacade(){

   Facade facade = new Facade();
   facade.doA();
   facade.doB();
   facade.doC();
}

代码运行结果:

doing A stuff
doing B stuff
doing C stuff

3. 总结

3.1 优缺点

3.1.1 优点

  1. 简化了调用过程,无需深入了解子系统,以防给子系统带来风险。
  2. 减少系统依赖、松散耦合
  3. 更好地划分访问层次,提高了安全性
  4. 遵循迪米特法则,即最少知道原则

3.1.2 缺点

  1. 增加子系统和扩展系统行为时,可能容易带来未知风险
  2. 不符合开闭原则
  3. 某些情况下可能违背单一职责原则

3.2 使用场景

问:在什么情况下可以使用门面模式?
答:为一个复杂子系统提供一个简单接口

子系统往往因为不断演化而变的越来越复杂,使用门面模式可以使得子系统更具有可复用性。Facade模式可以提供一个简单的默认视图,对大多数用户来说这个视图已经足够用了。而那些需要进一步继承的用户可以越过Facade层直接对子系统进行继承

一般而言,子系统和其他子系统之间、客户端与实现化层之间存在着很大的依赖性。引入Facade模式将一个子系统与它的客户端及其他子系统分离,可以提高子系统的独立性和可移植性

在构建一个层次化的系统时,可以使用 Facade模式定义系统中每一层的入口如果层与层之间是相互依赖的,则可以限定它们仅通过Facade进行通信,从而简化层与层之间的依赖关系

这有点像现在很多公司系统结构层次,web层访问聚合服务层、聚合服务层访问微服务层、微服务层访问底层dao层、dao层访问DB。类似下图。通过微服务拆分粒度变细,以及分层,正常情况限制服务调用需要层层传递调用,那么在顶层的调用者其实是感知不到具体接口内部有多复杂的,解耦了系统之间的依赖关系
在这里插入图片描述

3.3 常用场景

  1. commons提供的DBUtils
  2. Spring JDBC工具类JdbcUtils
  3. slf4j日志框架使用(门面模式最经典的应用)
  4. tomcat 的请求门面RequestFacadeResponseFacade

3.4 注意

初学者往往以为通过继承一个门面类便可以在系统中加入新的行为,这是不合理的。门面模式的用意是,为子系统提供一个集中化和简化的沟通管道,而不能向子系统加入新的行为。以医院为例,接待员并不是医护人员,接待员并不能为病人提供医疗服务

4. 扩展文献

关于slf4j实现原理

以上,本人菜鸟一枚,如有问题,请不吝指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值