外观模式 (Facade Pattern)

外观模式 (Facade Pattern)

外观模式是一种 结构型设计模式,通过为子系统中的一组接口提供一个统一的高层接口,简化了子系统的使用,让复杂系统更易于访问。


原理

  1. 核心思想
    • 提供一个 统一的接口 来访问子系统中的多个接口,从而简化客户端与复杂子系统的交互。
    • 客户端只需与外观接口交互,避免直接接触子系统的复杂实现细节。
  2. 适用场景
    • 需要简化复杂系统的访问。
    • 希望子系统能够被独立使用,同时也需要一个简化的入口。
  3. 参与角色
    • Facade(外观类):为客户端提供简化的高层接口。
    • Subsystems(子系统):实现系统的实际功能,可以被外观类调用,但对子系统的调用是透明的。
    • Client(客户端):通过外观类访问子系统。

优点

  1. 简化接口:降低客户端与子系统之间的耦合性。
  2. 松散耦合:客户端无需直接依赖子系统,从而更容易维护和扩展。
  3. 更好的层次划分:为复杂系统提供一个清晰的结构。

缺点

  1. 可能导致额外的封装:如果外观类的设计不够好,可能导致新的复杂性。
  2. 单一职责问题:外观类可能成为上帝类,承担过多的职责。

示例代码

场景描述

假设有一个 家庭影院系统,包含多个子系统:投影仪、音响、DVD播放器。我们希望通过一个简化的接口来启动和关闭家庭影院,而不需要逐个操作每个子系统。


1. 定义子系统类
java 复制代码
// 投影仪子系统
public class Projector {
    public void on() {
        System.out.println("Projector is ON");
    }

    public void off() {
        System.out.println("Projector is OFF");
    }
}

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

    public void off() {
        System.out.println("Sound System is OFF");
    }
}

// DVD播放器子系统
public class DVDPlayer {
    public void play() {
        System.out.println("DVD Player is PLAYING");
    }

    public void stop() {
        System.out.println("DVD Player has STOPPED");
    }
}

2. 创建外观类
java 复制代码
// 外观类:家庭影院控制器
public class HomeTheaterFacade {
    private Projector projector;
    private SoundSystem soundSystem;
    private DVDPlayer dvdPlayer;

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

    // 启动家庭影院
    public void startMovie() {
        System.out.println("Starting Home Theater...");
        projector.on();
        soundSystem.on();
        dvdPlayer.play();
    }

    // 关闭家庭影院
    public void stopMovie() {
        System.out.println("Stopping Home Theater...");
        dvdPlayer.stop();
        soundSystem.off();
        projector.off();
    }
}

3. 客户端代码
java 复制代码
public class FacadePatternExample {
    public static void main(String[] args) {
        // 创建子系统对象
        Projector projector = new Projector();
        SoundSystem soundSystem = new SoundSystem();
        DVDPlayer dvdPlayer = new DVDPlayer();

        // 创建外观对象
        HomeTheaterFacade homeTheater = new HomeTheaterFacade(projector, soundSystem, dvdPlayer);

        // 使用外观类操作子系统
        homeTheater.startMovie(); // 启动家庭影院
        homeTheater.stopMovie();  // 关闭家庭影院
    }
}

输出结果
text 复制代码
Starting Home Theater...
Projector is ON
Sound System is ON
DVD Player is PLAYING
Stopping Home Theater...
DVD Player has STOPPED
Sound System is OFF
Projector is OFF

UML 类图

复制代码
         +---------------------+
         |   HomeTheaterFacade  |
         +---------------------+
         | + startMovie()      |
         | + stopMovie()       |
         +---------------------+
               /     |     \
              /      |      \
   +-------------+ +-------------+ +-------------+
   |  Projector  | | SoundSystem | |  DVDPlayer  |
   +-------------+ +-------------+ +-------------+
   | + on()      | | + on()      | | + play()    |
   | + off()     | | + off()     | | + stop()    |
   +-------------+ +-------------+ +-------------+

使用场景

  1. 复杂系统的统一入口:如数据库访问、网络通信等。
  2. 模块间的解耦:简化子系统对外暴露的接口,降低耦合性。
  3. 提供默认行为:如框架中预定义的工具类。

小结

  • 外观模式通过引入外观类,降低了客户端对复杂子系统的依赖,增强了系统的模块化。
  • 它适合用于封装复杂系统,同时保持子系统的灵活性。
  • 需要注意外观类的职责划分,避免其成为"上帝类"。
相关推荐
爱笑的源码基地21 分钟前
一款全开源的信创云PACS影像云平台解决方案,支持多模态医学影像处理(CT/MR/DR/超声/病理等)
java·源码·国产化·pacs·云影像·区域pacs
我命由我1234538 分钟前
Android 开发问题:ClickableSpan 的点击事件没有生效
java·java-ee·android studio·android jetpack·android-studio·android runtime
万亿少女的梦1681 小时前
基于Python的高考志愿填报辅助系统设计与实现
java·spring boot·python·mysql·vue
微信开发api-视频号协议1 小时前
企业微信外部群开发自动化实践过程
java·前端·微信·自动化·企业微信·ipad
犀利豆2 小时前
#AI in Harness(一)
java·ai编程
极***涯2 小时前
深度拆解:多源BFS路径重构难题——跳出单层遍历误区,搞定高阶最短路径全量解
java·重构·宽度优先
YuK.W3 小时前
Leetcode100: 70.爬楼梯、118.杨辉三角、198.打家劫舍
java·算法·leetcode
这不小天嘛3 小时前
JAVA八股——redis篇
java·开发语言·redis
聚美智数5 小时前
黄历查询-运势查询-国际法定节假日查询-API接口介绍
android·java·数据库
Yeats_Liao7 小时前
18:JavaBean简介及其在表单处理与DAO设计模式中的应用-Java Web
java·后端·架构