一、外观模式的实现方式

外观模式的核心是通过封装复杂子系统的调用逻辑,为客户端提供一个统一的简单接口。以下是实现步骤及示例:


  1. 定义子系统类
    子系统类负责实现具体功能,与外观类解耦。例如,家庭影院系统中的投影仪、音响等组件:
// 子系统接口
interface TheaterControl {void on();void off();void setVolume(int volume);
}
// 具体子系统实现
class Projector implements TheaterControl {public void on() { System.out.println("投影仪开启"); }public void off() { System.out.println("投影仪关闭"); }
}
class StereoSystem implements TheaterControl {public void on() { System.out.println("音响开启"); }public void off() { System.out.println("音响关闭"); }public void setVolume(int volume) { System.out.println("音量设为:" + volume); }
}

  1. 创建外观类
    外观类聚合子系统对象,提供高层接口,协调子系统操作:
public class HomeTheaterFacade {private TheaterControl projector;private TheaterControl stereo;public HomeTheaterFacade() {this.projector = new Projector();this.stereo = new StereoSystem();}// 统一接口:观影模式public void watchMovie(String movie) {System.out.println("准备观看:" + movie);projector.on();stereo.on();stereo.setVolume(50);}
}

  1. 客户端调用
    客户端通过外观类简化复杂操作:
public class Client {public static void main(String[] args) {HomeTheaterFacade facade = new HomeTheaterFacade();facade.watchMovie("Java设计模式实战");}
}

二、测试方法与Mockito框架应用

测试外观模式时,需验证其是否正确调用子系统方法。通过Mockito框架模拟子系统对象,确保外观类逻辑正确。


  1. 基础测试:验证子系统方法调用
import static org.mockito.Mockito.*;
import org.junit.Test;
public class HomeTheaterFacadeTest {@Testpublic void testWatchMovie() {// 创建Mock对象TheaterControl mockProjector = mock(Projector.class);TheaterControl mockStereo = mock(StereoSystem.class);// 创建外观类并注入Mock对象HomeTheaterFacade facade = new HomeTheaterFacade() {@Overridepublic TheaterControl getProjector() { return mockProjector; }@Overridepublic TheaterControl getStereo() { return mockStereo; }};// 执行外观方法facade.watchMovie("测试电影");// 验证子系统方法调用verify(mockProjector).on();verify(mockStereo).on();verify(mockStereo).setVolume(50);}
}

  1. 高级测试:异常处理与状态验证
    模拟子系统异常,测试外观类的容错逻辑:
@Test
public void testWatchMovieWithException() {TheaterControl mockProjector = mock(Projector.class);when(mockProjector.on()).thenThrow(new RuntimeException("投影仪故障"));HomeTheaterFacade facade = new HomeTheaterFacade() {@Overridepublic TheaterControl getProjector() { return mockProjector; }};try {facade.watchMovie("测试电影");fail("预期抛出异常");} catch (RuntimeException e) {assertEquals("投影仪故障", e.getMessage());}
}

三、实现与测试的注意事项

  1. 实现最佳实践
    • 单一职责:外观类仅负责协调子系统,避免包含业务逻辑。
    • 接口隔离:子系统应通过接口与外观类交互,增强扩展性。
    • 线程安全:若外观类被多线程访问,需同步关键方法。
  2. 测试关键点
    • 覆盖所有子系统调用:确保每个子系统方法在测试中被验证。
    • 模拟异常场景:测试子系统故障时外观类的容错机制。
    • 避免过度模拟:仅Mock必要子系统,保留真实依赖以测试完整流程。

四、总结

外观模式通过封装复杂子系统的调用逻辑,显著降低客户端耦合度。实现时需遵循接口隔离与单一职责原则,测试时利用Mockito框架验证子系统交互。其核心价值在于简化接口设计,但需注意对开闭原则的潜在违背及测试复杂度问题。

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

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

相关文章

《解锁AudioSet:开启音频分析的无限可能》

音频新时代的 “密钥”:AudioSet 登场 在科技飞速发展的今天,音频作为信息传播与交互的关键媒介,早已渗透到现代科技的各个角落。从智能手机中的语音助手,让我们通过简单的语音指令就能查询信息、发送消息,到智能家居系…

50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | ThemeClock(主题时钟)

&#x1f4c5; 我们继续 50 个小项目挑战&#xff01;—— ThemeClock组件 仓库地址&#xff1a;https://github.com/SunACong/50-vue-projects 项目预览地址&#xff1a;https://50-vue-projects.vercel.app/ 使用 Vue 3 的 Composition API 和 <script setup> 语法结…

直播预告丨聊聊Milvus 2.6新功能及背后的开发故事

7 月 1 日晚上 20:00-21:00&#xff0c;Zilliz 视频号直播间&#xff0c;Zilliz 合伙人和研发VP 栾小凡将带来《一步到位&#xff0c;详解 Milvus 2.6 新功能》的分享&#xff0c;带你拆解 Milvus 2.6 四大突破&#xff1a; 降本增效的底层架构开发者生产力拉满的新功能性能不打…

pyenv-win 配置指南​

在 Python 开发过程中&#xff0c;经常会遇到需要使用不同版本 Python 的情况。比如&#xff0c;旧项目依赖某个特定的 Python 版本&#xff0c;而新项目则要求使用更新的版本。这时&#xff0c;版本管理工具就显得尤为重要。pyenv-win就是一款专门为 Windows 系统设计的 Pytho…

MongoDB 常见查询语法与命令详解

MongoDB 作为文档型数据库&#xff0c;其查询语言基于 BSON&#xff08;二进制 JSON&#xff09;格式&#xff0c;与传统关系型数据库的 SQL 语法有较大差异。 一、基本查询命令 1. find()&#xff1a;查询文档 语法&#xff1a;db.collection.find(查询条件, 投影)示例&…

AlpineLinux安装docker

或许你在docker中使用 Alpine Linux 的镜像使用得多,但是有没有想过在 Alpine Linux 上安装 Docker 来使用呢?默认情况下,Docker 包位于社区仓库中,因此在使用包管理来安装docker之前建议更换为国内源,并开启社区仓库的链接。 下面的操作是在root用户下运行的,如果要使用…

docker安装gitlab并配置ssl证书

本篇安装环境 Docker版本&#xff1a;Docker version 28.3.0 域名&#xff1a;test.disallow.cn 自签证书&#xff1a;/etc/gitlab/ssl&#xff08;已经存放在该目录&#xff09; 一、拉取镜像 docker run -itd \--privilegedtrue \--hostname gitlab.test.disallow.cn \--p…

Java开发者转型AI时代的路径

Java开发者转型AI时代的路径 引言 随着人工智能技术的飞速发展&#xff0c;AI已不再是遥不可及的未来&#xff0c;而是深刻影响着各行各业的当下。对于Java开发者而言&#xff0c;面对AI浪潮&#xff0c;如何顺势而为&#xff0c;实现职业转型与技能升级&#xff0c;成为摆在…

QT6 源(140)模型视图架构里的视图总基类 QAbstractItemView:

&#xff08;1&#xff09;先给出本类的继承关系 &#xff1a; &#xff08;2&#xff09;Qt 已经预先为视图定义了键盘功能&#xff0c;Qt 大师们通过编程&#xff0c;已经完善了视图对键盘的响应操作 &#xff1a; &#xff08;3&#xff09;因为本类是抽象基类&#xff0c;无…

vue上传各种文件,并预览组件,(预览,下载),下载resources目录下文件

前端组件vue 最终效果 <template><div ><div class"file-list" v-if"existingFiles.length > 0"><div class"file-card" v-for"(file, index) in existingFiles" :key"file.id"><div clas…

【CS创世SD NAND征文】SD NAND赋能新一代儿童智能玩具

基于全志F1C100S的高可靠存储方案 文章目录 基于全志F1C100S的高可靠存储方案[toc]前言 一、应用产品介绍&#xff1a;儿童智能玩具的需求演变二、技术方案介绍&#xff1a;构建智能玩具的"大脑"与"记忆库"三、核心技术模块分析3.1 主控芯片&#xff1a;全…

mac触摸板设置右键

在 Mac 笔记本上&#xff0c;触摸板默认没有物理左右键分区&#xff0c;但可以通过以下方式实现“右键”功能&#xff08;称为 辅助点按&#xff09;&#xff1a; 一、启用与使用右键&#xff08;辅助点按&#xff09; 步骤1&#xff1a;检查系统设置 点击屏幕左上角 &#x…

稳定币发行量创纪录地超过 Visa 交易量

稳定币发行量创纪录地超过 Visa 交易量 稳定币的崛起正在重塑全球金融格局&#xff0c;华夏基金首席执行官甘天&#xff08;Gan Tian&#xff09;强调了稳定币的快速增长&#xff0c;并指出稳定币的交易量在短短五年内就超过了Visa 40年的交易量。这凸显了货币使用的转变。 稳…

编程 IDE 混战简史:从 Copilot 到 Claude Code,一场重塑开发方式的战争

unsetunset引言&#xff1a;开发新纪元的序幕unsetunset 编程世界&#xff0c;从最初依赖打孔卡和简陋的命令行工具&#xff0c;到如今功能琳琅满目的集成开发环境&#xff08;IDE&#xff09;&#xff0c;每一步都见证了效率与智能的飞跃。IDE作为开发者与代码交互的核心界面&…

软测八股--计算机网络

计算机网络基础 局域网广域网 局域网&#xff1a;一个区域内由多台计算机互联成的计算机组&#xff08;学校&#xff0c;办公室&#xff0c;公司/学校等&#xff09;。可以实现文件管理&#xff0c;应用软件管理&#xff0c;答应及管理&#xff0c;扫描仪共享等。是封闭的&am…

某省职业院校技能大赛 高职组“信息安全管理与评估”赛项第二部分:应急响应

&#xff01;&#xff01;&#xff01;需要环境可私信博主&#xff01;&#xff01;&#xff01; &#xff01;&#xff01;&#xff01;若有错误欢迎指正&#xff01;:) 序号任务要求1提交攻击者的两个内网IP地址2提交网站管理员用户的用户名和密码3提交黑客得到 mysql 服务的…

OkHttp 简单配置

OkHttpClient 的简单配置&#xff0c;包含重试&#xff0c;线程池 Configuration public class OkHttpConfig {Bean("deSourceOkHttp")public OkHttpClient okHttpClient() {return new OkHttpClient.Builder().connectTimeout(60, TimeUnit.SECONDS).readTimeout(3…

群晖nas安装moodle跳坑记录

1&#xff0c;套件里面直接安装 会安装好几个依赖&#xff0c;包括php apach &#xff0c;数据库。这些安装的时间就比较长。 安装完成后自动安装 Moodle。 过程也很长数据库里面的表有接近500张。 2&#xff0c;安装位置 顺便提一下 nas程序的安装位置 这两个位置好像都不是…

鸿蒙HarmonyOS 5小游戏实践:打砖块游戏(附:源代码)

打砖块是一款经典的游戏&#xff0c;它简单易懂却又充满挑战性。本文将介绍如何使用ArkUI框架开发一个完整的打砖块游戏&#xff0c;涵盖游戏逻辑设计、UI实现和交互处理等核心内容。 游戏架构设计 我们的打砖块游戏采用了组件化设计&#xff0c;主要分为两个部分&#xff1a;…

Flutter MobX 响应式原理与实战详解

&#x1f4da; Flutter 状态管理系列文章目录 Flutter 状态管理(setState、InheritedWidget、 Provider 、Riverpod、 BLoC / Cubit、 GetX 、MobX 、Redux) setState() 使用详解&#xff1a;原理及注意事项 InheritedWidget 组件使用及原理 Flutter 中 Provider 的使用、注…