23种设计模式-外观(Facade)设计模式

发布于:2024-11-28 ⋅ 阅读:(8) ⋅ 点赞:(0)


类图: 外观设计模式类图

一.什么是外观设计模式?

外观设计模式(Facade Pattern)是一种结构型设计模式,通过为子系统中的一组接口提供一个一致的外部接口,简化客户端的使用。它将复杂的子系统封装起来,向客户端提供一个统一的、简单的访问方式。
核心思想:为子系统创建一个高级接口,隐藏其复杂性,让客户端与子系统交互变得简单。

二.外观设计模式的特点

  • 简化客户端接口:通过统一的外观类减少直接访问复杂子系统的需求。
  • 解耦性:客户端与子系统之间通过外观类交互,从而降低了耦合度。
  • 灵活性:在不改变子系统的前提下,可以随时调整外观类的功能。

三.外观设计模式的结构

  • Facade(外观类):为客户端提供统一接口,协调子系统的功能。
  • Subsystems(子系统):一组复杂的子系统,执行实际的业务逻辑,对外部隐藏实现细节。
  • Client(客户端):通过外观类调用子系统功能,而无需直接与子系统交互。
    在这里插入图片描述

四.外观设计模式的优缺点

  • 优点:
    • 降低客户端与子系统之间的耦合性。
    • 提高代码可读性和易用性,简化复杂子系统的调用过程。
    • 为系统增加新的外观类而不会影响子系统代码。
  • 缺点:
    • 外观类可能成为“上帝类”,过多依赖外观类可能导致其职责过于繁重。
    • 增加系统复杂性:如果过度设计外观层,可能导致代码冗余。

五.外观设计模式的 C++ 实现

 以下代码展示一个家庭影院系统的例子,外观类 HomeTheaterFacade 将隐藏复杂的子系统操作。

#include <iostream>
#include <string>
using namespace std;

// 子系统1:音响系统
class SoundSystem {
public:
    void On() { cout << "Sound System: On\n"; }
    void Off() { cout << "Sound System: Off\n"; }
    void SetVolume(int level) { cout << "Sound System: Volume set to " << level << endl; }
};

// 子系统2:投影仪
class Projector {
public:
    void On() { cout << "Projector: On\n"; }
    void Off() { cout << "Projector: Off\n"; }
    void SetInput(const string& input) { cout << "Projector: Input set to " << input << endl; }
};

// 子系统3:播放器
class MediaPlayer {
public:
    void On() { cout << "Media Player: On\n"; }
    void Off() { cout << "Media Player: Off\n"; }
    void Play(const string& movie) { cout << "Media Player: Playing movie \"" << movie << "\"\n"; }
    void Stop() { cout << "Media Player: Stopped\n"; }
};

// 外观类:家庭影院
class HomeTheaterFacade {
private:
    SoundSystem sound;
    Projector projector;
    MediaPlayer player;

public:
    void WatchMovie(const string& movie) {
        cout << "Setting up movie theater...\n";
        sound.On();
        sound.SetVolume(10);
        projector.On();
        projector.SetInput("HDMI");
        player.On();
        player.Play(movie);
        cout << "Movie is ready to watch!\n";
    }

    void EndMovie() {
        cout << "Shutting down movie theater...\n";
        player.Stop();
        player.Off();
        projector.Off();
        sound.Off();
        cout << "Goodbye!\n";
    }
};

// 主函数
int main() {
    HomeTheaterFacade homeTheater;
    homeTheater.WatchMovie("Inception");
    homeTheater.EndMovie();
    return 0;
}

六.外观设计模式的 JAVA 实现

// 子系统1:音响系统
class SoundSystem {
    public void on() {
        System.out.println("Sound System: On");
    }

    public void off() {
        System.out.println("Sound System: Off");
    }

    public void setVolume(int level) {
        System.out.println("Sound System: Volume set to " + level);
    }
}

// 子系统2:投影仪
class Projector {
    public void on() {
        System.out.println("Projector: On");
    }

    public void off() {
        System.out.println("Projector: Off");
    }

    public void setInput(String input) {
        System.out.println("Projector: Input set to " + input);
    }
}

// 子系统3:播放器
class MediaPlayer {
    public void on() {
        System.out.println("Media Player: On");
    }

    public void off() {
        System.out.println("Media Player: Off");
    }

    public void play(String movie) {
        System.out.println("Media Player: Playing movie \"" + movie + "\"");
    }

    public void stop() {
        System.out.println("Media Player: Stopped");
    }
}

// 外观类:家庭影院
class HomeTheaterFacade {
    private SoundSystem sound = new SoundSystem();
    private Projector projector = new Projector();
    private MediaPlayer player = new MediaPlayer();

    public void watchMovie(String movie) {
        System.out.println("Setting up movie theater...");
        sound.on();
        sound.setVolume(10);
        projector.on();
        projector.setInput("HDMI");
        player.on();
        player.play(movie);
        System.out.println("Movie is ready to watch!");
    }

    public void endMovie() {
        System.out.println("Shutting down movie theater...");
        player.stop();
        player.off();
        projector.off();
        sound.off();
        System.out.println("Goodbye!");
    }
}

// 主函数
public class FacadePatternDemo {
    public static void main(String[] args) {
        HomeTheaterFacade homeTheater = new HomeTheaterFacade();
        homeTheater.watchMovie("Inception");
        homeTheater.endMovie();
    }
}

七.代码解析

  • 子系统
    • SoundSystem:控制音响的开关和音量。
    • Projector:负责控制投影仪的开关和输入源。
    • MediaPlayer:负责播放和停止电影。
  • 外观类 HomeTheaterFacade
    • 通过组合子系统对象来封装复杂逻辑。
    • 提供了两个高层次接口:WatchMovie 和 EndMovie,分别用于启动和关闭家庭影院。
  • 客户端
    • 客户端直接调用外观类的方法,无需了解子系统的具体操作流程。

八.总结

 外观模式通过封装复杂子系统的调用细节,为客户端提供了简单易用的接口。它在需要对复杂系统进行高层次封装时非常有用,但要注意外观类的职责划分,避免其承担过多功能而导致维护困难。
应用场景:

  • 跨平台开发:隐藏不同平台的底层实现,为上层应用提供一致接口。
  • 第三方库封装:通过外观类封装复杂的库调用,使得库更易用。
  • 复杂系统简化:将多个模块组合起来,为外部提供一个简单接口。