先说结论
可以改成 static,但是!你现在这种写法有一个隐藏致命大坑,就算加上 static 也会出BUG。
先看你当前代码的问题
publicclassPipeTopologyConfiguration{publicdoubleTolerance=PipeTopologyConfig.Instance.Tolerance;publicstringLxField=PipeTopologyConfig.Instance.LxField;publicstringFxValue=PipeTopologyConfig.Instance.FxValue;}这几个是实例字段:只有你
new PipeTopologyConfiguration()创建对象的时候,才会从单例读取一次值,然后复制一份快照。
⚠️数据库配置后期修改、刷新缓存之后,这几个值不会自动更新!永远是第一次new时读到的旧值!
方案1:直接改成静态字段(❌依旧有快照过期问题,不推荐)
publicclassPipeTopologyConfiguration{publicstaticdoubleTolerance=PipeTopologyConfig.Instance.Tolerance;publicstaticstringLxField=PipeTopologyConfig.Instance.LxField;publicstaticstringFxValue=PipeTopologyConfig.Instance.FxValue;}缺陷:
静态字段只在第一次访问类的时候赋值 1 次。
你在界面修改数据库配置,调用LoadAllFromDatabase刷新了PipeTopologyConfig的缓存;
但是PipeTopologyConfiguration.Tolerance不会跟着变,一直保留旧数值,出现新旧配置两套数值,拓扑计算容差不生效,非常难排查。
方案2:最优写法 —— 静态只读属性(✅推荐,实时读取最新值)
不要存一份副本,每次外部读取的时候,现场去单例拿最新的数据,配置修改后立刻生效,零缓存过期问题。
publicstaticclassPipeTopologyConfiguration{publicstaticdoubleTolerance=>PipeTopologyConfig.Instance.Tolerance;publicstaticstringLxField=>PipeTopologyConfig.Instance.LxField;publicstaticstringFxValue=>PipeTopologyConfig.Instance.FxValue;}
=>是表达式体属性,没有后台字段,每次访问都会执行右边代码,实时从单例获取最新值。
调用方式完全没变,旧代码一行不用改:
doubletol=PipeTopologyConfiguration.Tolerance;对比三种方式的区别
| 写法 | 读取时机 | 配置修改后能否自动拿到新值 |
|---|---|---|
实例字段public double Tolerance = ... | new对象时读取一次 | ❌过期 |
静态字段public static double Tolerance = ... | 首次访问类读取一次 | ❌过期 |
静态属性public static double Tolerance => ... | 每次读取都去拿 | ✅实时最新 |
为什么建议直接做成 static class
publicstaticclassPipeTopologyConfiguration{publicstaticdoubleTolerance=>PipeTopologyConfig.Instance.Tolerance;publicstaticstringLxField=>PipeTopologyConfig.Instance.LxField;publicstaticstringFxValue=>PipeTopologyConfig.Instance.FxValue;}- 不需要
new; - 兼容你所有历史旧代码;
- 起到一层别名兼容层,以后就算底层配置实现改了,上层业务代码完全不用动;
- 永远实时读取数据库刷新后的最新参数,不会出现配置改了但是程序仍然用旧容差的隐蔽BUG。
如果你原来大量业务代码已经写死PipeTopologyConfiguration.Tolerance
这套就是完美兼容过渡方案,不需要到处改代码,只把这个类换成上面静态属性版本即可。
如果你需要,我也可以给你一份带注释、完整可以直接覆盖粘贴的最终版代码。