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

举报
bug菌 发表于 2023/09/25 18:05:32 2023/09/25
【摘要】 外观模式为客户端提供了一个简单的接口,从而隐藏了子系统的复杂性。它通过减少客户端与子系统之间的耦合来提高系统的可维护性和可扩展性。在外观模式中,一个外观类(Facade)提供了一个简单的接口,隐藏了子系统的复杂性,客户端与子系统之间的交互都通过外观类来进行。


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


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

前言

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

摘要

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

外观模式

概念

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

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

结构

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

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

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

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

image.png

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

应用场景

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

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

优缺点

优点:

外观模式的优点如下:

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

缺点:

外观模式的缺点如下:

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

实现方式

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

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

模式实现

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

子系统A

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

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

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()");
    }
}

外观类

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();
    }
}

客户端


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交互,并且不需要知道子系统的具体实现细节。

测试用例

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

public class Client {
    public static void main(String[] args) {
        Facade facade = new Facade();
        facade.method();
    }
}

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

SubSystemA.methodA()
SubSystemB.methodB()
SubSystemC.methodC()

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

执行截图如下:

image.png

代码解析

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

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

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

小结

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

附录源码

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

总结

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

☀️建议/推荐你


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

  最后,如果这篇文章对你有所帮助,帮忙给作者来个一键三连,关注、点赞、收藏,您的支持就是我坚持写作最大的动力。

  同时欢迎大家关注公众号:「猿圈奇妙屋」 ,以便学习更多同类型的技术文章,免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板、技术文章Markdown文档等海量资料。

📣关于我

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


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。