深入理解系统:UML类图

UML类图

类图(class diagram) 描述系统中的对象类型,以及存在于它们之间的各种静态关系

正向工程(forward engineering)在编写代码之前画UML图。
逆向工程(reverse engineering)从已有代码建造UML图,目的是帮助人们理解代码。

案例1:电商系统类图

在这里插入图片描述

# UML类图元素:类、属性、方法、继承、关联、聚合
from typing import Listclass User:def __init__(self, user_id: str, name: str):self.user_id = user_id  # 公有属性self._name = name       # 保护属性self.__password = ""    # 私有属性def login(self, password: str) -> bool:  # 公有方法"""验证用户登录"""return password == self.__passwordclass Customer(User):  # 继承关系 (泛化)def __init__(self, user_id: str, name: str):super().__init__(user_id, name)self.cart = ShoppingCart()  # 组合关系 (强拥有)def place_order(self) -> Order:"""创建订单"""return Order(self, self.cart.items)class Seller(User):  # 继承关系def __init__(self, user_id: str, name: str, store: Store):super().__init__(user_id, name)self.store = store  # 关联关系def add_product(self, product: Product):"""添加商品到店铺"""self.store.products.append(product)class Product:def __init__(self, product_id: str, name: str, price: float):self.product_id = product_idself.name = nameself.price = priceclass ShoppingCart:def __init__(self):self.items: List[Product] = []  # 聚合关系 (弱拥有)def add_item(self, product: Product):self.items.append(product)def calculate_total(self) -> float:return sum(item.price for item in self.items)class Order:def __init__(self, customer: Customer, items: List[Product]):self.customer = customer  # 关联关系self.items = itemsself.status = "Pending"def process_payment(self, payment: PaymentProcessor):  # 依赖关系payment.process(self.calculate_total())def calculate_total(self) -> float:return sum(item.price for item in self.items)class Store:def __init__(self, store_id: str, name: str):self.store_id = store_idself.name = nameself.products: List[Product] = []  # 聚合关系# 接口实现 (依赖倒置)
class PaymentProcessor(ABC):  # 抽象类/接口@abstractmethoddef process(self, amount: float):passclass CreditCardProcessor(PaymentProcessor):  # 实现关系def process(self, amount: float):print(f"Processing credit card payment: ${amount:.2f}")class PayPalProcessor(PaymentProcessor):  # 实现关系def process(self, amount: float):print(f"Processing PayPal payment: ${amount:.2f}")

案例2:车辆租赁系统类图

在这里插入图片描述

# UML类图元素:抽象类、枚举、组合、聚合、依赖
from abc import ABC, abstractmethod
from enum import Enum
from datetime import dateclass VehicleType(Enum):  # 枚举类CAR = 1TRUCK = 2SUV = 3MOTORCYCLE = 4class AbstractVehicle(ABC):  # 抽象类def __init__(self, license_plate: str, model: str, year: int):self.license_plate = license_plateself.model = modelself.year = yearself.available = True@abstractmethoddef get_rental_rate(self) -> float:passclass Car(AbstractVehicle):  # 继承def __init__(self, license_plate: str, model: str, year: int, seats: int):super().__init__(license_plate, model, year)self.seats = seatsdef get_rental_rate(self) -> float:  # 实现抽象方法return 50.0 + (self.seats * 5)class Truck(AbstractVehicle):  # 继承def __init__(self, license_plate: str, model: str, year: int, capacity: float):super().__init__(license_plate, model, year)self.capacity = capacity  # 载重能力(吨)def get_rental_rate(self) -> float:return 100.0 + (self.capacity * 20)class RentalAgency:def __init__(self, name: str):self.name = nameself.fleet: List[AbstractVehicle] = []  # 聚合self.rentals: List[RentalContract] = []  # 组合def add_vehicle(self, vehicle: AbstractVehicle):self.fleet.append(vehicle)def rent_vehicle(self, customer: Customer, vehicle: AbstractVehicle, start_date: date, end_date: date):if vehicle.available:contract = RentalContract(customer, vehicle, start_date, end_date)self.rentals.append(contract)vehicle.available = Falsereturn contractreturn Noneclass Customer:def __init__(self, customer_id: str, name: str):self.customer_id = customer_idself.name = nameself.license_number = ""class RentalContract:  # 组合类def __init__(self, customer: Customer, vehicle: AbstractVehicle, start_date: date, end_date: date):self.customer = customerself.vehicle = vehicleself.start_date = start_dateself.end_date = end_dateself.total_cost = self.calculate_cost()def calculate_cost(self) -> float:days = (self.end_date - self.start_date).daysreturn days * self.vehicle.get_rental_rate()def generate_invoice(self, printer: InvoicePrinter):  # 依赖关系printer.print_invoice(self)class InvoicePrinter:  # 工具类def print_invoice(self, contract: RentalContract):print(f"Invoice for {contract.customer.name}")print(f"Vehicle: {contract.vehicle.model}")print(f"Total: ${contract.total_cost:.2f}")

案例3:学校管理系统类图

在这里插入图片描述

# UML类图元素:多重继承、接口实现、依赖、关联
from abc import ABC, abstractmethod
from datetime import dateclass Person:def __init__(self, name: str, birth_date: date):self.name = nameself.birth_date = birth_datedef get_age(self) -> int:today = date.today()return today.year - self.birth_date.yearclass Researcher(ABC):  # 接口@abstractmethoddef conduct_research(self, topic: str):passclass Teacher(Person):  # 单继承def __init__(self, name: str, birth_date: date, department: str):super().__init__(name, birth_date)self.department = departmentself.courses: List[Course] = []  # 双向关联def assign_course(self, course: 'Course'):self.courses.append(course)course.teacher = selfclass Professor(Teacher, Researcher):  # 多重继承def __init__(self, name: str, birth_date: date, department: str, title: str):Teacher.__init__(self, name, birth_date, department)self.title = titledef conduct_research(self, topic: str):  # 实现接口print(f"Conducting research on {topic}")def supervise_phd(self, student: 'PhdStudent'):student.advisor = selfclass Student(Person):def __init__(self, name: str, birth_date: date, student_id: str):super().__init__(name, birth_date)self.student_id = student_idself.enrolled_courses: List['Course'] = []  # 关联def enroll(self, course: 'Course'):self.enrolled_courses.append(course)course.students.append(self)class PhdStudent(Student, Researcher):  # 多重继承def __init__(self, name: str, birth_date: date, student_id: str, research_topic: str):Student.__init__(self, name, birth_date, student_id)self.research_topic = research_topicself.advisor: Professor = None  # 关联def conduct_research(self, topic: str):  # 实现接口print(f"Conducting PhD research on {topic}")class Course:def __init__(self, course_code: str, name: str):self.course_code = course_codeself.name = nameself.teacher: Teacher = None  # 双向关联self.students: List[Student] = []  # 双向关联def add_student(self, student: Student):self.students.append(student)student.enrolled_courses.append(self)class Department:def __init__(self, name: str):self.name = nameself.faculty: List[Teacher] = []  # 聚合self.courses: List[Course] = []  # 聚合def hire_teacher(self, teacher: Teacher):self.faculty.append(teacher)def add_course(self, course: Course):self.courses.append(course)class EnrollmentSystem:  # 依赖多个类def enroll_student(self, student: Student, course: Course):if student not in course.students:student.enroll(course)return Truereturn False

综合案例:带抽象接口和静态方法的电商系统

在这里插入图片描述

from abc import ABC, abstractmethod
from datetime import datetime# 抽象接口:日志服务
class ILogger(ABC):@abstractmethoddef log(self, message: str):pass# 实现接口的类
class ConsoleLogger(ILogger):def log(self, message: str):print(f"[{datetime.now()}] {message}")class FileLogger(ILogger):def __init__(self, filename: str):self.filename = filenamedef log(self, message: str):with open(self.filename, "a") as file:file.write(f"[{datetime.now()}] {message}\n")# 带静态方法的工具类
class ValidationUtils:@staticmethoddef is_valid_email(email: str) -> bool:return "@" in email and "." in email.split("@")[-1]@staticmethoddef is_valid_phone(phone: str) -> bool:return phone.isdigit() and len(phone) >= 7# 使用接口和静态方法的类
class UserService:def __init__(self, logger: ILogger):self.logger = loggerdef register_user(self, name: str, email: str, phone: str):# 使用静态方法验证if not ValidationUtils.is_valid_email(email):self.logger.log(f"Invalid email: {email}")return Falseif not ValidationUtils.is_valid_phone(phone):self.logger.log(f"Invalid phone: {phone}")return False# 注册逻辑...self.logger.log(f"User {name} registered with {email}")return True# 工厂类(使用静态方法创建对象)
class LoggerFactory:@staticmethoddef create_logger(logger_type: str) -> ILogger:if logger_type == "console":return ConsoleLogger()elif logger_type == "file":return FileLogger("app.log")else:raise ValueError("Invalid logger type")

UML类图要素总结

UML要素Python代码表现UML符号说明
类(Class)class Person:矩形框包含类名、属性和方法
抽象类class AbstractVehicle(ABC):斜体类名包含抽象方法
接口class Interface(ABC): + @abstractmethod<<interface>> + 斜体名称只包含抽象方法
属性self.name: str+name: str+公有, -私有, #保护
方法def get_age(self):
静态方法: @staticmethod 装饰器
类方法:@classmethod 装饰器
抽象方法: @abstractmethod 装饰器
+get_age(): int
静态方法:{static} 标记或方法名下划线
类方法:{classmethod} 标记
抽象方法:{abstract} 标记 + 斜体方法名
类行为定义
继承class Teacher(Person):空心三角+实线泛化关系(is-a)
实现class Professor(Researcher):空心三角+虚线实现接口方法
组合一对一:self.cart = ShoppingCart()
一对多:self.car=[Wheel(),Wheel(),Wheel(),Wheel(),Engine()]
实心菱形+实线强拥有关系(同生命周期)
聚合self.fleet: List[Vehicle] = []空心菱形+实线弱拥有关系(可独立存在)
关联self.teacher: Teacher = None实线箭头对象间持久引用关系
依赖def process_payment(payment):虚线箭头临时使用(方法参数或局部变量中)
枚举class VehicleType(Enum):<<enumeration>>固定值集合
多重继承class Professor(Teacher, Researcher):多个空心三角继承多个父类

一些细节

关于【箭头方向】

箭头方向在UML中表示导航性(Navigability):

箭头类型表示代码等价
无箭头双向导航(默认)双方相互持有引用
单向导航只有源头类知道目标类
双向导航双方相互持有引用
◁/▷箭头端为被引用方箭头指向的类是被持有的类

关于类关系的虚实

以下是对类图中类关系图形的完整总结,重点说明实心/空心、实线/虚线的区别:

1. 实线 vs 虚线
线条类型关系强度生命周期代码对应典型关系
实线强关系可能绑定成员变量(属性)关联、聚合、组合
虚线弱关系无绑定方法参数/局部变量依赖、接口实现
2. 实心 vs 空心
填充类型所有权关系强度典型符号位置代表关系
实心强所有权最强菱形端组合关系
空心弱所有权中等菱形端/三角端聚合/继承/实现
完整关系对比图

在这里插入图片描述

关于【多重性】

多重性定义对象之间的数量关系,常见表示法:

表示法含义示例说明
1恰好1个每个人有1个心脏(组合关系)
0..10或1个学生可能有0或1个导师(关联关系)
1..*1个或多个订单必须包含至少1个商品(组合关系)
0..*0或多个部门可以有0或多个员工(聚合关系)
n恰好n个三角形有3条边(组合关系)
m..nm到n个课程有3-50名学生(关联关系)
*无限多个(同0..*社交媒体用户有多个好友(关联关系)

汇总

要素类型UML表示法代码表现多重性箭头方向生命周期关系
类(Class)矩形框(类名、属性、方法)class MyClass:不适用独立存在
抽象类类名斜体class MyClass(ABC):不适用独立存在
接口<<interface>> + 类框或圆圈class MyInterface(ABC):不适用独立存在
枚举<<enumeration>> + 枚举值class MyEnum(Enum):不适用独立存在
属性[可见性] 属性名: 类型 [= 默认值]self.attr = value不适用随对象存在
方法[可见性] 方法名(参数): 返回类型def method(self):不适用随对象存在
抽象方法斜体或{abstract}@abstractmethod不适用随抽象类存在
静态方法{static} 或下划线@staticmethod不适用类加载时存在
类方法{classmethod}@classmethod不适用类加载时存在
继承(泛化)空心三角箭头 + 实线class Child(Parent):不适用子类→父类子类依赖父类
接口实现空心三角箭头 + 虚线实现接口所有方法不适用实现类→接口实现类依赖接口
关联实线(可带箭头)类属性为另一类对象两端可设置可选(表示导航方向)相互独立
聚合空心菱形 + 实线外部传入对象(self.parts = [ext_obj])整体端通常为1菱形→整体部分可独立于整体
组合实心菱形 + 实线内部创建对象(self.part = Part())整体端通常为1菱形→整体部分依赖整体
依赖虚线箭头局部变量/参数/静态调用不适用使用方→被依赖方临时关系

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

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

相关文章

DeepSeek12-Open WebUI 知识库配置详细步骤

&#x1f4da; Open WebUI 知识库配置详细步骤&#xff08;中英文对照&#xff09; &#x1f310; 界面语言切换 # 首次登录后切换语言&#xff1a; 1. 点击左下角用户头像 → Settings 2. 在 "General" 选项卡找到 "Language" 3. 选择 中文(简体)/Engli…

Python网络设备批量配置脚本解析

目录 脚本概述 代码解析 导入模块 日志配置 核心函数config_device 主程序逻辑 使用说明 脚本优化建议 完整代码 脚本概述 这是一个使用Python编写的网络设备批量配置脚本&#xff0c;主要功能是通过SSH协议批量登录多台网络设备&#xff08;如路由器、交换机等&…

Z-FOLD: A Frustratingly Easy Post-Training Quantization Scheme for LLMs

文章目录 摘要1 引言2 相关工作2.1 量化2.2 大型语言模型的量化 3 Z-FOLD3.1 新引入的参数 ζ3.2 参数整合&#xff08;ζ 折叠&#xff09;3.3 使用校准集的微调 4 实验4.1 实验设置4.2 与其他方法的比较4.3 Z-FOLD 的泛化能力4.4 Z-FOLD 的可移植性4.5 消融研究 5 结论6 限制…

交流电机深度解析:从基础到实战的全面指南

简介 交流电机作为现代工业中不可或缺的动力设备,广泛应用于各个领域。本文将带你深入了解交流电机,从最基础的概念和工作原理开始,逐步介绍其类型、结构、关键参数等基础知识。同时,我们会探讨交流电机在企业级开发研发中的技术实战,包括控制技术、调速方法、建模与仿真…

【靶场】XXE-Lab xxe漏洞

前言 学习xxe漏洞,搭了个XXE-Lab的靶场 一、搭建靶场 现在需要登录,不知道用户名密码,先随便试试抓包 二、判断是否存在xxe漏洞 1.首先登录抓包 看到xml数据解析,由此判断和xxe漏洞有关,但还不确定xxe漏洞是否存在。 2.尝试xxe 漏洞 判断是否存在xxe漏洞 A.send to …

【C++特殊工具与技术】优化内存分配(三):operator new函数和opertor delete函数

目录 一、基础概念&#xff1a;operator new与operator delete的本质 1.1 标准库提供的operator new接口 1.2 标准库operator delete的接口 1.3 关键特性总结 二、new表达式与operator new的调用链解析 2.1 new表达式的底层步骤 2.2 示例&#xff1a;观察new表达式的调用…

[c#]判定当前软件是否用管理员权限打开

有时一些软件的逻辑中需要使用管理员权限对某些文件进行修改时&#xff0c;那么该软件在执行或者打开的场合&#xff0c;就需要用使用管理员身份运行才能达到效果。那么在c#里&#xff0c;如何判定该软件是否是对管理员身份运的呢&#xff1f; 1.取得当前的windows用户。 2.取得…

如果在main中抛出异常,该如何处理

#采用 setDefaultUncaughtExceptionHandler 进行全局兜底 public static void main(String[] args) { Thread.setDefaultUncaughtExceptionHandler((thread, ex) -> { System.err.println("全局捕获异常: " ex.getMessage()); ex.printStackTrace(); System.exi…

HBM 读的那些事

如下所示&#xff0c;为HBM读的时序。注意这里说的HBM是和HBM3是有区别的. RL 的配置,是通过MR2来实现的 WDQS貌似和CK同频。这幅图告诉你&#xff0c;WDQS和CK的源头是一样的&#xff0c;都来自PLL&#xff0c;而且中间没有经过倍频操作。所以两者频率基本是一致的。这是HBM的…

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…

三十五、面向对象底层逻辑-Spring MVC中AbstractXlsxStreamingView的设计

在Web应用开发中&#xff0c;大数据量的Excel导出功能是常见需求。传统Apache POI的XSSF实现方式在处理超大数据集时&#xff0c;会因全量加载到内存导致OOM&#xff08;内存溢出&#xff09;问题。Spring MVC提供的AbstractXlsxStreamingView通过流式处理机制&#xff0c;有效…

【大模型:知识图谱】--3.py2neo连接图数据库neo4j

【图数据库】--Neo4j 安装_neo4j安装-CSDN博客 需要打开图数据库Neo4j&#xff0c; neo4j console 目录 1.图数据库--连接 2.图数据库--操作 2.1.创建节点 2.2.删除节点 2.3.增改属性 2.4.建立关系 2.5.查询节点 2.6.查询关系 3.图数据库--实例 1.图数据库--连接 fr…

基于dify的营养分析工作流:3分钟生成个人营养分析报告

你去医院做体检&#xff0c;需要多久拿到体检报告呢&#xff1f;医院会为每位病人做一份多维度的健康报告吗&#xff1f;"人工报告需1小时/份&#xff1f;数据误差率高达35%&#xff1f;传统工具无法个性化&#xff1f; Dify工作流AI模型的组合拳&#xff0c;正在重塑健康…

Web后端基础(基础知识)

BS架构&#xff1a;Browser/Server&#xff0c;浏览器/服务器架构模式。客户端只需要浏览器&#xff0c;应用程序的逻辑和数据都存储在服务端。 优点&#xff1a;维护方便缺点&#xff1a;体验一般 CS架构&#xff1a;Client/Server&#xff0c;客户端/服务器架构模式。需要单独…

MySQL(56)什么是复合索引?

复合索引&#xff08;Composite Index&#xff09;&#xff0c;也称为多列索引&#xff0c;是在数据库表的多列上创建的索引。它可以提高涉及多个列的查询性能&#xff0c;通过组合多个列的值来索引数据。复合索引特别适用于需要同时过滤多列的查询。 复合索引的优点 提高多列…

高并发下的缓存击穿/雪崩解决方案

有效解决缓存击穿和雪崩的方法包括&#xff1a;1. 使用互斥锁处理缓存击穿&#xff1b;2. 采用熔断器模式防止雪崩&#xff1b;3. 实施缓存预热和降级策略&#xff1b;4. 利用分片和多级缓存分散请求压力。这些方法各有优劣&#xff0c;需根据实际业务场景灵活调整和结合使用。…

【读论文】OpenAI o3与o4系统模型技术报告解读

回顾一下,4月16日,OpenAI发布了一份关于其o系列新模型——OpenAI o3和OpenAI o4-mini——的System Card。这份文档不仅揭示了这两款模型在推理能力和工具使用方面的显著进步,也详细阐述了其训练方法、数据来源、安全评估以及在图像理解生成、数学推理等多个核心领域的表现。…

第1课、LangChain 介绍

LangChain 介绍 LangChain 是一个以大语言模型&#xff08;LLM, Large Language Model&#xff09;为核心的开发框架&#xff0c;旨在帮助开发者高效地将如 GPT-4 等大型语言模型与外部数据源和计算资源集成&#xff0c;构建智能化应用。 1.1 工作原理 如上图所示&#xff…

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…

[论文阅读] 人工智能+软件工程(软件测试) | 当大语言模型遇上APP测试:SCENGEN如何让手机应用更靠谱

当大语言模型遇上APP测试&#xff1a;SCENGEN如何让手机应用更靠谱&#xff1f; 一、论文基础信息 论文标题&#xff1a;LLM-Guided Scenario-based GUI Testing&#xff08;《大语言模型引导的基于场景的GUI测试》&#xff09;作者及机构&#xff1a;Shengcheng Yu等&#x…