「聊设计模式」之外观模式(Facade)

🏆本文收录于《聊设计模式》专栏,专门攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎持续关注&&收藏&&订阅!


大家下午好,我是bug菌,今天我们继续聊设计模式。

前言

设计模式是一种通用的解决问题的方式,它不仅仅是在编程中有用,还可以应用于软件工程的其他方面。外观模式(Facade)是一种结构型设计模式,它为一个复杂的子系统提供了一个简单的接口。

摘要

外观模式为客户端提供了一个简单的接口,从而隐藏了子系统的复杂性。它通过减少客户端与子系统之间的耦合来提高系统的可维护性和可扩展性。在外观模式中,一个外观类(Facade)提供了一个简单的接口,隐藏了子系统的复杂性,客户端与子系统之间的交互都通过外观类来进行。

外观模式

概念

外观模式是一种结构型设计模式,它提供了一个统一的接口,用来访问系统中的一组接口。它隐藏了系统的复杂性,并将其封装在一个单一的类中,使得系统能够更加方便地使用。

在外观模式中,通常有一个外观类(Facade),它代表了系统中的一个子系统,并且封装了系统中的一组接口。客户端只需要调用外观类提供的接口,就能够完成其所需的功能,而无需了解子系统的内部实现。外观类简化了客户端与子系统之间的交互,提高了系统的可维护性和可扩展性。

结构

外观模式是一种结构型设计模式,它提供了一个统一的接口,以便于访问子系统中的一群接口。

外观模式包含以下几个角色:

  1. 外观(Facade):为客户端提供了一个简单的接口,客户端通过外观访问子系统中的一群接口。
  2. 子系统(Subsystem):实现了子系统的功能,处理由外观对象指派的任务。对于子系统内部的模块,外观不需要知道具体的实现方式。
  3. 客户端(Client):通过外观访问子系统中的一群接口,客户端可以直接调用外观提供的方法,而不需要了解子系统内部的实现细节。

如下是外观模式的UML类图:

外观模式的实现中,外观类的职责是将客户端和子系统解耦,客户端不需要了解子系统内部的实现细节,只需要知道如何使用外观类提供的接口即可。外观类对于客户端来说是一个黑盒子,客户端只需要知道如何使用即可。

应用场景

外观模式适用于以下场景:

  • 当一个系统有多个子系统,并且这些子系统之间互相合作以完成一个复杂的任务时;
  • 当客户端需要与系统交互,并且需要了解系统的内部结构和工作原理时;
  • 当需要简化一个复杂的系统,并且需要提供一个简单的接口时。

优缺点

优点:

外观模式的优点如下:

  • 简化了客户端与子系统之间的交互,减少了客户端的复杂性;
  • 隐藏了子系统的复杂性,提高了系统的可维护性和可扩展性;
  • 降低了客户端与子系统之间的耦合,提高了系统的灵活性和可移植性。

缺点:

外观模式的缺点如下:

  • 外观模式可能会导致系统的性能下降,因为客户端需要调用外观类来间接访问子系统;
  • 外观模式可能会使系统变得更加复杂,因为需要引入一个额外的外观类来封装子系统。

实现方式

外观模式的实现方式如下:

  • 定义一个外观类(Facade),它提供了一个简单的接口,隐藏了子系统的复杂性;
  • 外观类中包含子系统的实例变量,并且通过这些实例变量来与子系统进行交互;
  • 客户端只需要与外观类交互,并且不需要知道子系统的具体实现细节。

模式实现

下面是一个简单的外观模式的代码示例,它演示了如何使用外观模式来隐藏子系统的复杂性:

子系统A

java 复制代码
package com.example.javaDesignPattern.facade;

/**
 * @author bug菌
 * @version 1.0
 * @date 2023/9/19 15:56
 */
public class SubSystemA {
    public void methodA() {
        System.out.println("SubSystemA.methodA()");
    }
}

子系统B

java 复制代码
package com.example.javaDesignPattern.facade;

/**
 * @author bug菌
 * @version 1.0
 * @date 2023/9/19 15:59
 */
public class SubSystemB {
    public void methodB() {
        System.out.println("SubSystemB.methodB()");
    }
}

子系统C

java 复制代码
package com.example.javaDesignPattern.facade;

/**
 * @author bug菌
 * @version 1.0
 * @date 2023/9/19 16:00
 */
public class SubSystemC {
    public void methodC() {
        System.out.println("SubSystemC.methodC()");
    }
}

外观类

java 复制代码
package com.example.javaDesignPattern.facade;

/**
 * @author bug菌
 * @version 1.0
 * @date 2023/9/19 16:00
 */
public class Facade {
    private SubSystemA subSystemA;
    private SubSystemB subSystemB;
    private SubSystemC subSystemC;

    public Facade() {
        subSystemA = new SubSystemA();
        subSystemB = new SubSystemB();
        subSystemC = new SubSystemC();
    }

    public void method() {
        subSystemA.methodA();
        subSystemB.methodB();
        subSystemC.methodC();
    }
}

客户端

java 复制代码
package com.example.javaDesignPattern.facade;

/**
 * @author bug菌
 * @version 1.0
 * @date 2023/9/19 16:01
 */
public class Client {
    public static void main(String[] args) {
        Facade facade = new Facade();
        facade.method();
    }
}

在这个例子中,SubSystemASubSystemBSubSystemC是三个不同的子系统,它们各自完成各自的任务。Facade是一个外观类,它提供了一个简单的接口来隐藏子系统的复杂性。客户端只需要与Facade交互,并且不需要知道子系统的具体实现细节。

测试用例

为了测试外观模式的实现,我们可以编写以下测试用例:

java 复制代码
package com.example.javaDesignPattern.facade;

/**
 * @author bug菌
 * @version 1.0
 * @date 2023/9/19 16:01
 */
public class Client {
    public static void main(String[] args) {
        Facade facade = new Facade();
        facade.method();
    }
}

运行这个测试用例后,我们会发现输出了以下结果:

java 复制代码
SubSystemA.methodA()
SubSystemB.methodB()
SubSystemC.methodC()

这表明外观模式的实现是正确的。

执行截图如下:

示例代码解析

这段代码演示了外观模式(Facade Pattern)的使用,其中:

  • 客户端创建了一个 Facade 对象并调用它的 method 方法。
  • Facade 对象内部封装了多个子系统的功能接口,此处并未展示具体实现。
  • 客户端无需了解每个子系统的具体实现,只需要调用 Facade 的方法即可完成相关操作。

外观模式可以简化系统的复杂度,降低耦合度,使得客户端更容易使用和维护系统。

小结

外观模式是一种结构型设计模式,它为一个复杂的子系统提供了一个简单的接口。它通过减少客户端与子系统之间的耦合来提高系统的可维护性和可扩展性。在外观模式中,一个外观类(Facade)提供了一个简单的接口,隐藏了子系统的复杂性,客户端与子系统之间的交互都通过外观类来进行。

附录源码

如上涉及代码均已上传同步在GitHub,提供给同学们参考性学习。

总结

设计模式是一种通用的解决问题的方式,它可以应用于软件工程的各个方面。外观模式是一种结构型设计模式,它为一个复杂的子系统提供了一个简单的接口。在实际开发中,我们可以使用外观模式来简化系统的复杂性,提高系统的可维护性和可扩展性。

☀️建议/推荐你

如果想系统性的全面学习设计模式,建议小伙伴们直接毫无顾忌的关注这个专栏《聊设计模式》,无论你是想提升自己的编程技术,还是渴望更好地理解代码背后的设计思想,本专栏都会为你提供实用的知识和启发,帮助你更好地解决日常开发中的挑战,将代码变得更加优雅、灵活和可维护!

📣关于我

我是bug菌,CSDN | 掘金 | infoQ | 51CTO 等社区博客专家,历届博客之星Top30,掘金年度人气作者Top40,51CTO年度博主Top12,华为云 | 阿里云| 腾讯云等社区优质创作者,全网粉丝合计15w+ ;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板等海量资料。


相关推荐
s***P9827 小时前
Spring Boot实时推送技术详解:三个经典案例
spring boot·后端·状态模式
用户69371750013847 小时前
24.Kotlin 继承:调用超类实现 (super)
android·后端·kotlin
java干货7 小时前
优雅停机!Spring Boot 应用如何使用 Hook 线程完成“身后事”?
java·spring boot·后端
鹿里噜哩7 小时前
Spring Authorization Server 打造认证中心(三)自定义登录页
后端·架构
tealcwu7 小时前
【Unity技巧】实现在Play时自动保存当前场景
java·unity·游戏引擎
uup7 小时前
Java 多线程下的可见性问题
java
用户8307196840827 小时前
通过泛型限制集合只读或只写
java
云技纵横7 小时前
基于Redis键过期实现订单超时自动关闭:一套优雅的事件驱动方案
后端
Cache技术分享7 小时前
260. Java 集合 - 深入了解 HashSet 的内部结构
前端·后端