外观模式简介

外观模式定义
外观(Facade)模式是是一种软件设计模式,通过为多个复杂的子系统提供一个一致的高层接口,而使这些子系统更加容易使用,更加容易被访问。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。
外观模式的核心思想主要是通过创建一个外观类,将复杂系统的内部实现细节隐藏起来,只暴露出一个简化的接口给客户端。客户端只需要与外观类进行交互,而不需要直接与子系统的组件进行交互,从而达到想要的效果。

外观模式包含以下角色:

  1. 外观(Facade)角色:这是外观模式的核心部分,也被称为门面角色。外观类为多个子系统对外提供一个共同的接口,使得调用端能够更容易地与系统进行交互。通过外观类,调用端无需了解子系统的内部细节和复杂性,只需与外观类进行交互即可。
  2. 子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它。它们处理由外观类指派的任务,是系统功能的实际提供者。虽然子系统之间可能存在复杂的交互和依赖关系,但外观类为调用端屏蔽了这些复杂性,使得调用端能够以一种更简单、更直接的方式与系统进行交互。
  3. 客户(Client)角色:这是外观接口的调用者。调用者通过外观类与各个子系统交互,无需了解子系统的具体实现和细节。调用者只需要与外观类进行通信,即可实现所需的功能。

外观模式优缺点:
优点:

  1. 简化接口:外观模式为子系统提供了一个简化的接口,使得调用者无需关心子系统的内部细节和复杂性,降低了系统的学习成本和使用难度。
  2. 降低耦合度:通过引入外观类,子系统与调用者之间的耦合度得到了降低。外观类作为中间层,屏蔽了子系统的具体实现,使得子系统内部的修改不会影响到调用者。
  3. 提高灵活性:由于外观类提供了统一的接口,调用者可以更加灵活地使用子系统,而无需关心子系统的具体实现细节。这有助于增加系统的可扩展性和可维护性。
  4. 易于维护:当子系统内部发生变更时,只需要修改外观类即可,而无需修改所有调用者的代码。这大大降低了系统的维护成本。

缺点:

  1. 可能违背开闭原则:当需要添加新的子系统功能时,可能需要修改外观类或者增加新的外观类。这在一定程度上违背了开闭原则(即对扩展开放,对修改封闭),可能导致系统的稳定性和可维护性受到影响。
  2. 可能增加不必要的复杂性:在某些情况下,如果子系统本身就很简单或者调用者需要直接访问子系统的某些功能,引入外观模式可能会增加不必要的复杂性。

使用场景

  1. 当一个系统的复杂性变得很高,由于存在大量的子系统和相互关联的类,导致客户端代码变得冗长和复杂时,可以考虑使用外观模式。外观模式可以将复杂的系统进行封装,提供一个简化的接口给客户端,使得客户端代码更加清晰、易于理解和维护。
  2. 当客户端与多个子系统进行交互,而这些子系统之间存在复杂的依赖关系时,可以使用外观模式来简化客户端与子系统的交互过程。外观模式可以将这些复杂的依赖关系和交互逻辑封装在外观类中,客户端只需要与外观类进行交互,无需关心子系统之间的具体交互细节。
  3. 当需要向客户端隐藏底层实现细节,提供一个高层次的接口时,可以使用外观模式。外观模式可以屏蔽客户端与子系统之间的直接交互,通过外观类提供的简化接口来完成操作。

以下举一个外观模式的例子:
下面通过一个简单的例子来演示。假设有一个电脑系统,包含了多个子系统,如音乐功能、视频功能和联网功能

创建三个子系统类(Subsystem)-音乐功能、视频功能和联网功能

public class Music {public void open() {System.out.println("加载音乐");}public void stop() {System.out.println("关闭音乐");}}
public class Video {public void open() {System.out.println("打开视频");}public void stop() {System.out.println("关闭视频");}}
public class Internet {public void open() {System.out.println("连接网络");}public void stop() {System.out.println("断开网络");}}

创建外观类(Facade) – 电脑系统

public class Computer {private Music music;private Video video;private Internet internet;public Computer() {this.music = new Music();this.video = new Video();this.internet = new Internet();}public void openVideo() {internet.open();music.open();video.open();}public void stopVideo() {video.stop();music.stop();internet.stop();}}

创建客户端(Client)

public class Client {public static void main(String[] args) {Computer computer = new Computer();System.out.println("播放视频步骤:");// 播放视频computer.openVideo();System.out.println("关闭视频步骤:");// 关闭视频computer.stopVideo();}}

输出结果如下所示:

播放视频步骤:连接网络加载音乐打开视频关闭视频步骤:关闭视频关闭音乐断开网络

在上述例子中,音乐功能、视频功能和联网功能是子系统,Computer是外观类,封装了对这些子系统的调用,并提供了简化的接口给客户端。
在客户端中,我们使用外观模式简化了电脑系统的使用。通过调用外观类的方法,客户端无需直接与多个子系统交互,而是通过外观类来管理对子系统的调用。直接一个接口调用打开视频,打开音乐,连接网络功能

总而言之:
外观模式Facade封装了子系统外部和子系统内部多个模块的交互过程,从而简化了外部的调用。通过外观,子系统为外部提供一些高层的接口,以方便它们的使用。如果不使用外观模式,客户端通常需要和子系统内部的多个模块交互,也就是说客户端会和这些模块之间都有依赖关系,任意一个模块的变动都可能会引起客户端的变动。使用外观模式后,客户端只需要和外观类交互,即只和这个外观类有依赖关系,不需要再去关心子系统内部模块的变动情况了。这样一来,客户端不但简单,而且这个系统会更有弹性。

以上代码下载请点击该链接:https://github.com/Yarrow052/Java-package.git