Skip to content
Gains Summary
Main Navigation 首页 / Home
C++ 编程 / C++ Programming
系统与高性能 / Systems & Performance
Web 开发 / Web Development
人工智能 / Artificial Intelligence
工业软件 / Industrial Software
其他内容 / Other Topics
C++ 编程 / C++系统与性能 / SystemsWeb 开发 / Web人工智能 / AI工业软件 / Industrial

外观

Sidebar Navigation

← C++ 编程 / C++ Programming

插件系统 / Plugin Systems

1. 插件工程:可演进的模块边界 / Plugin Engineering and Evolvable Module Boundaries

2. 运行时动态加载:LoadLibrary 与 dlopen —— 打开插件的大门 / Runtime Dynamic Loading with LoadLibrary and Dlopen

3. 插件接口设计:C ABI、函数表与受控 C++ 接口 / Plugin Interface Design with C ABI, Function Tables, and Controlled C++ Interfaces

4. CMake 构建完整插件项目 / Building a Complete Plugin Project with CMake

5. 插件架构设计模式:发现、生命周期、依赖与通信 / Plugin Architecture Patterns for Discovery, Lifecycle, Dependencies, and Communication

6. 跨平台插件开发:Windows / Linux / macOS 统一策略

7. 插件热加载与版本管理 / Plugin Hot Reloading and Version Management

8. 插件安全:沙箱、进程隔离与权限控制 / Plugin Security with Sandboxing, Process Isolation, and Permissions

9. 工业软件插件系统案例分析 / Industrial Software Plugin System Case Study

10. 综合实战:版本化 C ABI 插件系统 / Full Project: Versioned C ABI Plugin System

本页目录

工业软件插件系统案例分析 / Industrial Software Plugin System Case Study ​

📅 创建时间:2026-07-13 🏷️ 标签:#工业软件 #插件系统 #FreeCAD #ParaView #案例分析 📚 前置知识:plugin architecture patterns, overview


📋 本章目标 ​

  • 了解工业软件插件生态的三种典型架构
  • 深入分析 FreeCAD 的 Workbench 模块化机制
  • 理解 ParaView 的 Plugin Manager 与 VTK 管线集成
  • 对比不同插件架构的 trade-off
  • 将前面学到的插件开发知识应用于理解真实系统

第1部分:工业软件插件生态全景 ​

┌─────────────────────────────────────────────────────────────────────────────┐
│              工业软件插件架构的三种典型模式                                    │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  模式1:宏/脚本录制型                                                        │
│  ┌───────────────────────────────────────────────────────────────┐         │
│  │ 代表:AutoCAD AutoLISP、3ds Max MAXScript、Rhino PythonScript  │         │
│  │                                                               │         │
│  │ 特点:                                                        │         │
│  │ • 内嵌脚本引擎(Lua/Python/自研DSL)                           │         │
│  │ • 用户可录制操作 → 生成脚本 → 回放                             │         │
│  │ • "插件"实际上是脚本文件                                        │         │
│  │ • 入门门槛低(不需要编译)                                      │         │
│  │ • 性能有限(脚本引擎开销)                                      │         │
│  └───────────────────────────────────────────────────────────────┘         │
│                                                                             │
│  模式2:C++ 插件 / 动态库型                                                  │
│  ┌───────────────────────────────────────────────────────────────┐         │
│  │ 代表:ParaView Plugin、FreeCAD C++ Module、Abaqus UMAT        │         │
│  │                                                               │         │
│  │ 特点:                                                        │         │
│  │ • 编译型插件(.dll / .so),性能等同于主程序                    │         │
│  │ • 通过定义好的 C++ 接口或 Fortran 接口接入                      │         │
│  │ • 入口门槛高(需要编译环境、理解 API)                          │         │
│  │ • 适合:求解器、数据处理、高性能模块                            │         │
│  └───────────────────────────────────────────────────────────────┘         │
│                                                                             │
│  模式3:混合型                                                               │
│  ┌───────────────────────────────────────────────────────────────┐         │
│  │ 代表:FreeCAD、Blender、QGIS                                   │         │
│  │                                                               │         │
│  │ 特点:                                                        │         │
│  │ • C++ 核心引擎 + Python 接口层 + Python 插件                   │         │
│  │ • Python 插件可调用编译好的 C++ 函数(通过 pybind11 等绑定)   │         │
│  │ • 兼顾性能(核心用 C++)和易用性(插件用 Python)               │         │
│  └───────────────────────────────────────────────────────────────┘         │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

第2部分:FreeCAD —— Workbench 模块化架构 ​

2.1 架构总览 ​

┌─────────────────────────────────────────────────────────────────────────────┐
│              FreeCAD 的模块化架构                                             │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────┐           │
│  │                    FreeCAD 应用程序                          │           │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐         │           │
│  │  │  GUI 层     │  │  App 层     │  │  Base 层    │         │           │
│  │  │  (Qt)       │  │  (文档/对象) │  │  (基础类型)  │         │           │
│  │  └─────────────┘  └─────────────┘  └─────────────┘         │           │
│  └─────────────────────────────────────────────────────────────┘           │
│                                    │                                        │
│                    ┌───────────────┼───────────────┐                        │
│                    ▼               ▼               ▼                        │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐                       │
│  │  Part    │ │  Sketcher│ │  Mesh    │ │  FEM     │  ← Workbench(就是插件)│
│  │  Design  │ │          │ │  Design  │ │  Solver  │                        │
│  └──────────┘ └──────────┘ └──────────┘ └──────────┘                       │
│                                                                             │
│  每个 Workbench = 一个 C++ 动态库模块                                        │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

2.2 Workbench 的双语言策略 ​

每个 Workbench 通常包含两部分:

python
# ====== Init.py — Python 侧:注册 Workbench ======
class FemWorkbench(Workbench):
    """有限元分析工作台"""

    def __init__(self):
        self.__class__.Icon = FreeCAD.getResourceDir() + "Mod/Fem/fem.svg"
        self.__class__.MenuText = "FEM"
        self.__class__.ToolTip = "有限元分析工作台"

    def Initialize(self):
        # 导入编译好的 C++ 模块
        import Fem
        # 注册命令(Python 包装的 C++ 操作)
        import FemCommands
        # 设置工具栏和菜单
        self.appendToolbar("FEM", ["FEM_Solver", "FEM_Material"])

    def Activated(self):
        # 切换到 FEM Workbench 时,加载对应的 C++ .so
        pass

Gui.addWorkbench(FemWorkbench())
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
cpp
// ====== C++ 侧:核心计算逻辑 ======
// 编译为 Fem.so (或 Fem.pyd),通过 pybind11 暴露给 Python
#include <pybind11/pybind11.h>

namespace py = pybind11;

// C++ 求解器核心(性能关键部分)
class Solver {
public:
    void setMesh(const Mesh& mesh);
    Results solve();
};

// 绑定到 Python
PYBIND11_MODULE(Fem, m) {
    py::class_<Solver>(m, "Solver")
        .def(py::init<>())
        .def("set_mesh", &Solver::setMesh)
        .def("solve", &Solver::solve);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

2.3 FreeCAD 插件模式的 trade-off ​

┌─────────────────────────────────────────────────────────────────────────────┐
│              FreeCAD 设计决策                                                 │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  ✅ 优势:                                                                    │
│  • Python 插件 = 开发快、门槛低、社区活跃                                     │
│  • C++ 核心 = 计算性能不妥协                                                  │
│  • 双语言让"不同水平"的开发者都能贡献                                         │
│                                                                             │
│  ❌ 代价:                                                                    │
│  • C++/Python 之间的桥接层(cbindings)是维护负担                               │
│  • 版本升级时 Python API 可能 break                                          │
│  • 调试跨越 C++/Python 边界的问题很痛苦                                       │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

第3部分:ParaView —— 科学可视化插件系统 ​

3.1 架构 ​

┌─────────────────────────────────────────────────────────────────────────────┐
│              ParaView Plugin Manager                                         │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  宿主(ParaView Client/Server)                                              │
│  ┌─────────────────────────────────────────────────────────────┐           │
│  │                                                              │           │
│  │  Plugin Manager                                              │           │
│  │  ┌──────────┐  ┌──────────┐  ┌──────────┐                  │           │
│  │  │ 发现     │  │ 加载     │  │ 配置     │                  │           │
│  │  │XML扫描   │  │dlopen   │  │GUI配置   │                  │           │
│  │  └──────────┘  └──────────┘  └──────────┘                  │           │
│  │                                                              │           │
│  └─────────────────────────────────────────────────────────────┘           │
│         │                    │                    │                         │
│         ▼                    ▼                    ▼                         │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐                                  │
│  │ Filter   │  │ Reader   │  │ Writer   │   ← 插件类型                      │
│  │ Plugin   │  │ Plugin   │  │ Plugin   │                                  │
│  │ (处理数据)│  │ (读取格式)│  │ (写出格式)│                                  │
│  └──────────┘  └──────────┘  └──────────┘                                  │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

3.2 插件定义——ServerManager XML ​

ParaView 的插件通过 XML 声明自己提供的 filter/reader/writer:

xml
<!-- MyFilter.xml -->
<ServerManagerConfiguration>
  <ProxyGroup name="filters">
    <SourceProxy name="MyCustomFilter"
                 class="vtkMyCustomFilter"
                 label="My Custom Filter">
      <InputProperty name="Input"
                     command="SetInputConnection">
        <ProxyGroupDomain name="groups">
          <Group name="sources"/>
          <Group name="filters"/>
        </ProxyGroupDomain>
      </InputProperty>
      <DoubleVectorProperty name="Threshold"
                            command="SetThreshold"
                            number_of_elements="1"
                            default_values="0.5">
      </DoubleVectorProperty>
    </SourceProxy>
  </ProxyGroup>
</ServerManagerConfiguration>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
cpp
// vtkMyCustomFilter.cxx —— C++ 实现
class vtkMyCustomFilter : public vtkDataSetAlgorithm {
public:
    static vtkMyCustomFilter* New();
    vtkTypeMacro(vtkMyCustomFilter, vtkDataSetAlgorithm);

    void SetThreshold(double t) { Threshold = t; }

protected:
    int RequestData(vtkInformation*,
                    vtkInformationVector**,
                    vtkInformationVector*) override;
    double Threshold = 0.5;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14

ParaView 在启动时扫描插件目录中的 XML 文件 → 解析出插件类型 → 按需加载 .so → 注册到 Pipeline Browser。

3.3 VTK Pipeline 集成 ​

ParaView 的插件系统深度集成在 VTK Pipeline 中——这和我们之前学的通用插件系统最大的不同:

数据流:Source → Filter1 → Filter2 → ... → Mapper → Render

每个 Filter 都可以是插件!插件通过 vtkObjectFactory 机制
注册到 VTK 的类工厂,之后 VTK Pipeline 就能自动使用它们。
1
2
3
4

第4部分:Trade-off 总结 ​

┌─────────────────────────────────────────────────────────────────────────────┐
│              不同插件架构的取舍                                               │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  维度           │  C++ 动态库    │  脚本(Python等)  │  混合型               │
│  ───────────────┼────────────────┼──────────────────┼───────────────────────│
│  性能           │ ★★★★★ 原生    │ ★★☆☆☆ 解释      │ ★★★★☆ 核心C++       │
│  开发速度       │ ★★☆☆☆ 编译    │ ★★★★★ 即改即跑  │ ★★★★☆               │
│  分发难度       │ ★★★☆☆ ABI坑  │ ★★★★★ 跨平台    │ ★★★☆☆               │
│  安全性         │ ★★☆☆☆ 难控制  │ ★★★★☆ 可沙箱    │ ★★★☆☆               │
│  调试难度       │ ★★★☆☆         │ ★★★★☆          │ ★★☆☆☆ 跨语言难       │
│  社区门槛       │ ★★☆☆☆ 高      │ ★★★★★ 低        │ ★★★☆☆               │
│  适合场景       │ 求解器/引擎     │ 自动化/UI扩展    │ CAD/BIM等大型桌面软件 │
│                                                                             │
│  核心认知:没有最佳方案,只有最适合具体场景的方案                              │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

核心总结 ​

┌─────────────────────────────────────────────────────────────────────────────┐
│              工业软件插件系统 核心要点                                         │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  三种模式:脚本型(轻量易用)/ C++型(高性能)/ 混合型(平衡)                 │
│                                                                             │
│  FreeCAD:Python Workbench + C++ 模块                                        │
│    → 双语言策略降低社区贡献门槛同时保证核心性能                               │
│                                                                             │
│  ParaView:XML 声明 + C++ 实现 + VTK Pipeline 深度集成                       │
│    → 解决"科学数据可视化管线"这个特定问题的最优方案                           │
│                                                                             │
│  通用插件系统(我们的 00-12 篇)vs 领域专用系统(工业软件)                    │
│    → 领域专用系统更深度集成到业务逻辑,但也更不通用                             │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

章节测试 ​

测试1:三种模式 ​

工业软件的三种插件模式分别是什么?它们各自最适合什么场景?

测试2:FreeCAD 的双语言 ​

FreeCAD 为什么选择 Python + C++ 混合策略?这种策略的主要代价是什么?

测试3:通用 vs 专用 ​

第 06-12 篇构建的通用插件系统,和 ParaView 的插件系统有什么本质不同?


参考答案 ​

测试1答案 ​

答案:(1) 脚本型:适合自动化操作、UI 定制、快速原型;(2) C++ 动态库型:适合求解器、Reader/Writer、高性能数据处理;(3) 混合型:适合 CAD/BIM 等需要兼顾性能和易用性的大型桌面软件。

测试2答案 ​

答案:选择理由:(1) Python 降低插件开发门槛,吸引更广泛的社区贡献;(2) C++ 保证几何内核、求解器等计算密集型模块的性能;(3) pybind11 等绑定工具让两种语言可以交互。主要代价:(1) C++/Python 之间的桥接层是维护负担;(2) 跨语言调试困难;(3) 版本升级时 Python API 可能 break。

测试3答案 ​

答案:通用插件系统提供"任何类型的插件都可以加载"的框架(接口 + 发现 + 加载 + 生命周期),不关心插件具体做什么。ParaView 的插件系统深度集成在 VTK Pipeline 中——插件必须是特定类型(Filter/Reader/Writer),遵循特定的数据流模型。通用系统更灵活但集成度低,专业系统集成度高但限制了"插件能做什么"的范围。


相关笔记 ​

  • overview - 工业软件学习路线
  • plugin architecture patterns - 插件架构设计模式
  • full plugin project - 从零构建完整插件系统

下一步学习 ​

  • [ ] 阅读 14 - 综合实战:从零构建完整插件系统 —— 把全部知识串起来

学习状态:🟡 开始学习

工程深化:把本篇知识落到项目里 ​

这一节不是为了凑篇幅,而是把《工业软件插件系统案例分析 / Industrial Software Plugin System Case Study》从“知道概念”推进到“能在项目里稳定使用”。 阅读时可以把每个知识点都追问成四件事:它保护什么边界,失败时有什么现象,怎样最小复现,怎样写进团队流程。

text
concept -> boundary -> failure signal -> minimal proof -> project rule
1

工程切片 1:最小可复现样例 ​

**场景。**围绕 插件发现 建一个很小的案例,不要一开始就放进完整业务系统。把问题压缩到一个可以提交给同事的目录,保留源码、构建命令、版本输出和预期现象。

**边界。**先判断这里讨论的是 插件发现、加载器 还是 契约 的责任;如果三者混在一起,先把输入、输出和所有权拆开。

text
input -> 插件发现 -> 加载器 -> 契约 -> observable result
1

**验证。**记录一条能重复运行的命令或测试,并写明成功输出和失败输出。只说“本机能跑”不够,至少要记录工具版本、构建类型和关键参数。

**常见错误。**把偶然通过当成规则、把私有实现当成公开契约、或者让错误路径绕开清理逻辑,都会让本篇主题在真实项目里变得不可维护。

**复盘问题。**如果明天换一个编译器、Qt 版本、插件版本、输入规模或发布目录,这个结论是否仍成立?不成立时,应该由文档、测试还是 CI 给出提示?

工程切片 2:接口边界 ​

**场景。**围绕 加载器 建一个很小的案例,不要一开始就放进完整业务系统。写清调用方能依赖什么、不能依赖什么,并把隐式假设转换成命名函数、配置项或测试。

**边界。**先判断这里讨论的是 加载器、契约 还是 生命周期 的责任;如果三者混在一起,先把输入、输出和所有权拆开。

text
input -> 加载器 -> 契约 -> 生命周期 -> observable result
1

**验证。**记录一条能重复运行的命令或测试,并写明成功输出和失败输出。只说“本机能跑”不够,至少要记录工具版本、构建类型和关键参数。

**常见错误。**把偶然通过当成规则、把私有实现当成公开契约、或者让错误路径绕开清理逻辑,都会让本篇主题在真实项目里变得不可维护。

**复盘问题。**如果明天换一个编译器、Qt 版本、插件版本、输入规模或发布目录,这个结论是否仍成立?不成立时,应该由文档、测试还是 CI 给出提示?

工程切片 3:失败注入 ​

**场景。**围绕 契约 建一个很小的案例,不要一开始就放进完整业务系统。故意制造一个常见错误,让日志、断言或测试先失败,再用修复后的证据说明规则生效。

**边界。**先判断这里讨论的是 契约、生命周期 还是 隔离 的责任;如果三者混在一起,先把输入、输出和所有权拆开。

text
input -> 契约 -> 生命周期 -> 隔离 -> observable result
1

**验证。**记录一条能重复运行的命令或测试,并写明成功输出和失败输出。只说“本机能跑”不够,至少要记录工具版本、构建类型和关键参数。

**常见错误。**把偶然通过当成规则、把私有实现当成公开契约、或者让错误路径绕开清理逻辑,都会让本篇主题在真实项目里变得不可维护。

**复盘问题。**如果明天换一个编译器、Qt 版本、插件版本、输入规模或发布目录,这个结论是否仍成立?不成立时,应该由文档、测试还是 CI 给出提示?

工程切片 4:跨平台差异 ​

**场景。**围绕 生命周期 建一个很小的案例,不要一开始就放进完整业务系统。至少比较 Windows、Linux 或不同编译器下的一个差异,记录差异属于标准、实现还是平台约定。

**边界。**先判断这里讨论的是 生命周期、隔离 还是 诊断 的责任;如果三者混在一起,先把输入、输出和所有权拆开。

text
input -> 生命周期 -> 隔离 -> 诊断 -> observable result
1

**验证。**记录一条能重复运行的命令或测试,并写明成功输出和失败输出。只说“本机能跑”不够,至少要记录工具版本、构建类型和关键参数。

**常见错误。**把偶然通过当成规则、把私有实现当成公开契约、或者让错误路径绕开清理逻辑,都会让本篇主题在真实项目里变得不可维护。

**复盘问题。**如果明天换一个编译器、Qt 版本、插件版本、输入规模或发布目录,这个结论是否仍成立?不成立时,应该由文档、测试还是 CI 给出提示?

工程切片 5:性能观察 ​

**场景。**围绕 隔离 建一个很小的案例,不要一开始就放进完整业务系统。用小规模和压力规模各跑一次,区分算法成本、同步成本、I/O 成本和工具链配置成本。

**边界。**先判断这里讨论的是 隔离、诊断 还是 插件发现 的责任;如果三者混在一起,先把输入、输出和所有权拆开。

text
input -> 隔离 -> 诊断 -> 插件发现 -> observable result
1

**验证。**记录一条能重复运行的命令或测试,并写明成功输出和失败输出。只说“本机能跑”不够,至少要记录工具版本、构建类型和关键参数。

**常见错误。**把偶然通过当成规则、把私有实现当成公开契约、或者让错误路径绕开清理逻辑,都会让本篇主题在真实项目里变得不可维护。

**复盘问题。**如果明天换一个编译器、Qt 版本、插件版本、输入规模或发布目录,这个结论是否仍成立?不成立时,应该由文档、测试还是 CI 给出提示?

工程切片 6:生命周期 ​

**场景。**围绕 诊断 建一个很小的案例,不要一开始就放进完整业务系统。标出资源创建、转移、共享、停止和销毁的顺序,特别关注错误返回和提前退出路径。

**边界。**先判断这里讨论的是 诊断、插件发现 还是 加载器 的责任;如果三者混在一起,先把输入、输出和所有权拆开。

text
input -> 诊断 -> 插件发现 -> 加载器 -> observable result
1

**验证。**记录一条能重复运行的命令或测试,并写明成功输出和失败输出。只说“本机能跑”不够,至少要记录工具版本、构建类型和关键参数。

**常见错误。**把偶然通过当成规则、把私有实现当成公开契约、或者让错误路径绕开清理逻辑,都会让本篇主题在真实项目里变得不可维护。

**复盘问题。**如果明天换一个编译器、Qt 版本、插件版本、输入规模或发布目录,这个结论是否仍成立?不成立时,应该由文档、测试还是 CI 给出提示?

工程切片 7:诊断证据 ​

**场景。**围绕 插件发现 建一个很小的案例,不要一开始就放进完整业务系统。保留命令、日志、符号、栈、测试输出或截图,让结论可以被另一个环境重新验证。

**边界。**先判断这里讨论的是 插件发现、加载器 还是 契约 的责任;如果三者混在一起,先把输入、输出和所有权拆开。

text
input -> 插件发现 -> 加载器 -> 契约 -> observable result
1

**验证。**记录一条能重复运行的命令或测试,并写明成功输出和失败输出。只说“本机能跑”不够,至少要记录工具版本、构建类型和关键参数。

**常见错误。**把偶然通过当成规则、把私有实现当成公开契约、或者让错误路径绕开清理逻辑,都会让本篇主题在真实项目里变得不可维护。

**复盘问题。**如果明天换一个编译器、Qt 版本、插件版本、输入规模或发布目录,这个结论是否仍成立?不成立时,应该由文档、测试还是 CI 给出提示?

工程切片 8:维护策略 ​

**场景。**围绕 加载器 建一个很小的案例,不要一开始就放进完整业务系统。把一次性经验沉淀到 README、CI、脚本、示例工程或检查表里,避免只存在个人记忆中。

**边界。**先判断这里讨论的是 加载器、契约 还是 生命周期 的责任;如果三者混在一起,先把输入、输出和所有权拆开。

text
input -> 加载器 -> 契约 -> 生命周期 -> observable result
1

**验证。**记录一条能重复运行的命令或测试,并写明成功输出和失败输出。只说“本机能跑”不够,至少要记录工具版本、构建类型和关键参数。

**常见错误。**把偶然通过当成规则、把私有实现当成公开契约、或者让错误路径绕开清理逻辑,都会让本篇主题在真实项目里变得不可维护。

**复盘问题。**如果明天换一个编译器、Qt 版本、插件版本、输入规模或发布目录,这个结论是否仍成立?不成立时,应该由文档、测试还是 CI 给出提示?

工程切片 9:版本演进 ​

**场景。**围绕 契约 建一个很小的案例,不要一开始就放进完整业务系统。为未来变更预留兼容策略:版本号、特性位、弃用窗口、迁移脚本和回滚入口。

**边界。**先判断这里讨论的是 契约、生命周期 还是 隔离 的责任;如果三者混在一起,先把输入、输出和所有权拆开。

text
input -> 契约 -> 生命周期 -> 隔离 -> observable result
1

**验证。**记录一条能重复运行的命令或测试,并写明成功输出和失败输出。只说“本机能跑”不够,至少要记录工具版本、构建类型和关键参数。

**常见错误。**把偶然通过当成规则、把私有实现当成公开契约、或者让错误路径绕开清理逻辑,都会让本篇主题在真实项目里变得不可维护。

**复盘问题。**如果明天换一个编译器、Qt 版本、插件版本、输入规模或发布目录,这个结论是否仍成立?不成立时,应该由文档、测试还是 CI 给出提示?

工程切片 10:最小消费者 ​

**场景。**围绕 生命周期 建一个很小的案例,不要一开始就放进完整业务系统。从使用者角度写一个小程序或小工程,只依赖公开接口,验证安装包、头文件和运行时行为。

**边界。**先判断这里讨论的是 生命周期、隔离 还是 诊断 的责任;如果三者混在一起,先把输入、输出和所有权拆开。

text
input -> 生命周期 -> 隔离 -> 诊断 -> observable result
1

**验证。**记录一条能重复运行的命令或测试,并写明成功输出和失败输出。只说“本机能跑”不够,至少要记录工具版本、构建类型和关键参数。

**常见错误。**把偶然通过当成规则、把私有实现当成公开契约、或者让错误路径绕开清理逻辑,都会让本篇主题在真实项目里变得不可维护。

**复盘问题。**如果明天换一个编译器、Qt 版本、插件版本、输入规模或发布目录,这个结论是否仍成立?不成立时,应该由文档、测试还是 CI 给出提示?

工程切片 11:边界复盘 ​

**场景。**围绕 隔离 建一个很小的案例,不要一开始就放进完整业务系统。用一张表说明问题发生在源码、编译、链接、加载、运行、关闭或发布中的哪一层。

**边界。**先判断这里讨论的是 隔离、诊断 还是 插件发现 的责任;如果三者混在一起,先把输入、输出和所有权拆开。

text
input -> 隔离 -> 诊断 -> 插件发现 -> observable result
1

**验证。**记录一条能重复运行的命令或测试,并写明成功输出和失败输出。只说“本机能跑”不够,至少要记录工具版本、构建类型和关键参数。

**常见错误。**把偶然通过当成规则、把私有实现当成公开契约、或者让错误路径绕开清理逻辑,都会让本篇主题在真实项目里变得不可维护。

**复盘问题。**如果明天换一个编译器、Qt 版本、插件版本、输入规模或发布目录,这个结论是否仍成立?不成立时,应该由文档、测试还是 CI 给出提示?

工程切片 12:反例训练 ​

**场景。**围绕 诊断 建一个很小的案例,不要一开始就放进完整业务系统。写出一个看似能工作但不可维护的方案,再说明它在规模、团队协作或发布时会怎样失败。

**边界。**先判断这里讨论的是 诊断、插件发现 还是 加载器 的责任;如果三者混在一起,先把输入、输出和所有权拆开。

text
input -> 诊断 -> 插件发现 -> 加载器 -> observable result
1

**验证。**记录一条能重复运行的命令或测试,并写明成功输出和失败输出。只说“本机能跑”不够,至少要记录工具版本、构建类型和关键参数。

**常见错误。**把偶然通过当成规则、把私有实现当成公开契约、或者让错误路径绕开清理逻辑,都会让本篇主题在真实项目里变得不可维护。

**复盘问题。**如果明天换一个编译器、Qt 版本、插件版本、输入规模或发布目录,这个结论是否仍成立?不成立时,应该由文档、测试还是 CI 给出提示?

本篇收束 ​

掌握《工业软件插件系统案例分析 / Industrial Software Plugin System Case Study》的标志,不是记住所有名词,而是能把 插件发现、加载器、契约、生命周期、隔离、诊断 放进一条可验证的工程链路。 先用最小样例建立判断,再用测试和脚本固定判断,最后把失败证据留给未来的自己和团队。

最后更新于:

Pager
上一篇8. 插件安全:沙箱、进程隔离与权限控制 / Plugin Security with Sandboxing, Process Isolation, and Permissions
下一篇10. 综合实战:版本化 C ABI 插件系统 / Full Project: Versioned C ABI Plugin System

持续记录,持续成长

Copyright © Tidenflow