当前位置: 首页 > news >正文

23种设计模式之【外观模式】-核心原理与 Java实践

文章目录

  • 外观模式(Facade Pattern)
  • 核心原理
  • Java 实践示例
  • 外观模式的特点
  • 外观模式的应用场景

外观模式(Facade Pattern)

外观模式是 23 种设计模式中的一种结构型模式,其核心思想是为复杂系统中的一组接口提供一个统一的高层接口,使子系统更易于使用。这种模式通过引入一个 “外观类”,封装子系统的复杂性,为客户端提供简单直观的访问入口,从而降低客户端与子系统之间的耦合度。

核心原理

外观角色(Facade)
提供一个统一的接口,封装子系统的复杂交互逻辑
客户端通过外观类访问子系统,无需直接与子系统交互
子系统角色(Subsystem)
由多个相关联的类组成,实现子系统的具体功能
对子系统而言,外观类只是另一个客户端,不影响子系统内部结构
客户端(Client)
通过外观类与子系统交互,无需了解子系统的内部实现
简化了与复杂系统的交互过程

外观模式的核心是 “封装复杂性,提供简化接口”,遵循 “最少知识原则”(迪米特原则),减少客户端需要了解的类和方法数量。

Java 实践示例

以 “家庭影院系统” 为例实现外观模式:
家庭影院包含多个设备(投影仪、音响、播放器、灯光等)
观看电影需要协调多个设备的操作(开投影仪、开音响、关灯光等)
外观类封装这些复杂操作,提供 “一键观影” 的简化接口

package com.example.demo;public class FacadePattern {public static void main(String[] args) {// 创建子系统组件Projector projector = new Projector();SoundSystem soundSystem = new SoundSystem();Player player = new Player();Light light = new Light();// 创建外观类HomeTheaterFacade theaterFacade = new HomeTheaterFacade(projector, soundSystem, player, light);System.out.println("=== 准备观看电影 ===");theaterFacade.watchMovie("星际穿越");System.out.println("\n=== 电影结束 ===");theaterFacade.endMovie();}// 子系统:投影仪public static class Projector {public void on() {System.out.println("投影仪已开启");}public void off() {System.out.println("投影仪已关闭");}public void setInput(String source) {System.out.println("投影仪输入源设置为:" + source);}public void zoomIn() {System.out.println("投影仪画面放大");}}// 子系统:音响系统public static class SoundSystem {public void on() {System.out.println("音响系统已开启");}public void off() {System.out.println("音响系统已关闭");}public void setVolume(int level) {System.out.println("音响音量设置为:" + level);}}// 子系统:播放器public static class Player {public void on() {System.out.println("播放器已开启");}public void off() {System.out.println("播放器已关闭");}public void play(String movie) {System.out.println("正在播放电影:" + movie);}public void stop() {System.out.println("电影播放已停止");}}// 子系统:灯光public static class Light {public void dim(int level) {System.out.println("灯光调暗至:" + level + "%");}public void on() {System.out.println("灯光已打开");}}// 外观类:家庭影院外观public static class HomeTheaterFacade {// 持有子系统组件的引用private Projector projector;private SoundSystem soundSystem;private Player player;private Light light;// 通过构造函数注入子系统组件public HomeTheaterFacade(Projector projector, SoundSystem soundSystem,Player player, Light light) {this.projector = projector;this.soundSystem = soundSystem;this.player = player;this.light = light;}// 封装观看电影的复杂流程public void watchMovie(String movie) {System.out.println("准备观看电影...");light.dim(20);          // 调暗灯光projector.on();         // 打开投影仪projector.setInput("播放器"); // 设置输入源projector.zoomIn();     // 放大画面soundSystem.on();       // 打开音响soundSystem.setVolume(8); // 设置音量player.on();            // 打开播放器player.play(movie);     // 播放电影}// 封装结束电影的复杂流程public void endMovie() {System.out.println("结束电影...");light.on();             // 打开灯光projector.off();        // 关闭投影仪soundSystem.off();      // 关闭音响player.stop();          // 停止播放player.off();           // 关闭播放器}}//=== 准备观看电影 ===//准备观看电影...//灯光调暗至:20%//投影仪已开启//投影仪输入源设置为:播放器//投影仪画面放大//音响系统已开启//音响音量设置为:8//播放器已开启//正在播放电影:星际穿越////=== 电影结束 ===//结束电影...//灯光已打开//投影仪已关闭//音响系统已关闭//电影播放已停止//播放器已关闭
}

外观模式的特点

优点:
简化接口:为复杂子系统提供简单统一的访问接口,降低使用难度
解耦客户端与子系统:客户端无需了解子系统内部结构,减少耦合
提高灵活性:子系统内部变化时,只需调整外观类,不影响客户端
符合迪米特原则:客户端只需与外观类交互,减少与其他类的通信
缺点:
外观类可能成为 “上帝对象”,承担过多职责
新增子系统功能时,可能需要修改外观类,违反开闭原则
与适配器模式的区别:
外观模式:为复杂系统提供简化接口,不改变原有接口
适配器模式:将一个接口转换为另一个接口,解决接口不兼容问题

外观模式的应用场景

复杂系统简化:
当系统包含多个子模块,且模块间交互复杂时
例如:电商平台的下单流程(涉及库存、支付、物流等子系统)
框架封装:
框架为开发者提供简化接口,隐藏内部实现细节
例如:Spring 的JdbcTemplate封装了复杂的 JDBC 操作
例如:MyBatis 的SqlSession封装了数据库访问的复杂逻辑
遗留系统集成:
为老旧系统提供新的外观接口,便于与新系统集成
避免直接修改遗留系统代码,降低风险
分层架构中的层间交互:
在分层架构中,每层可为上层提供外观接口
例如:服务层为控制层提供外观接口,封装多个 DAO 的交互

外观模式是 “封装复杂性” 的典型实现,在框架设计和系统集成中应用广泛。它通过提供简洁接口,降低了系统的使用门槛,同时隔离了客户端与子系统的直接依赖,提高了系统的可维护性。

http://www.dtcms.com/a/394215.html

相关文章:

  • 第4章:构建自己的物料解决方案
  • 华为昇腾 950 系列芯片深度解析
  • 2025华为杯 C题围岩裂隙精准识别与三维模型重构保姆级教程思路分析【国奖版】
  • 搭建Electron桌面项目
  • Linux 线程之pthread库
  • 内存泄漏、内存溢出与内存访问越界
  • C++初阶(11)string类的模拟实现
  • Python快速入门专业版(三十九):Python集合:去重与集合运算(交集、并集、差集)
  • pytorch 中meshgrid()函数详解
  • 深度探秘GAIA:一个为下一代AI量身打造的挑战性基准
  • 今日分享C++ ---继承
  • TableGPT:浙江大学发布的表格大模型
  • Linux 概述
  • 领码学堂·定时任务新思维[二]——七大替代方案总览:场景、优缺点与快速选型
  • NLP:详解FastText
  • 【力扣】hot100系列(一)哈希部分解析(多解法+时间复杂度分析)
  • 用AI开发HTML双语阅读工具助力英语阅读
  • AI论文速读 | 当大语言模型遇上时间序列:大语言模型能否执行多步时间序列推理与推断
  • 如何使用升腾C92主机搭建本地Linux编译服务器并通过Windows映射访问共享目录
  • 测试DuckDB-rs项目中的示例程序
  • 分布式协议与算法实战-实战篇
  • 【硬件-笔试面试题-105】硬件/电子工程师,笔试面试题(知识点:详细讲讲什么是链表和数组)
  • 【获取地址栏的搜索关键字】功能-总结
  • 关于__sync_bool_compare_and_swap的使用及在多核多线程下使用时的思考
  • 【嵌入式简单外设篇】-433MHz 无线遥控模块
  • 计算机视觉(opencv)实战三十——摄像头实时风格迁移,附多种风格转换
  • 【数据分享】《中国农村统计年鉴》(1985-2024年)全pdf和excel
  • 2025年中国研究生数学建模竞赛“华为杯”C题 围岩裂隙精准识别与三维模型重构完整高质量成品 思路 代码 结果分享!全网首发!
  • [Linux]文件与 fd
  • FFmpeg 深入精讲(二)FFmpeg 初级开发