外观模式

外观(Facade、门面)模式属于结构型模式的一种。

外观模式给客户端提供一个统一入口,并对外屏蔽内部子系统的调用细节。

外观模式通过为一组复杂的接口提供一个统一的高层接口,使得客户端与子系统之间的交互变得更加简单。外观模式旨在将客户端与多个复杂子系统的交互进行解耦,客户端无需了解子系统的内部实现细节,只需要通过外观类提供的接口与系统进行交互。

子系统类不会意识到外观的存在, 它们在系统内运作并且相互之间可直接进行交互。

如果我们想拥有某个功能,但是这个功能是在多个子系统中相互有交叉,我们并不想去改动子系统中代码。此时,我们就可以使用外观模式,建一个外观类,在外观类中去调用多个子系统中的方法,而我们使用时,只需调用外观类即可。

外观模式相当于一个中介。

我们经常说的网关Gateway,本质上也是一个Facade。

外观模式通常有以下组成部分:

  • 外观类(Facade):为复杂子系统提供一个简化的接口,客户端通过它与系统进行交互。
  • 子系统类(Subsystem):实现子系统的具体功能,但通常这些类不直接与客户端交互。
  • 客户端(Client):通过外观类与系统进行交互,不直接接触子系统。

假如我们有个复杂的观影系统,包括多个子系统(例如,DVD播放器、音响和投影仪)。我们通过外观模式来简化操作。

1、定义子系统类

// DVD 播放器
class DVDPlayer {
    public void on() {
        System.out.println("DVD Player is ON");
    }
    public void off() {
        System.out.println("DVD Player is OFF");
    }
    public void play() {
        System.out.println("DVD is playing");
    }
    public void stop() {
        System.out.println("DVD is stopped");
    }
}

// 音响系统
class SoundSystem {
    public void on() {
        System.out.println("Sound system is ON");
    }
    public void off() {
        System.out.println("Sound system is OFF");
    }
    public void setVolume(int level) {
        System.out.println("Setting sound volume to " + level);
    }
}

// 投影仪
class Projector {
    public void on() {
        System.out.println("Projector is ON");
    }
    public void off() {
        System.out.println("Projector is OFF");
    }
    public void focus() {
        System.out.println("Projector is focused");
    }
}

2、创建外观类

class HomeTheaterFacade {
    private DVDPlayer dvdPlayer;
    private SoundSystem soundSystem;
    private Projector projector;

    public HomeTheaterFacade(DVDPlayer dvd, SoundSystem sound, Projector proj) {
        this.dvdPlayer = dvd;
        this.soundSystem = sound;
        this.projector = proj;
    }

    public void watchMovie() {
        System.out.println("Get ready to watch a movie...");
        projector.on();
        projector.focus();
        soundSystem.on();
        soundSystem.setVolume(5);
        dvdPlayer.on();
        dvdPlayer.play();
    }

    public void endMovie() {
        System.out.println("Shutting down the movie theater...");
        dvdPlayer.stop();
        dvdPlayer.off();
        soundSystem.off();
        projector.off();
    }
}

3、客户端

public class Client {
    public static void main(String[] args) {
        // 创建子系统
        DVDPlayer dvd = new DVDPlayer();
        SoundSystem sound = new SoundSystem();
        Projector projector = new Projector();
        
        // 创建外观类
        HomeTheaterFacade homeTheater = new HomeTheaterFacade(dvd, sound, projector);
        
        // 客户端通过外观类进行操作
        homeTheater.watchMovie();
        System.out.println("\n--- Movie is Over ---\n");
        homeTheater.endMovie();
    }
}

外观模式的优缺点

优点:

  • 简化调用:外观模式通过提供一个统一的接口,简化了与复杂系统的交互。
  • 减少依赖:客户端代码无需知道子系统的内部细节,降低了系统之间的耦合度。
  • 提高可维护性:如果子系统的内部实现发生变化,只要外观类保持不变,客户端代码不需要进行修改。

缺点:

  • 外观类可能成为与程序中所有类都耦合的对象。

使用外观模式时,客户端不需要关心子系统的具体实现,而是通过外观类来简化操作,提高了系统的可维护性和灵活性。

欲让其亡,先令其狂。-- 烟沙九洲

 
 
posted @ 2024-11-27 23:46  烟沙九洲  阅读(15)  评论(0编辑  收藏  举报  来源