UML之类图学习

UML 类图在 C/C++ 中的工程化理解

一、设计约束(核心认知)

UML 类图不是"语法图",而是"设计意图图"

UML 中的可见性符号表达的是设计约束,而不是语言语法本身:

  • +:我允许你用(对外接口)
  • -:你不该碰(内部实现细节)
  • #:给子模块/派生模块留的

C/C++ 只是实现方式,不是 UML 的限制


二、C++ 视角下的 UML 类图

1. UML 与 C++ 的直接映射关系

UML 概念 C++ 对应
类(Class) class
属性(Attribute) 成员变量
方法(Operation) 成员函数
继承 : public Base
+ / - / # public / private / protected

2. C++ 示例代码

cpp 复制代码
class SerialPort {
public:
    void init();
    void send(uint8_t* buf, int len);
private:
    int fd;
};

3. 对应的 UML 类图表示

复制代码
┌────────────────────────────┐
│        SerialPort          │
├────────────────────────────┤
│ - fd : int                 │
├────────────────────────────┤
│ + init() : void            │
│ + send(buf : uint8_t*,     │
│        len : int) : void   │
└────────────────────────────┘

4. 设计含义说明

  • fd 被标记为 -:外部模块不应该直接操作底层资源

  • init()send() 被标记为 +:对外提供的稳定 API


三、C 语言视角下的 UML 类图

C 语言没有 class,但 UML 允许你"逻辑上当成 class"

在 C 项目中,UML 类图表达的是模块设计意图

1. C 语言中的工程约定

  • static 函数/变量 → UML 中的 -(private)
  • .h 中暴露的 API → UML 中的 +(public)
  • struct + 函数 → 逻辑上的一个"类"

2. C 语言示例代码

c 复制代码
typedef struct {
    UART_HandleTypeDef *huart;
    uint8_t rxBuf[128];
    uint16_t rxLen;
    UartState state;
} UartDriver_t;

void Uart_Init(UartDriver_t *drv, UART_HandleTypeDef *huart);
void Uart_Send(UartDriver_t *drv, uint8_t *buf, uint16_t len);
void Uart_StartReceive(UartDriver_t *drv);
UartState Uart_GetState(UartDriver_t *drv);

3. 对应的 UML 类图表示

注意UartDriver_t *drv 在 UML 中是隐含的 this,不需要画出来

复制代码
┌────────────────────────────────────┐
│            UartDriver              │
├────────────────────────────────────┤
│ - huart : UART_HandleTypeDef*      │
│ - rxBuf : uint8_t[128]             │
│ - rxLen : uint16_t                 │
│ - state : UartState                │
├────────────────────────────────────┤
│ + init(huart : UART_HandleTypeDef*)│
│ + send(buf : uint8_t*, len : u16)  │
│ + startReceive() : void            │
│ + getState() : UartState           │
└────────────────────────────────────┘

4. 设计含义说明

  • struct 成员在设计上属于 private 属性

    • → 即使语法上可访问,也不代表设计上允许访问
  • 对外函数即 UML 中的 public 方法

  • UartDriver_t *drv 是 C 语言模拟的 this 指针


四、关键理解总结(非常重要)

  1. UML 类图表达的是"边界",不是语法

  2. + / - / # 表达的是"谁能用",不是"怎么写"

  3. C 语言完全可以按照 UML 的类图思想来设计模块

  4. 一个设计良好的 C 模块,本质上就是一个 UML 类


补充说明

为什么这种理解很重要?

在嵌入式开发和系统编程中,即使使用 C 语言,我们仍然需要:

  • 模块化设计:清晰的接口边界
  • 封装性:隐藏实现细节
  • 可维护性:通过设计约束减少耦合

UML 类图为我们提供了一种语言无关的设计思维方式,帮助我们在 C 语言中也能实现良好的面向对象设计原则。

实践建议

  1. 设计先行:先画 UML 类图,再写代码
  2. 注释规范:在头文件中标注哪些是公开 API,哪些是内部使用
  3. 命名约定 :使用命名规范来体现模块边界(如 模块名_函数名
  4. 代码审查:检查是否有违反设计意图的访问行为
相关推荐
小林有点嵌2 小时前
UML之用例图学习
学习·microsoft·uml
wdfk_prog3 小时前
[Linux]学习笔记系列 -- [fs][fs_parser]
linux·笔记·学习
白帽子凯哥哥3 小时前
在学习SQL注入或XSS这类具体漏洞时,如何设计一个高效的“理论+实践”学习循环?
sql·学习·漏洞·xss
全栈陈序员3 小时前
v-if 和 v-for 的优先级是什么?
前端·javascript·vue.js·学习·前端框架·ecmascript
全栈陈序员3 小时前
你对 SPA 单页面应用的理解?它的优缺点分别是什么?如何实现 SPA 应用?
前端·vue.js·学习·前端框架·vue
soumns丶涛3 小时前
ESP32学习(1) - 点亮第一个LED
学习
全栈陈序员4 小时前
请描述下你对 Vue 生命周期的理解?在 `created` 和 `mounted` 中请求数据有什么区别?
前端·javascript·vue.js·学习·前端框架
代码游侠4 小时前
应用——UDP Socket 编程笔记
linux·运维·网络·笔记·网络协议·学习·udp
YJlio4 小时前
Windows Sysinternals 文件工具学习笔记(12.10):PendMoves + MoveFile 实战——重启后文件替换的安全姿势
windows·笔记·学习