结构型设计模式 - 大作业

题目

结构型设计模式大作业:多平台多媒体播放器系统

一、项目背景

为了构建一个可扩展、易维护的多平台多媒体播放器系统,我们需要支持播放不同格式的媒体文件(如 MP3、MP4、AVI),并支持跨平台播放(如 Windows、Linux)。此外,为了提升用户体验,该播放器还应支持播放过程中的附加功能(如字幕、倍速、音效增强),同时具备播放列表的组织能力和访问权限控制。为简化客户端调用过程,应对系统暴露一个统一的操作接口。

二、任务目标

本练习题旨在训练你将多种结构型设计模式融合运用,构建复杂系统的能力。你需要使用以下六种结构型设计模式:桥接模式、装饰器模式、组合模式、适配器模式、代理模式和外观模式。

三、开发任务分解

任务1:实现桥接模式结构

目标:解耦媒体类型(MP3、MP4)与播放平台(Windows、Linux)。

要求:

  • 定义接口 Platform,包含方法 decode(String filename)。

  • 创建类 WindowsPlatform 和 LinuxPlatform 实现 Platform 接口。

  • 定义抽象媒体类(可选)或直接定义类 MP3 与 MP4,实现接口 Media。

  • 媒体类持有 Platform 引用,通过 platform.decode(…) 播放文件。

实现建议:桥接模式重点在于媒体种类和平台种类之间的解耦。

任务2:实现装饰器模式结构

目标:为媒体播放过程动态叠加功能,如字幕、倍速播放、音效增强等。

要求:

  • 创建抽象类 MediaDecorator,实现 Media 接口并持有 Media 实例。

  • 创建具体装饰类 SubtitleDecorator、SpeedDecorator、EffectDecorator。

  • 每个装饰器调用原始 media.play(),再叠加附加操作。

实现建议:可将多个装饰器组合使用,形成链式调用结构。

任务3:实现组合模式结构

目标:使用播放列表统一管理媒体项或嵌套播放列表,实现递归播放。

要求:

  • 定义类 Playlist,实现 Media 接口。

  • 定义 List<Media> 成员变量,支持添加媒体或子播放列表。

  • 在 play() 方法中,遍历 items 调用每个媒体项的 play()。

实现建议:Playlist 和 MP3/MP4 都实现 Media 接口,形成树形结构。

任务4:实现适配器模式结构

目标:将老旧 AVI 媒体格式转换为系统可播放格式(通过适配 MP4)。

要求:

  • 创建类 AviAdapter,实现 Media 接口。

  • 在内部持有 MP4 实例,将 AVI 文件名包装成 MP4 并播放。

实现建议:适配器模式用于“接口转换”,让 AVI 行为看起来像 Media。

任务5:实现代理模式结构

目标:在播放前进行权限验证,播放后记录日志。

要求:

  • 创建类 MediaProxy,实现 Media 接口。

  • MediaProxy 构造函数中接收真实 Media 对象和用户身份。

  • 在 play() 中先判断权限,再调用真实对象的 play(),并打印日志。

实现建议:可设置用户 admin 具有播放权限,非 admin 提示权限不足。

任务6:实现外观模式结构

目标:简化客户端播放流程,提供统一播放入口。

要求:

  • 创建类 MediaPlayerFacade,包含方法 playMedia(Media media)。

  • 在客户端只使用 facade 对象播放任意媒体或播放列表。

实现建议:将播放、装饰、代理等过程对客户端隐藏,降低复杂度。

四、参考输出

媒体播放开始:
播放媒体:song1.mp3(Windows平台)
-> 字幕开启
-> 1.5 倍速
播放媒体:video1.mp4(Linux平台)
-> 音效增强
播放媒体:video2.avi(通过适配器转换)
播放子播放列表:
播放媒体:song2.mp3
权限验证成功
日志记录:song2.mp3 已播放

代码

PlantUML