理解设计模式与 UML 类图:构建稳健软件架构的基石
在软件开发的广阔天地里,设计模式与 UML(统一建模语言)类图犹如两座灯塔,为开发者照亮前行的道路,指引着我们构建出高质量、可维护且易于扩展的软件系统。今天,就让我们一同深入探索单一职责、开闭原则、简单工厂模式以及 UML 类图中的关键概念,包括关联、依赖、泛化、实现,还有关联关系中的特殊形式 —— 组合与聚合。
一、设计模式的基石:单一职责与开闭原则
(一)单一职责原则
单一职责原则如同软件世界中的 “专注大师”,它强调一个类只应承担一个职责,即仅有一个引起它变化的原因。想象一下,如果一个类既负责数据的存储,又负责数据的展示与用户交互,那么一旦用户界面需要调整,数据存储部分可能也会受到牵连,导致代码的稳定性和可维护性大打折扣。例如,在一个电商系统中,我们有一个 Product 类,它的职责应该仅仅是处理与产品相关的信息,如产品名称、价格、库存等,而不应该涉及订单处理或用户账户管理等其他功能。这样,当产品的属性或业务逻辑发生变化时,我们只需要关注 Product 类本身,而不用担心对其他无关模块造成影响。
(二)开闭原则
开闭原则则像是一位 “包容的智者”,倡导软件实体对扩展开放,对修改关闭。这意味着当系统需要添加新功能或适应新的需求变化时,我们应该通过扩展现有代码来实现,而不是直接修改已有的稳定代码。以一个图形绘制系统为例,最初系统可能只支持绘制圆形和矩形。按照开闭原则,我们可以设计一个抽象的 Shape 类,Circle 和 Rectangle 类继承自它。当需要添加绘制三角形的功能时,我们只需创建一个新的 Triangle 类继承自 Shape 类,而无需修改 Shape、Circle 和 Rectangle 类中的原有代码。这样,既保证了系统的稳定性,又能灵活地应对不断变化的需求。
二、简单工厂模式:对象创建的智慧工厂
简单工厂模式犹如一个高效的 “生产车间”,负责创建对象而将对象的使用与创建过程分离开来。在实际应用中,比如在一个游戏开发场景里,有多种角色类型,如战士、法师、刺客等。我们可以创建一个 CharacterFactory 简单工厂类,它根据传入的参数(如角色类型的标识)来决定创建哪种具体的角色对象。这样,游戏中的其他模块,如游戏场景、战斗逻辑等,只需要从这个工厂获取角色对象,而不必关心角色是如何被创建出来的。这大大降低了代码的耦合度,使得各个模块可以独立地进行开发、测试和维护。
三、UML 类图:软件架构的蓝图
UML 类图是软件架构的可视化蓝图,它通过各种图形符号和关系来描述系统中的类、对象以及它们之间的交互。其中,关联、依赖、泛化和实现是 UML 类图中几个核心的关系概念。
(一)关联关系
关联关系描绘了类与类之间的一种语义连接,就像是人与人之间的各种联系。在学校管理系统中,Student 类和 Class 类之间存在关联关系,一个班级可以容纳多个学生,而一个学生也必然属于某个班级。在 UML 类图中,关联关系用一条直线表示。这种关系体现了类之间相对稳定的结构联系,是构建复杂系统结构的基础。
(二)依赖关系
依赖关系则更像是一种临时性的 “借力” 行为。例如,Driver 类和 Car 类之间存在依赖关系,因为司机需要驾驶汽车才能完成运输任务。在代码层面,可能是 Driver 类的某个方法中使用了 Car 类的对象。在 UML 类图中,依赖关系用带箭头的虚线表示,箭头指向被依赖的类。依赖关系表明一个类的变化可能会影响到另一个类,但这种影响相对较弱且局部。
(三)泛化关系
泛化关系就是我们熟知的继承关系,它体现了一种 “is-a” 的层次结构。以动物世界为例,Mammal(哺乳动物)类是一个泛化的概念,Cat(猫)类和 Dog(狗)类都继承自 Mammal 类,它们共享 Mammal 类的一些共性特征,如具有毛发、哺育后代等,同时又各自具有独特的属性和行为。在 UML 类图中,泛化关系用带空心三角形箭头的实线表示,箭头指向父类。泛化关系有助于代码的复用和扩展,通过继承父类的属性和方法,子类可以减少重复代码的编写,并且可以根据自身需求进行个性化的扩展。
(四)实现关系
实现关系主要用于接口和实现类之间的桥梁搭建。比如,在一个图形绘制库中,有一个 Shape 接口,它定义了图形绘制的基本方法,如 draw 方法。而 Circle 类、Rectangle 类等具体的图形类则实现了这个 Shape 接口,它们必须按照接口的规范来实现 draw 方法。在 UML 类图中,实现关系用带空心三角形箭头的虚线表示,箭头指向接口。实现关系使得不同的类可以遵循相同的接口规范,从而提高了代码的灵活性和可替换性。
四、关联关系中的特殊形式:组合与聚合
(一)聚合关系
聚合关系是一种相对松散的整体与部分关系,就像汽车和轮胎的关系。轮胎是汽车的一部分,但轮胎可以从汽车上拆卸下来,单独存在并可能被安装到其他汽车上。在 UML 类图中,聚合关系用空心菱形箭头的直线表示,箭头指向整体。聚合关系体现了一种弱的 “拥有” 关系,部分的生命周期可以独立于整体。
(二)组合关系
组合关系则是一种紧密的整体与部分关系,类似于人体和心脏的关系。心脏是人体不可或缺的一部分,当人体不存在时,心脏也就失去了其存在的意义,其生命周期完全依赖于整体。在 UML 类图中,组合关系用实心菱形箭头的直线表示,箭头指向整体。组合关系强调了部分与整体的强关联性和不可分割性。
理解并熟练运用这些设计模式和 UML 类图的概念,对于软件开发者来说具有极其重要的意义。它们能够帮助我们在软件开发的初期就设计出合理的架构,提高代码的质量和可维护性,减少后期因需求变更而带来的巨大成本。无论是初入编程世界的新手,还是经验丰富的资深开发者,深入研究这些知识都将为我们的软件开发之旅带来无尽的智慧和力量。让我们在实践中不断探索和应用这些宝贵的理念,构建出更加优秀的软件系统。
以上就是关于单一职责、开闭原则、简单工厂模式以及 UML 类图相关概念的深入探讨,希望能为广大开发者在软件架构设计和开发过程中提供有益的参考和启示。
相关文章:
理解设计模式与 UML 类图:构建稳健软件架构的基石
在软件开发的广阔天地里,设计模式与 UML(统一建模语言)类图犹如两座灯塔,为开发者照亮前行的道路,指引着我们构建出高质量、可维护且易于扩展的软件系统。今天,就让我们一同深入探索单一职责、开闭原则、简…...
FastAPI重载不生效?解决PyCharm中Uvicorn无法重载/重载缓慢的终极方法!
文章目录 📖 介绍 📖🏡 演示环境 🏡📒 重载缓慢 📒📝 问题概述🚨 相关原因📝 解决方案一📝 解决方案二📝 解决方案三📝 解决方案四⚓️ 相关链接 ⚓️📖 介绍 📖 在使用FastAPI开发时,reload=True 本应让你在修改代码后自动重启服务,提升开发效率…...
最新子比主题zibll8.0开心版源码 无加密无后门
Zibll子比主题专为博客、自媒体及资讯类网站精心打造,以其简约而不失高雅的设计风格,为网站增添独特魅力与视觉美感。 8.0更新内容: 新增发帖选择板块、话题、标签时支持搜索,同时优化了选择栏目,更加方便快捷 新增小工具文章列表…...
【数据分析】认清、明确
1、什么是数据分析。 - 通过对大量的数据进行科学的分析。 - 得出结论,提出建议,辅助公司企业的决策。2、数据分析分为几步。 - 1.明确目的! - 2.收集数据!自己的数据! 自动化采集的数据! - 3.数据处理! - 4.数据分析!数据分析(业务)数据挖掘(代码算法…...
工业生产安全-安全帽第二篇-用java语言看看opencv实现的目标检测使用过程
一.背景 公司是非煤采矿业,核心业务是采选,大型设备多,安全风险因素多。当下政府重视安全,头部技术企业的安全解决方案先进但价格不低,作为民营企业对安全投入的成本很敏感。利用我本身所学,准备搭建公司的…...
人工智能(AI)与机器学习(ML)基础知识
目录 1. 人工智能与机器学习的核心概念 什么是人工智能(AI)? 什么是机器学习(ML)? 什么是深度学习(DL)? 2. 机器学习的三大类型 (1)监督式学…...
得物彩虹桥架构演进之路-负载均衡篇
文 / 新一 一、前言 一年一更的彩虹桥系列又来了,在前面两期我们分享了在稳定性和性能2个层面的一些演进&优化思路。近期我们针对彩虹桥 Proxy 负载均衡层面的架构做了一次升级,目前新架构已经部署完成,生产环境正在逐步升级中…...
Jmeter中的断言(四)
13--XPath断言 功能特点 数据验证:验证 XML 响应数据是否包含或不包含特定的字段或值。支持 XPath 表达式:使用 XPath 表达式定位和验证 XML 数据中的字段。灵活配置:可以设置多个断言条件,满足复杂的测试需求。 配置步骤 添加…...
vue2 src_Todolist编辑($nextTick)
main.js //引入Vue import Vue from "vue"; //引入App import App from ./App;//关闭Vue的生产提示 Vue.config.productionTip false;new Vue({el: #app,render: h > h(App),beforeCreate() {//事件总线Vue.prototype.$bus this;} });App.vue <template>…...
driver.js实现页面操作指引
概述 在访问某些网站的时候,第一次进去你会发现有个操作指引,本文引用driver.js,教你在你的页面也加入这般高大上的操作指引。 实现效果 实现 driver.js简介 driver.js是一个功能强大且高度可定制的基于原生JavaScript开发的新用户引导库…...
ffmpeg区域颜色覆盖
ffmpeg去除水印(遮盖指定区域)的几种办法_ffmpeg去水印-CSDN博客 ffmpeg -i a.mp4 -vf "drawboxx1560:y30:w310:h100:tfill" b.mp4 drawbox在视频帧上绘制一个矩形: x和y:矩形左上角的坐标。默认值是0。 w和h:矩形的宽度和高度。…...
【Python TensorFlow】进阶指南(续篇三)
在前几篇文章中,我们探讨了TensorFlow的高级功能,包括模型优化、分布式训练、模型解释等多个方面。本文将进一步深入探讨一些更具体和实用的主题,如模型持续优化的具体方法、异步训练的实际应用、在线学习的实现细节、模型服务化的最佳实践、…...
QT 实现仿制 网络调试器(未实现连接唯一性) QT5.12.3环境 C++实现
网络调试助手: 提前准备:在编写代码前,要在.pro工程文件中,添加network模块。 服务端: 代码: widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QtWidgets> #inclu…...
【英特尔IA-32架构软件开发者开发手册第3卷:系统编程指南】2001年版翻译,2-31
文件下载与邀请翻译者 学习英特尔开发手册,最好手里这个手册文件。原版是PDF文件。点击下方链接了解下载方法。 讲解下载英特尔开发手册的文章 翻译英特尔开发手册,会是一件耗时费力的工作。如果有愿意和我一起来做这件事的,那么ÿ…...
面试题---深入源码理解MQ长轮询优化机制
引言 在分布式系统中,消息队列(MQ)作为一种重要的中间件,广泛应用于解耦、异步处理、流量削峰等场景。其中,延时消息和定时消息作为MQ的高级功能,能够进一步满足复杂的业务需求。为了实现这些功能…...
stable diffusion生成模型
1、stable diffusion Stable Diffusion 是一种扩散模型,基于对图像的逐步去噪过程训练和生成。它的核心包括以下几个步骤: 扩散过程(Diffusion Process)在训练时,向真实图像逐步添加噪声,最终将其变为纯随机噪声。这是一个正向过程,目的是学习如何将复杂的图像分解成随…...
分治法的魅力:高效解决复杂问题的利器
文章目录 分治法 (Divide and Conquer) 综合解析一、基本原理二、应用场景及详细分析1. 排序算法快速排序 (Quicksort)归并排序 (Mergesort) 2. 大整数运算大整数乘法 3. 几何问题最近点对问题 4. 字符串匹配KMP算法的优化版 三、优点四、局限性五、分治法与动态规划的对比六、…...
Spring IOC实战指南:从零到一的构建过程
Spring 优点: 方便解耦,简化开发。将所有对象创建和依赖关系维护交给 Spring 管理(IOC 的作用)AOP 切面编程的支持。方便的实现对程序进行权限的拦截、运行监控等功能(可扩展性)声明式事务的支持。只需通过配置就可以完成对事务的管理,无需手…...
3.langchain中的prompt模板 (few shot examples in chat models)
本教程将介绍如何使用LangChain库和智谱清言的 GLM-4-Plus 模型来理解和推理一个自定义的运算符(例如使用鹦鹉表情符号🦜)。我们将通过一系列示例来训练模型,使其能够理解和推断该运算符的含义。 环境准备 首先,确保…...
量子感知机
神经网络类似于人类大脑,是模拟生物神经网络进行信息处理的一种数学模型。它能解决分类、回归等问题,是机器学习的重要组成部分。量子神经网络是将量子理论与神经网络相结合而产生的一种新型计算模式。1995年美国路易斯安那州立大学KAK教授首次提出了量子…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
c# 局部函数 定义、功能与示例
C# 局部函数:定义、功能与示例 1. 定义与功能 局部函数(Local Function)是嵌套在另一个方法内部的私有方法,仅在包含它的方法内可见。 • 作用:封装仅用于当前方法的逻辑,避免污染类作用域,提升…...
第八部分:阶段项目 6:构建 React 前端应用
现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能
指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...
java高级——高阶函数、如何定义一个函数式接口类似stream流的filter
java高级——高阶函数、stream流 前情提要文章介绍一、函数伊始1.1 合格的函数1.2 有形的函数2. 函数对象2.1 函数对象——行为参数化2.2 函数对象——延迟执行 二、 函数编程语法1. 函数对象表现形式1.1 Lambda表达式1.2 方法引用(Math::max) 2 函数接口…...
命令行关闭Windows防火墙
命令行关闭Windows防火墙 引言一、防火墙:被低估的"智能安检员"二、优先尝试!90%问题无需关闭防火墙方案1:程序白名单(解决软件误拦截)方案2:开放特定端口(解决网游/开发端口不通)三、命令行极速关闭方案方法一:PowerShell(推荐Win10/11)方法二:CMD命令…...
