Skip to content

外观模式

外观模式(Facade Pattern)是一种结构型设计模式,它为复杂的子系统提供了一个统一的接口,使得这个子系统的使用变得更加容易。外观模式并不打算给所有类提供一个简化接口,而是为那些需要简化交互过程的特定任务或用户案例提供一个高层次的接口。

通过引入外观类,外观模式帮助隐藏了系统的复杂性,并且提供了更简单、更高层次的接口来与这些系统进行交互。这不仅减少了客户端代码的复杂度,还提高了代码的可读性和可维护性。

外观模式的主要角色

  1. Facade(外观角色):为调用者提供一个简化的接口,隐藏内部子系统的复杂性。
  2. SubSystem Classes(子系统类):实现子系统的功能,处理 Facade 对象的请求。
  3. Client(客户角色):通过 Facade 访问子系统功能,不需要直接与复杂的子系统交互。

在 JavaScript 中的实现

下面是一个简单的例子来说明如何在 JavaScript 中使用外观模式:

示例:家庭影院系统

假设你有一个家庭影院系统,包含多个组件如 DVD 播放器、投影仪、音响系统等。为了观看电影,你需要按顺序操作每个组件。使用外观模式可以大大简化这个过程。

javascript
// 子系统类
class DvdPlayer {
  on() {
    console.log("DvdPlayer is ON");
  }
  play(movie) {
    console.log(`Playing movie: ${movie}`);
  }
}

class Projector {
  on() {
    console.log("Projector is ON");
  }
  setInput(input) {
    console.log(`Setting projector input to: ${input}`);
  }
}

class SoundSystem {
  on() {
    console.log("SoundSystem is ON");
  }
  setVolume(volume) {
    console.log(`Setting volume to: ${volume}`);
  }
}

// 外观角色
class HomeTheaterFacade {
  constructor(dvd, projector, soundSystem) {
    this.dvdPlayer = dvd;
    this.projector = projector;
    this.soundSystem = soundSystem;
  }

  watchMovie(movie) {
    console.log("Preparing home theater...");
    this.dvdPlayer.on();
    this.dvdPlayer.play(movie);
    this.projector.on();
    this.projector.setInput("DVD");
    this.soundSystem.on();
    this.soundSystem.setVolume(10);
    console.log("Enjoy your movie!");
  }

  endMovie() {
    console.log("Shutting down home theater...");
    // Here you can add logic to turn off the systems or perform other shutdown tasks.
    console.log("Home theater is shut down.");
  }
}

// 客户端代码
const dvdPlayer = new DvdPlayer();
const projector = new Projector();
const soundSystem = new SoundSystem();

const homeTheater = new HomeTheaterFacade(dvdPlayer, projector, soundSystem);

homeTheater.watchMovie("Inception");
// 输出:
// Preparing home theater...
// DvdPlayer is ON
// Playing movie: Inception
// Projector is ON
// Setting projector input to: DVD
// SoundSystem is ON
// Setting volume to: 10
// Enjoy your movie!

homeTheater.endMovie();
// 输出:
// Shutting down home theater...
// Home theater is shut down.

代码解释

  • 子系统类DvdPlayer, Projector, 和 SoundSystem 分别代表了家庭影院系统的不同部分。每个类都有自己的方法来控制其行为。
  • 外观角色HomeTheaterFacade 类提供了 watchMovieendMovie 方法,简化了启动和关闭家庭影院的过程。它负责调用各个子系统的方法,但对外部隐藏了这些细节。
  • 客户端代码:只需要与 HomeTheaterFacade 交互,而不需要知道具体子系统的操作细节。

应用场景

外观模式适用于以下几种情况:

  • 当你需要为复杂的子系统提供一个简单的接口时。
  • 当你需要将子系统的实现细节与高层接口分离时,以便于维护或更新子系统而不影响客户端代码。
  • 当你希望减少系统之间的依赖关系,提高模块间的独立性时。

通过使用外观模式,可以使系统更加易于使用,同时保持良好的结构和清晰的设计。这对于大型系统或者集成第三方库来说尤为重要。

Released under the MIT License.