Java学习-------外观模式

        在软件开发中,随着系统的不断迭代,模块会越来越多,模块之间的依赖关系也会变得错综复杂。这不仅会增加开发难度,还会让系统的维护和扩展变得棘手。而外观模式就像一位 “前台接待员”,为复杂的系统提供一个简洁统一的接口,让外部与系统的交互变得简单高效。。​

        外观模式是设计模式三大类中的一种结构型设计模式,它为子系统中的一组接口提供一个统一的高层接口,使得子系统更容易被使用。简单来说,就是在复杂的子系统外面套上一个 “壳”,这个 “壳” 封装了子系统内部的复杂逻辑和交互细节,外部只需与这个 “壳” 进行交互,无需关心子系统内部的具体实现。​例如,我们使用电脑时,只需按下开机键,电脑就会完成主板通电、CPU 启动、内存加载系统等一系列复杂操作,而我们无需了解这些内部步骤,这里的 “开机键” 就相当于外观模式中的统一接口。​

        外观模式的核心原理是封装与委派。它通过引入一个外观类(Facade),将子系统中各个模块的接口进行整合和封装。当外部客户端需要调用子系统的功能时,不需要直接与子系统中的各个模块交互,而是调用外观类提供的接口,外观类再将请求委派给子系统中相应的模块进行处理。​其基本结构包含以下几个部分:​

(1)外观类:这是外观模式的核心,它知道子系统中各个模块的功能,为客户端提供统一的接口,负责将客户端的请求转发给合适的子系统模块。​

(2)子系统模块:实现子系统的具体功能,它们不知道外观类的存在,也不与外观类进行交互,仅在接收到外观类的委派请求时执行相应操作。​

(3)客户端:通过外观类与子系统进行交互,无需了解子系统内部的复杂结构。​

        外观模式在软件开发中有着重要的作用,主要体现在以下几个方面:​

(1)简化接口调用:客户端无需记住子系统中众多模块的接口,只需与外观类的统一接口交互,大大降低了客户端使用子系统的难度。​

(2)降低耦合度:外观类将客户端与子系统隔离开来,使得客户端与子系统之间的依赖关系变为客户端与外观类之间的依赖,减少了系统的耦合度,便于后续的维护和扩展。​

(3)隐藏子系统细节:子系统内部的实现细节对客户端是透明的,客户端不需要知道子系统是如何工作的,只需关注外观类提供的功能是否满足需求。​

(4)便于子系统的管理:当子系统内部发生变化时,只要外观类的接口保持不变,客户端就不需要做任何修改,降低了因子系统变化对客户端造成的影响。​

        作为一种设计模式,外观模式带来了许多优点,例如:

(1)提高易用性:为复杂的子系统提供了简单易用的接口,让客户端能够快速上手使用子系统,减少了学习成本。​

(2)降低耦合度:将客户端与子系统的直接交互转变为与外观类的交互,降低了两者之间的耦合,符合 “迪米特法则”(最少知识原则)。​

(3)增强系统灵活性:子系统内部的模块可以自由修改和扩展,只要不影响外观类的接口,就不会对客户端产生影响,提高了系统的灵活性。​

(4)便于维护:由于客户端与子系统之间通过外观类进行交互,当子系统出现问题时,只需排查外观类与子系统之间的交互,缩小了问题排查的范围,便于系统的维护。​

        但同时,其也有各种各样的缺点,如:

(1)引入冗余:如果客户端需要使用子系统中一些较为特殊的功能,而外观类没有提供相应的接口,客户端可能还是需要直接与子系统交互,这时候外观模式就显得有些冗余。​

(2)外观类可能变得复杂:随着子系统功能的不断增加,外观类需要整合的接口也会越来越多,可能会导致外观类变得庞大而复杂,增加了外观类的维护难度。​

(3)限制了客户端的灵活性:外观类提供的是统一的接口,可能无法满足客户端的个性化需求,客户端不能像直接与子系统交互那样灵活地使用子系统的功能。​

        下面通过一个家庭影院的例子来演示外观模式的实现。

        一个家庭影院包含投影仪、音响、播放器等设备,要观看电影需要依次开启这些设备并进行相应设置,操作较为复杂。我们可以使用外观模式,创建一个家庭影院外观类来简化这些操作。​

        

// 子模块类
// 投影仪
class Projector {public void on() {System.out.println("投影仪开启");}public void off() {System.out.println("投影仪关闭");}public void setMode() {System.out.println("投影仪设置为电影模式");}
}// 音响
class SoundSystem {public void on() {System.out.println("音响开启");}public void off() {System.out.println("音响关闭");}public void setVolume(int volume) {System.out.println("音响音量设置为:" + volume);}
}// 播放器
class Player {public void on() {System.out.println("播放器开启");}public void off() {System.out.println("播放器关闭");}public void play() {System.out.println("播放器开始播放电影");}
}
// 外观类
// 家庭影院
class HomeTheaterFacade {private Projector projector;private SoundSystem soundSystem;private Player player;public HomeTheaterFacade(Projector projector, SoundSystem soundSystem, Player player) {this.projector = projector;this.soundSystem = soundSystem;this.player = player;}// 观看电影的统一接口public void watchMovie() {System.out.println("准备观看电影...");projector.on();projector.setMode();soundSystem.on();soundSystem.setVolume(8);player.on();player.play();System.out.println("电影开始播放");}// 结束观看电影的统一接口public void endMovie() {System.out.println("电影结束,关闭设备...");player.off();soundSystem.off();projector.off();System.out.println("所有设备已关闭");}
}
// 客户端
public class Client {public static void main(String[] args) {// 创建子系统对象Projector projector = new Projector();SoundSystem soundSystem = new SoundSystem();Player player = new Player();// 创建外观类对象HomeTheaterFacade homeTheater = new HomeTheaterFacade(projector, soundSystem, player);// 通过外观类接口观看电影homeTheater.watchMovie();// 电影结束,关闭设备homeTheater.endMovie();}
}

        其运行结果大致为:

准备观看电影...
投影仪开启
投影仪设置为电影模式
音响开启
音响音量设置为:8
播放器开启
播放器开始播放电影
电影开始播放
电影结束,关闭设备...
播放器关闭
音响关闭
投影仪关闭
所有设备已关闭

        从代码和运行结果可以看出,客户端只需调用家庭影院外观类的watchMovie和endMovie方法,就可以完成观看电影的一系列复杂操作,无需直接与投影仪、音响、播放器等子系统模块交互,大大简化了客户端的操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/93815.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/93815.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go语言-->变量

Go语言–>变量 在 Go 语言中,定义变量有几种常见的方式。下面是一些常见的语法和用法: 1. 使用 var 关键字定义变量 最常见的方式是使用 var 关键字,后面跟上变量名和类型。你也可以为变量赋初值。 基本格式: var variableName…

分布式链路追踪的实现原理

分布式链路追踪系统的实现涉及多个核心技术环节,下面我将从数据采集、上下文传播、存储分析等维度深入解析其工作原理。 一、核心架构组件 1. 系统组成模块 #mermaid-svg-pDlZY54w2Z0Bp1H1 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-si…

Python爬虫实战:研究micawber库相关技术构建网页采集系统

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上的数据量呈现出爆炸式增长。如何从海量的网页数据中提取有价值的信息,成为了一个重要的研究课题。网络爬虫作为一种自动获取网页内容的技术,为解决这一问题提供了有效的手段。通过网络爬虫,可以快速、高效地采集…

前端框架Vue3(三)——路由和pinia

路由的理解 路由就是一组key-value的对应关系,多个路由,需要经过路由器的管理。 路由-基本切换效果 导航区、展示区请来路由器制定路由的具体规则(什么路径,对应着什么组件)形成一个一个的路由 【两个注意点】 路由组件…

【go】实现BMI计算小程序与GUI/WEB端实现

好的,下面是用 Go 语言实现的一个简单的 BMI(Body Mass Index,身体质量指数)计算器,包含中文注释与完整代码,可以直接运行。 一、BMI 计算公式 BMI体重(kg)身高2(m2&…

Windows系统优化命令-记录

闲着无聊,近来电脑有些卡顿,记录一下相关命令。最好的命令还是格式化╮(╯▽╰)╭ 1. 磁盘清理相关命令 cleanmgr - 磁盘清理工具 cleanmgr启动磁盘清理工具,可清理临时文件、回收站等内容 diskpart - 磁盘分区工具 diskpart用于磁盘管理&…

BFCP协议学习

BFCP是为了SIP呼叫中实现presentation的二进制协议。开源库libbfcp 如何协商角色 SIP 消息的SDP中有BFCP 的部分,其中s-only 代表要当服务器角色,c-only 代表要当client角色。confid, userid 都是需要在后续消息中对齐的。 通过port信息可以为后续bfcp…

常用设计模式系列(十七)—命令模式

常用设计模式系列(十七)—命令模式 第一节、前言 各位老铁好! 今天我来跟大家分享对象行为型模式第二章节——《命令模式》,“命令”一词,通俗易懂,我们在生活中经常会发出各种各样的命令,就像你…

【AI绘画】Stable Diffusion 全面指南:安装、版本对比、功能解析与高级应用

引言:Stable Diffusion 概述 在人工智能图像生成领域,商业工具如Midjourney凭借其集成化服务与高质量输出占据市场,而Stable Diffusion(简称SD)则以开源特性构建了差异化优势。与商业工具依赖云端资源、受限于订阅费用…

kafka使用kraft

window 使用kafka-storage生成生成一个uuid .\kafka-storage.bat random-uuid格式化存储 在这里插入代码片.\kafka-storage.bat format -t 对应的uuid D:\configure\fisher\kafka\config\kraft\server.properties 启动命令 .\kafka-server-start.bat D:\configure\fisher\kafka…

HCIA-Datacom认证笔记:IP路由基础——核心概念与路由分类

网络技术学习中,IP路由是绕不开的核心知识点,对于备考HCIA-Datacom认证的朋友来说,掌握路由基础能为后续学习打下良好基础。今天带朋友们梳理一下IP路由的核心概念、路由表结构及路由分类一、路由核心概念什么是路由? 简单来说&am…

FFmpeg 安装与使用

文章目录1. 环境部署(Windows)1.1. 安装包下载1.2. 配置环境变量1.3. 验证安装2. FFmpeg 基础使用教程2.1. 常用命令格式2.2. 基础功能示例2.2.1. 视频转码(MP4 → MKV)2.2.2. 调整分辨率(1080p → 480p)2.…

Python 数据分析(四):Pandas 进阶

目录 1. 概述2. 缺失项3. 分组聚合4. 数据合并5. 数据可视化 5.1 折线图5.2 条形图5.3 直方图5.4 散点图5.5 饼图 1. 概述 我们在上一篇文章初识 Pandas中已经对 Pandas 作了一些基本介绍,本文我们进一步来学习 Pandas 的一些使用。 2. 缺失项 在现实中我们获…

结构化文本文档的内容抽取与版本重构策略

结构化文本文档的内容抽取与版本重构策略 摘要 本文深入探讨了结构化文本文档处理领域中的两大核心技术——内容抽取与版本重构。文章首先分析了结构化文档的特点及其在现代信息管理中的重要性,随后系统性地介绍了文档内容抽取的技术路线与方法论,包括…

【BUUCTF系列】[HCTF 2018]WarmUp1

本文仅用于技术研究,禁止用于非法用途。 Author:枷锁 点开题目显示一个图片,没有任何交互功能,我们直接查看网页源代码我们可以看到有一个歆慕的注释source.php,我们进行拼接,访问一下这个文件在url后加上/source.php进…

Flutter Chen Generator - IconFont Generator

Flutter Chen Generator 🚀 一个强大的Flutter代码生成工具包,包含多个实用的代码生成器。 ✨ 功能特性 📁 资源生成器 (Assets Generator) 🔄 自动扫描assets目录并生成Dart常量🧠 智能驼峰命名转换,保…

【MATLAB】(二)基础知识

一.MATLAB命令1.指令行“头首”的 “>>” 是 “指令输入提示符” ,它是自动输入的。“>>” 为运算提示符,表示MATLAB处于准备就绪状态。如在提示符后输入一条命令或一段程序后按Enter键,MATLAB将给出对应的结果,并将结…

Day36| 1049. 最后一块石头的重量 II、494.目标和、474.一和零

文章链接 1049. 最后一块石头的重量 II 解题关键:找到重量和尽量相等的两堆 确定dp数组以及下标的含义 dp[j]表示容量(这里说容量更形象,其实就是重量)为j的背包,最多可以背最大重量为dp[j]。 确定递推公式 01背包…

【A*/BFS】P5507 机关

# P5507 机关 题目描述 这扇门上有一个机关,上面一共有12个旋钮,每个旋钮有4个状态,将旋钮的状态用数字111到444表示 每个旋钮只能向一个方向旋转(状态:1->2->3->4->1),在旋转时&am…

终结集成乱局:模型上下文协议(MCP)如何重构AI工具生态?

AI 助手正处于能力发展的初级阶段。它们擅长处理独立任务——例如解析 PDF、编写 SQL 语句、等等——但当你要求它们在 Slack、Gmail 和 Jira 等平台间协同操作时,整个流程就变得异常复杂且脆弱,如同调试一套由众多 API 密钥串联的精密机械(鲁…