开发手记 · 第 8 / 9 篇 合集目录 ‹ 上一篇 下一篇 ›

读一套长期维护的工控软件架构时,有一点是它让我印象最深的:加一个功能页面,居然不用改主程序。

它的做法是,每个功能是一个独立的插件包,自己带一张清单,写明我要挂一个页面、我要提供一套参数设置。框架启动时挨个读清单,把插件挂到该挂的地方。主程序本身几乎是个空壳,只负责读清单、搭舞台。

我顺着这个思路往下看,发现模块之间不直接 new 依赖,而是向一个服务定位器要。要什么能力,问有没有实现某某接口的服务,拿到就用。接口是契约,实现可替换,只要新模块实现了同一个接口、注册进框架,就能替换掉老模块,调用方一行不用改。

最让我服气的是一次真实需求:要支持一种新品牌的下位机。换作以前,我得在主程序里改通信层的分支、改设备选择逻辑、改一堆配置。但在那套系统里,下位机通信是一个可替换的接口,只新建了一个通信插件,把协议写进去,框架按配置挑它,主程序一行没动。

可插拔的价值,不在酷,在边界清晰。当一个功能被关在自己的插件包里,它就不能随便去碰别的模块的内部;当它要被替换,你删掉这个包就行,不会在主程序里留下一地断线。当然插件化也不是白给的,间接层多了,追一个问题要绕几道弯,新人得先学这套扩展点的词汇,小项目上这么搞是给自己找麻烦。但那种要养很多年、不断加东西的系统,留插槽比焊死聪明太多。