设计模式-结构性模式

结构型模式主要关注类或对象的组合,旨在通过识别简单的结构关系来设计更复杂的结构。以下是几种常见的结构型设计模式:

1. 适配器模式(Adapter Pattern)

    • 将一个类的接口转换成客户端所期望的另一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
    • 适用于需要使用现有类但其接口不符合需求的情况。

假设我们有一个旧的MediaPlayer接口,它只能播放.mp3文件。现在我们需要一个新功能,能够播放.wav格式的文件。我们可以使用适配器模式来解决这个问题。

// 已有的MediaPlayer接口
interface MediaPlayer {void play(String audioType, String fileName);
}// 实现了MediaPlayer接口的类
class AudioPlayer implements MediaPlayer {@Overridepublic void play(String audioType, String fileName) {if (audioType.equalsIgnoreCase("mp3")) {System.out.println("Playing mp3 file. Name: " + fileName);} else {System.out.println("Invalid media. " + audioType + " format not supported");}}
}// 新的AdvancedMediaPlayer接口及其实现类
interface AdvancedMediaPlayer {void playWav(String fileName);
}class WavPlayer implements AdvancedMediaPlayer {@Overridepublic void playWav(String fileName) {System.out.println("Playing wav file. Name: " + fileName);}
}// 创建适配器类
class MediaAdapter implements MediaPlayer {private AdvancedMediaPlayer advancedMusicPlayer;public MediaAdapter() {advancedMusicPlayer = new WavPlayer();}@Overridepublic void play(String audioType, String fileName) {if(audioType.equalsIgnoreCase("wav")) {advancedMusicPlayer.playWav(fileName);}}
}// 使用适配器
public class AdapterPatternDemo {public static void main(String[] args) {MediaPlayer audioPlayer = new AudioPlayer();audioPlayer.play("mp3", "song.mp3");audioPlayer.play("wav", "song.wav"); // 这里会显示不支持MediaPlayer mediaAdapter = new MediaAdapter();mediaAdapter.play("wav", "song.wav"); // 现在可以播放wav文件}
}

2. 桥接模式(Bridge Pattern)

    • 将抽象部分与它的实现部分分离,使它们都可以独立变化。
    • 适用于当不想在抽象和实现之间建立固定的绑定关系时,例如图形库中形状和颜色的组合。

假设我们有一个绘图应用程序,它可以绘制不同形状,并且这些形状可以用不同的颜色绘制。为了使形状和颜色独立变化,我们可以使用桥接模式。

// 颜色接口
interface Color {void applyColor();
}// 具体的颜色实现
class RedColor implements Color {@Overridepublic void applyColor() {System.out.println("Red color applied.");}
}class BlueColor implements Color {@Overridepublic void applyColor() {System.out.println("Blue color applied.");}
}// 抽象的形状类,持有Color对象的引用
abstract class Shape {protected Color color;public Shape(Color color) {this.color = color;}abstract void draw();
}// 具体的形状实现
class Circle extends Shape {public Circle(Color color) {super(color);}@Overridevoid draw() {System.out.print("Drawing Circle. ");color.applyColor();}
}// 使用桥接模式
public class BridgePatternDemo {public static void main(String[] args) {Shape redCircle = new Circle(new RedColor());redCircle.draw(); // 输出:Drawing Circle. Red color applied.Shape blueCircle = new Circle(new BlueColor());blueCircle.draw(); // 输出:Drawing Circle. Blue color applied.}
}

3. 组合模式(Composite Pattern)

    • 允许将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
    • 常用于文件系统、菜单等层次化结构的场景。

假设我们有一个组织结构,包括员工和部门。每个部门可能包含多个员工和其他部门。我们可以使用组合模式来处理这种“部分-整体”的层次结构。

// 组件接口
interface Employee {void showEmployeeDetails();
}// 叶子节点
class Developer implements Employee {private String name;private long empId;public Developer(String name, long empId) {this.name = name;this.empId = empId;}@Overridepublic void showEmployeeDetails() {System.out.println("Developer Name: " + name + ", EmpId: " + empId);}
}// 组合部件
class Manager implements Employee {private List<Employee> employees = new ArrayList<>();public void addEmployee(Employee emp) {employees.add(emp);}public void removeEmployee(Employee emp) {employees.remove(emp);}@Overridepublic void showEmployeeDetails() {for (Employee emp : employees) {emp.showEmployeeDetails();}}
}// 使用组合模式
public class CompositePatternDemo {public static void main(String[] args) {Employee dev1 = new Developer("John", 1001L);Employee dev2 = new Developer("Jane", 1002L);Manager manager = new Manager();manager.addEmployee(dev1);manager.addEmployee(dev2);Employee dev3 = new Developer("Doe", 1003L);manager.addEmployee(dev3);manager.showEmployeeDetails();}
}

4. 装饰模式(Decorator Pattern)

    • 动态地给一个对象添加一些额外的职责,就增加功能来说,比生成子类更为灵活。
    • 适用于需要动态地为对象添加功能而不改变原有代码的情况,如Java中的I/O流。

装饰模式允许你通过创建一个包装对象动态地向一个对象添加功能,而不需要修改其结构。

// 基础组件接口
interface Coffee {double getCost(); // 获取成本String getDescription(); // 获取描述
}// 具体组件实现
class SimpleCoffee implements Coffee {@Overridepublic double getCost() { return 10; } // 简单咖啡的成本@Overridepublic String getDescription() { return "Simple Coffee"; }
}// 装饰器抽象类
abstract class CoffeeDecorator implements Coffee {protected Coffee decoratedCoffee;public CoffeeDecorator(Coffee c) {this.decoratedCoffee = c;}@Overridepublic double getCost() { return decoratedCoffee.getCost(); }@Overridepublic String getDescription() { return decoratedCoffee.getDescription(); }
}// 牛奶装饰器
class MilkDecorator extends CoffeeDecorator {public MilkDecorator(Coffee c) { super(c); }@Overridepublic double getCost() { return super.getCost() + 2; }@Overridepublic String getDescription() { return super.getDescription() + ", Milk"; }
}// 使用装饰模式
public class DecoratorPatternDemo {public static void main(String[] args) {Coffee myCoffee = new MilkDecorator(new SimpleCoffee());System.out.println("Cost: " + myCoffee.getCost());System.out.println("Description: " + myCoffee.getDescription());}
}

5. 外观模式(Facade Pattern)

    • 为子系统中的一组接口提供一个一致的界面,定义了一个高层接口,这个接口使得这一子系统更加容易使用。
    • 适用于简化复杂系统的接口,如数据库连接管理。

外观模式提供了一个统一的接口,用来访问子系统中的一群接口。它提供了一个高层次的接口,使得子系统更易于使用。

// 子系统类
class CPU {public void processData() { System.out.println("Processing data."); }
}class Memory {public void load() { System.out.println("Loading data from memory."); }
}class HardDrive {public void readData() { System.out.println("Reading data from hard drive."); }
}// 外观类
class ComputerFacade {private CPU cpu;private Memory memory;private HardDrive hardDrive;public ComputerFacade() {this.cpu = new CPU();this.memory = new Memory();this.hardDrive = new HardDrive();}public void startComputer() {memory.load();hardDrive.readData();cpu.processData();}
}// 使用外观模式
public class FacadePatternDemo {public static void main(String[] args) {ComputerFacade computer = new ComputerFacade();computer.startComputer();}
}

6. 享元模式(Flyweight Pattern)

    • 运用共享技术有效地支持大量细粒度的对象。
    • 适用于需要创建大量相似对象且内存占用成为问题的情况,如文本编辑器中的字符对象。

享元模式主要用于减少创建对象的数量,以减少内存占用和提高性能。它通过共享尽可能多的对象来做到这一点。

// 享元接口
interface Shape {void draw(String color);
}// 具体享元类
class Circle implements Shape {private String color;public Circle(String color) {this.color = color;}@Overridepublic void draw(String fillColor) {System.out.println("Drawing Circle [Color: " + color + ", FillColor: " + fillColor + "]");}
}// 享元工厂
class ShapeFactory {private static final HashMap<String, Shape> circleMap = new HashMap<>();public static Shape getCircle(String color) {Circle circle = (Circle)circleMap.get(color);if(circle == null) {circle = new Circle(color);circleMap.put(color, circle);System.out.println("Creating circle of color: " + color);}return circle;}
}// 使用享元模式
public class FlyweightPatternDemo {public static void main(String[] args) {ShapeFactory shapeFactory = new ShapeFactory();Shape shape1 = shapeFactory.getCircle("Red");shape1.draw("Dark Red");Shape shape2 = shapeFactory.getCircle("Red"); // 不会创建新对象shape2.draw("Light Red");}
}

7. 代理模式(Proxy Pattern)

    • 为其他对象提供一种代理以控制对这个对象的访问。
    • 适用于需要在访问对象时加入额外处理逻辑的情况,如远程调用、权限检查等。

代理模式为其他对象提供一种代理以控制对这个对象的访问。

// 主题接口
interface Image {void display();
}// 真实主题类
class RealImage implements Image {private String fileName;public RealImage(String fileName) {this.fileName = fileName;loadFromDisk(fileName);}@Overridepublic void display() {System.out.println("Displaying " + fileName);}private void loadFromDisk(String fileName) {System.out.println("Loading " + fileName);}
}// 代理类
class ProxyImage implements Image {private RealImage realImage;private String fileName;public ProxyImage(String fileName) {this.fileName = fileName;}@Overridepublic void display() {if(realImage == null) {realImage = new RealImage(fileName);}realImage.display();}
}// 使用代理模式
public class ProxyPatternDemo {public static void main(String[] args) {Image image = new ProxyImage("test_10mb.jpg");// 图像将从磁盘加载image.display();System.out.println("");// 图像不会从磁盘加载image.display();}
}

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

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

相关文章

VantUI官网更新2025,移动端前端开发

Vant 2 - Mobile UI Components built on Vue https://vant-ui.github.io/vant/v2/#/zh-CN/quickstart Vant 4 - A lightweight, customizable Vue UI library for mobile web apps. https://vant-ui.github.io/vant/#/zh-CN Vant Weapp - 轻量、可靠的小程序 UI 组件库,微…

《我的AUTOSAR之路》Det 解析

Det 解析 1. 引言和功能概述2. Errors2.1 开发错误(Development Errors)2.2 运行时错误(Runtime Errors)2.3 临时故障(Transient Faults)3 错误查询默认错误追踪器(Default Error Tracer,DET) 1. 引言和功能概述 默认错误追踪器(DET):该规范描述了默认错误追踪器(…

电脑连接示波器显示波形

通过网线连接示波器和电脑&#xff0c;将示波器波形显示在电脑上直接复制图片至报告中&#xff0c;以下是配置步骤。 一、设备 网线&#xff0c;Tektronix示波器&#xff0c;电脑 二、使用步骤 1.用网线连接电脑和示波器 2.电脑关掉WiFi&#xff0c;查看IPv4网关地址&#xf…

npm i 失败权限问题

安装完node之后, 测试全局安装一个最常用的 express 模块进行测试 失败&#xff0c;但是用管理员权限打开cmd 安装就成功。 报错如下&#xff1a; npm ERR! If you believe this might be a permissions issue, please double-check the npm ERR! permissions of the file and …

上海创智学院(测试)算法笔试(ACM赛制)部分例题

1.第一个题&#xff0c;大概题目意思是求n句话中最长的单词和最短的单词 这个题目做的有点磕巴&#xff0c;好几年没有写过c/c了&#xff0c;连string的复制都不会写了&#xff0c;哈哈哈&#xff0c;太笨了 后面一点点捡起来&#xff0c;还是写出来了&#xff0c;本身没啥&…

编写一个程序,输出 “Hello, World!“(Python版)

编写一个程序&#xff0c;输出 "Hello, World!" 在 Python 中&#xff0c;输出 “Hello, World!” 的程序非常简单。你只需要使用 print 函数即可。以下是代码示例&#xff1a; print("Hello, World!")将这段代码保存为一个 .py 文件&#xff08;例如 hel…

python实战项目58:采集蜻蜓FM热门音频top排行榜

python实战项目58:采集蜻蜓FM热门音频top排行榜 一、采集流程介绍二、数据接口采集三、使用xpath提取页面数据1、抓包,找到数据接口2、发送请求,获取数据3、提取数据4、保存数据一、采集流程介绍 蜻蜓FM热门音频top排行榜的链接为: https://m.qingting.fm/rank/,首页如下图…

【Matlab仿真】Matlab Function中如何使用静态变量?

背景 根据Simulink的运行机制&#xff0c;每个采样点会调用一次MATLAB Function的函数&#xff0c;两次调用之间&#xff0c;同一个变量的前次计算的终值如何传递到当前计算周期来&#xff1f;其实可以使用persistent变量实现函数退出和进入时内部变量值的保持。 persistent变…

LaneATT环境配置步骤

本文介绍Ubuntu下配置车道线检测算法LaneATT代码运行环境&#xff0c;步骤如下。 1. 从LaneATT官方代码仓库下载源码。也可git直接拉取。 2. 安装Anaconda或miniconda 。 参考&#xff1a;https://docs.anaconda.com/miniconda/ 3. 创建conda虚拟环境LaneATT&#xff08;环…

【AIGC】使用Python实现科大讯飞语音服务ASR转录功能:完整指南

文章目录 讯飞ASR转写API完整指南1. 引言2. 讯飞ASR API介绍3. API参数说明3.1 认证参数3.2 上传参数3.3 查询结果参数3.4 orderResult 字段3.5 Lattice 字段3.6 json_1best 字段3.7 st 字段 4. Python代码实现4.1 生成签名4.2 上传音频文件4.3 获取转写结果4.4 解析转写结果 5…

大学本科教务系统设计方案,涵盖需求分析、架构设计、核心模块和技术实现要点

以下是大学本科教务系统的设计方案,涵盖需求分析、架构设计、核心模块和技术实现要点: 大学本科教务系统设计方案 一、需求分析 1. 核心用户角色 角色功能需求学生选课/退课、成绩查询、课表查看、学分统计、考试报名、学业预警教师成绩录入、课程大纲上传、教学进度管理、…

30道Qt面试题(答案公布)

前五个答案 ✦ 1. Qt中常用的五大模块是哪些? Qt中常用的五大模块包括: • Qt Core:提供核心非GUI功能,如数据结构、文件操作、国际化等。 • Qt GUI:提供与平台无关的图形和基本窗口功能。 • Qt Widgets:提供用于创建传统桌面应用程序的UI组件。 • Qt Netw…

jdk21下载、安装(Windows、Linux、macOS)

Windows 系统 1. 下载安装 访问 Oracle 官方 JDK 下载页面 或 OpenJDK 下载页面&#xff0c;根据自己的系统选择合适的 Windows 版本进行下载&#xff08;通常选择 .msi 安装包&#xff09;。 2. 配置环境变量 右键点击 “此电脑”&#xff0c;选择 “属性”。 在左侧导航栏…

2022年全国职业院校技能大赛网络系统管理赛项模块A:网络构建(样题6)-网络部分解析-附详细代码

目录 附录1:拓扑图 附录2:地址规划表 1.SW1 2.SW2 3.SW3 4.SW4 5.VSU 6.SW7 7.R1 8.R2 9.R3 10.AC1 11.AC2 12.EG1 13.EG2 附录1:拓扑图 附录2:地址规划表

java项目之网络游戏交易系统源码(ssm+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的网络游戏交易系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 本网络游戏交易系统分为管理员…

高并发内存池的thread cache部分实现及测试

并发内存池的三个主要组成部分&#xff1a; 线程缓存&#xff08;Thread Cache&#xff09; 每个线程拥有独立的线程缓存&#xff0c;用于处理小于256KB的内存分配。由于每个线程都有自己的缓存&#xff0c;线程在从线程缓存中分配内存时无需加锁&#xff0c;这有效避免了竞争…

【红队利器】单文件一键结束火绒6.0

关于我们 4SecNet 团队专注于网络安全攻防研究&#xff0c;目前团队成员分布在国内多家顶级安全厂商的核心部门&#xff0c;包括安全研究领域、攻防实验室等&#xff0c;汇聚了行业内的顶尖技术力量。团队在病毒木马逆向分析、APT 追踪、破解技术、漏洞分析、红队工具开发等多个…

索提诺比率(Sortino Ratio):更精准的风险调整收益指标(中英双语)

索提诺比率&#xff08;Sortino Ratio&#xff09;&#xff1a;更精准的风险调整收益指标 &#x1f4c9;&#x1f4ca; &#x1f4cc; 什么是索提诺比率&#xff1f; 在投资分析中&#xff0c;我们通常使用 夏普比率&#xff08;Sharpe Ratio&#xff09; 来衡量风险调整后的…

深度学习奠基作 AlexNet 论文阅读笔记(2025.2.25)

文章目录 训练数据集数据预处理神经网络模型模型训练正则化技术模型性能其他补充 训练数据集 模型主要使用2010年和2012年的 ImageNet 大规模视觉识别挑战赛&#xff08;ILSVRC&#xff09;提供的 ImageNet 的子集进行训练&#xff0c;这些子集包含120万张图像。最终&#xff…

Deepseek 实战全攻略,领航科技应用的深度探索之旅

想玩转 Deepseek&#xff1f;这攻略别错过&#xff01;先带你了解它的基本原理&#xff0c;教你搭建运行环境。接着给出自然语言处理、智能客服等应用场景的实操方法与代码。还分享模型微调、优化技巧&#xff0c;结合案例加深理解&#xff0c;让你全面掌握&#xff0c;探索科技…