详细介绍:我不是架构师,但我也想少写点重复代码(C#软件框架)

为什么要写这份教程(引言)

在做非标自动化反复出现的,比如日志、线程、通讯、数据库、配方管理等等。就是项目的过程中,我常常遇到一个问题:不同项目之间就算需求不一样,但一些基础功能却
把旧项目的代码 Ctrl+C / Ctrl+V (CV工程师)每次都从头去写, 不仅费时间,还容易写得零散、不统一。

为了提高开发效率,也为了自己能更快上手新项目,我逐渐把这些通用模块整理出来,尝试做成一个可以复用的框架。
这份教程并不是一本高深的软件架构,而只是我在工作中一些实践经验的总结和分享,希望能给同行,尤其是刚入行的朋友,带来一些参考。

  • 软件开发中常见的问题:

    • 代码越写越乱,没有统一规范。

    • 模块耦合度高,维护困难。

    • 新人接手需要很久才能看懂逻辑。

  • 目的:

    • 让大家快速理解我的软件架构设计思路。

    • 让项目更容易扩展、维护。

    • 提高团队协作效率。

个人介绍

我本身重要从事计算机视觉和上位机软件开发,从业时间并不算很长,但在参与多个非标自动化项目的过程中,慢慢积累了一些实战经验。

更依赖一些就是在非标自动化行业,软件开发和传统企业级应用有所不同。它往往不需要特别繁琐的设计模式或庞大的架构体系,而高频使用的基础模块,例如:日志、消息机制、线程管理、TCP/Modbus 通讯、csv材料存储、配方管理等等。

这些模块虽然看起来都很常见,但在实际项目中几乎每次都会用到。不同任务的需求不一样,如果每次都从零去写,不仅效率不高,还可能因为写法不同导致后期维护麻烦。

为了提高开发效率,减少重复劳动,我在项目实践中逐渐整理出一套模块化的软件架构。这套架构并不是什么“先进的设计途径”,更多是结合行业特点和个人习惯总结出来的:

  • 够用、实用—— 解决实际问题,而不是追求过度设计;

  • 模块化—— 功能拆分清晰,便于复用;

  • 易于分享—— 封装成 DLL 分发给同事,避免再用低效的 Ctrl+C / Ctrl+V 方式复制代码。

这份教程,主要是把我在项目中总结的一些技巧点、编写思路和经验分享出来,供大家做个参考。每个人项目情况都不一样,所以这些内容不一定适合所有场景,大家可以结合自身搭配应用。

这里分享的更多是我个人在工作实践中的一些体会,不是标准答案,也谈不上最优解。希望它能给同样在做非标项目的开发者一些借鉴,给大家提一些开发思路,提升效率。

C#软件架构思想

整体来说,这套软件框架行分为三大部分:

  1. 系统核心功能(后端)

    • 这是整个框架的基础部分,包括日志、消息、线程、通讯、数据库、配方管理等模块。

    • 这些模块会被统一封装到 DLL 中,献出稳定、通用的接口。

    • 在不同的项目中,前端或业务逻辑都能够通过调用这些 DLL 来触发对应的能力。

  2. UI 界面设计(前端)

    • 前端部分主要根据具体项目需求来独立开发。

    • 界面中的按钮、菜单或事件,最终都会经过调用后端 DLL 的接口,来构建日志记录、材料存储、通讯交互等功能。

    • 这样前后端分离,前端只关注交互和展示,后端负责能力实现,结构清晰,维护方便。

  3. 脚本插件(扩展功能)

    • 脚本插件用于在框架之外扩展功能,比如快速增加新的业务逻辑或流程控制。

    • 这部分内容暂时不展开,本教程先聚焦于核心后端功能。

本教程的重点是系统核心作用(后端),也就是如何把常用的功能模块抽象出来,封装成 DLL,并在计划中高效复用。前端的开发则会根据具体项目需求单独实现,通过调用这些 DLL 来达成交互和逻辑。

1.日志系统

  • 功能定位:记录软件运行过程中的关键信息(调试、警告、错误、运行状态)。

  • 设计思路:

    • 支持多级别日志(Info、Warning、Error)。

    • 自动生成日志文件(按日期分文件)。

    • 可配置输出到控制台、档案或远程服务。

  • 使用场景:项目调试、问题追踪、运行监控。

2.消息机制

  • 功能定位:模块与模块之间的通信桥梁。

  • 设计思路:

    • 基于订阅-发布模式。

    • 模块依据消息总线传递,不直接耦合。

    • 支持异步消息队列,避免阻塞。

  • 使用场景:

    • 线程之间交换数据。

    • UI 界面与后台逻辑解耦。

    • 不同功能模块互通(如算法结果 → 界面显示)。

3.CSV数据存储

  • 功能定位:快速保存和读取表格型数据。

  • 设计思路:

    • 轻量级存储,不依赖数据库。

    • 给予统一接口读写 CSV。

    • 自动追加、按列格式化输出。

  • 使用场景:

    • 保存检测结果。

    • 记录运行信息。

    • 导出配置或日志供 Excel 查看。

4.异步存图

  • 功能定位:将相机采集或算法处理的图片异步保存。

  • 设计思路:

    • 独立线程负责存图,避免阻塞主流程。

    • 支持按时间戳、目录结构自动命名。

    • 可配置图像格式(BMP/PNG/JPEG)。

  • 使用场景:

    • 视觉检测项目中保存检测截图。

    • 故障时保存异常图像。

5.系统变量

  • 功能定位:软件运行过程中全局共享的一些基础参数。例如微信这些设置

  • 设计思路:

    • 存储应用级别的运行状态。

    • 提供统一接口进行读写,避免随意全局变量。

  • 使用场景:

    • 系统初始化参数(如路径、设备信息、窗口高、宽度)。

    • 项目级通用配置。

6.全局变量

  • 功能定位:程序运行期间可在多个模块访问的变量。

  • 设计思路:

    • 用统一类或容器进行管理。

    • 控制写入权限,避免混乱。

  • 使用场景:

    • 多线程共享一些只读数据。

    • 各模块间的公共开关或状态值。

7.型号配置变量

  • 功能定位:不同产品型号的配置信息。

  • 设计思路:

    • 每个型号单独配置文件(如 JSON/XML/CSV)。

    • 给予加载/切换接口,协助在线切换型号。

  • 使用场景:

    • 视觉检测项目中切换检测规则。

    • 不同生产型号的参数切换。

8.线程类

  • 功能定位:封装线程操作,简化多线程编写。

  • 设计思路:

    • 封装线程启动、停止、异常处理。

    • 支持循环执行、延时执行。

  • 使用场景:

    • 相机采集线程。

    • 通讯线程。

    • 数据处理线程。

9.脚本线程控制器

  • 功能定位:统一管理多个线程的生命周期。

  • 设计思路:

    • 提供启动、暂停、恢复、终止等控制。

    • 集中监控线程状态。

  • 使用场景:

    • 管理算法脚本或后台任务。

    • 需要同时运行多个独立线程时。

10.ModbusTCP通讯

  • 功能定位:与 PLC 或工业设备进行数据交互。

  • 设计思路:

    • 封装 ModbusTCP 协议。

    • 支持读写寄存器、线圈。

  • 使用场景:

    • 上位机与 PLC 进行工控通讯。

    • 设备状态监控与控制。

11.数据库

  • 功能定位:存储和查询结构化信息。

  • 设计思路:

    • 封装常用数据库操作(SQLite、MySQL、SQLServer)。

    • 提供统一接口,简化应用。

  • 使用场景:

    • 存储检测结果。

    • 保存用户运行记录。

    • 报表数据统计。

12.TCP客户端管理

  • 功能定位:管理多个 TCP 客户端的连接和信息。

  • 设计思路:

    • 统一管理连接池。

    • 供应心跳检测、自动重连。

  • 使用场景:

    • 一台 PC 同时连接多台设备。

    • 统一转发/调度消息。

13.TCP客户端

  • 功能定位:单个 TCP 客户端的通讯封装。

  • 设计思路:

    • 提供连接、发送、接收接口。

    • 帮助异步收发、事件回调。

  • 使用场景:

    • 与服务器交换检测结果。

    • 单机设备远程控制。

14.TCP服务端

  • 功能定位:接收客户端连接并进行数据交互。

  • 设计思路:

    • 支持多客户端连接。

    • 提供消息广播、单发。

  • 使用场景:

    • 上位机作为主控,接收下位机数据。

    • 集中管理多个客户端。

15.配方管理对象

  • 功能定位:管理不同工艺或检测配方的参数。

  • 设计思路:

    • 每个配方对应一组参数集合。

    • 提供新增、编辑、切换、保存功能。

  • 使用场景:

    • 工业生产线不同工艺的参数切换。

    • 视觉检测不同产品配方的快速切换。

功能模块封装:怎么分发和复用?

在项目里,日志、消息、线程这些东西,基本就是“到处都用”,但没必要“到处都写”。
要是每个项目都从头敲一遍,那不是开发,而是体力劳动了。
所以干脆封装成 DLL,一劳永逸,哪里应该点哪里。

那问题来了:是把所有东西打成一个“大礼包”,还是拆成小份,随取随用呢?


方案一:大一统框架(PiFramework.dll)

把日志、消息、线程、TCP、配置……统统打包进一个 PiFramework.dll,
项目里只要引用它,就像装了个“瑞士军刀”,啥作用都有。

优点

  • 超省心:一次引用,啥作用都齐活。

  • 模块互通:比如日志和全局变量可以手拉手直接配合。

  • 有气势:别人一看,“哟,这哥们有个完整的框架啊”。

缺点

  • 比较臃肿:就算你只想写个日志,也得背着 TCP、线程一起上路。

  • 更新不灵活:哪怕只改了一个小 Bug,也得重新发整套 DLL。

适用场景
适合内部团队用。大家一起用一个 DLL,不用再发代码片段,告别“Ctrl+C / Ctrl+V 开发模式”。版本统一,少扯皮。


方案二:自由拼装(按模块拆分 DLL)

把功能拆成多个小 DLL:

  • PiFramework.Log.dll(日志系统)

  • PiFramework.Notification.dll(消息机制)

  • PiFramework.Thread.dll(线程框架)

  • PiFramework.Net.dll(TCP/Modbus 通讯)

  • PiFramework.Config.dll(配置管理)

想用哪个加哪个,组合随意。

优点

  • 按需取用:就想写日志?那只引入 Log.dll 就够了。

  • 更新方便:更新 TCP,不会牵连日志。

缺点

  • 有依赖关系:比如线程模块可能还得带上日志模块。

  • 用的人得有点心思,知道自己要加哪些 DLL。

我自己用的就是方案一。说实话,我们这类软件体系也不算大,真没必要搞得七零八落的。要是每次更新还得到处找 DLL,就跟拼积木似的,维护量能把人劝退。一个 DLL 搞定,省心省力,哪天出 Bug 也知道去哪动手。

后续,我计划会在CSDN 上陆续发布这些模块的功能讲解和 DLL 封装教程,让大家许可边看边参考、边用边学习。不过毕竟工作忙,更新频率可能不会太快,希望大家理解。

总之,这份教程更多是经验分享与思路参考,希望对同样在做非标自动化任务的开发者有所支援,也欢迎大家在实践中结合自身需求灵活使用。


日志架构开发方法https://blog.csdn.net/qq_54122623/article/details/150564238?sharetype=blogdetail&sharerId=150564238&sharerefer=PC&sharesource=qq_54122623&spm=1011.2480.3001.8118

posted @ 2025-10-22 15:23  yjbjingcha  阅读(2)  评论(0)    收藏  举报