面向科学家和工程师的 SOLID 原则:让研究代码易于维护
Source: Dev.to
请提供您希望翻译的具体文本内容,我将按照要求进行简体中文翻译并保留原始的 Markdown 格式。
为什么你的研究代码需要更好的设计
它看起来很 innocently:一个 200 行的 Python 脚本能够完美地分析实验数据,导师也很满意。六个月后,这个脚本膨胀到 2,000 行,支持多种分析方法、几种仪器类型,以及一个“基本可用”的绘图系统。每加入一个新功能,都有可能破坏其他功能,而唯一懂得这段代码的人只有你——甚至你自己也不完全确定它们是如何组合在一起的。
你知道代码需要重构,但该从哪里开始?设计模式和软件架构资源往往针对 Web 应用和企业系统,而不是光谱数据分析或实验室设备控制。本系列正是为你而写。
Source: …
本系列覆盖内容
在接下来的几周里,我将发布一个 5 部分系列,介绍 SOLID 原则——一套使代码更易维护、可测试且可扩展的设计原则。每条原则都有单独的详细文章,配有完整、可运行的 Python 示例,示例取自真实的科学场景(不涉及购物车或用户认证)。
五大原则
| Principle | Tagline | Typical Scientific Use‑Case |
|---|---|---|
| Single Responsibility Principle | “One Class, One Job” | 将数据加载、分析和可视化分离。 |
| Open/Closed Principle | “Extending Without Breaking” | 在不修改已有代码的情况下添加新分析方法。 |
| Liskov Substitution Principle | “Interchangeable Components” | 安全地替换仪器驱动或文件解析器。 |
| Interface Segregation Principle | “Lean Interfaces” | 只提供每个组件实际需要的方法。 |
| Dependency Inversion Principle | “Depend on Abstractions” | 将高层管道逻辑与底层硬件细节解耦。 |
每篇文章包括:
- 一个贴近实际的科学问题。
- 展示问题的 “Before” 代码。
- 应用该原则后的 “After” 代码。
- 解释重构为何有帮助。
- 何时使用(以及何时可以跳过)该原则的指导。
谁应该阅读此文
- 博士生,他们的“临时”脚本现在需要支持多个实验室成员。
- 研究科学家,维护已经超出原始范围的代码。
- 工程师,害怕打开已有六个月历史的代码库。
- 实验室管理员,负责维护已离职学生编写的代码。
你不需要计算机科学学位或设计模式的知识。你只需要一段正变得越来越难以维护的代码。
如何识别何时应用 SOLID
| 开发阶段 | 典型需求 | SOLID 强度 |
|---|---|---|
| 探索性代码 | 快速数据探索 | 不需要 SOLID |
| 一次性脚本 | 简单分析 | 轻度 SOLID |
| 生产流水线(每日运行多年) | 可靠、可重复的处理 | 中等 SOLID |
| 可重用库(供整个研究团队使用) | 可扩展、可测试、可维护 | 高度 SOLID |
警示信号 表明是时候重构了:
- 更改数据加载方式会迫使在执行分析的同一文件中进行编辑。
- 添加新功能会破坏无关的功能。
- 将一个组件替换为另一个会产生奇怪的结果。
- 类中包含仅抛出
NotImplementedError的方法。 - 测试需要真实硬件或实际文件才能运行。
如果你对其中任何一项回答“是”,接下来的文章将准确告诉你该怎么做。
系列日程及预期内容
- 频率: 每周一次,从下周一开始。
- 阅读时间: 每篇约 15–20 分钟。
- 内容: 问题描述、前后代码、重构理由以及适用性指导。
第一篇(周一): 面向科学家和工程师的单一职责原则 —— 将通过一步步重构一个真实的光谱分析脚本,演示如何将单块代码拆分为聚焦且易维护的模块。
入门
看看你当前的代码库并自问:
- 当我需要更改数据加载方式时,是否必须编辑进行分析的同一个文件?
- 当我添加新功能时,是否会导致不相关的东西出错?
- 我是否曾经替换过组件却得到奇怪的结果?
- 我是否有只抛出
NotImplementedError的方法实现的类? - 我能否在不连接真实硬件或读取真实文件的情况下测试代码?
如果有任何答案是“是”,本系列将提供具体步骤帮助你改进代码。
欢迎留下评论,提出你想了解的问题或主题。祝编码愉快!