翻这套工业数据 WebApi 时,我注意到一种很轻的"上岗"方式:贴个标签,方法就进了调度。
代码里有个 [StrategyMethod] 特性,全仓命中 61 处。意思是:你不用去某张表、某个工厂里登记"我是策略",只要在方法上贴这个特性,框架扫一遍就把它收编。贴标签就上岗,比写一堆注册代码省事得多。
(等价改写,名字换掉了)它大致是这样用的:
[StrategyMethod("curve.decode")]
public void DecodeCurve(byte[] payload) { /* 业务处理 */ }
// 框架扫描所有 [StrategyMethod],按名字把方法挂进调度表
约定优于配置
这套思路叫"约定优于配置"。你遵守"贴标签"这个约定,框架就替你办完接入的杂活。好处是明显的:新增一个策略,不用动注册中心,不用改工厂的 switch,一个特性搞定。工业数据采集中,要处理的业务实体、曲线、记录文件类型很多,每加一种就贴一个,扩展面很平。
我没法确认这个特性是哪次需求催出来的,但更可能的情况是:早期策略还少,手写注册还能忍,等类型一多,就换成"贴标签"来摊平成本。
入口也藏进了标签
代价是入口变隐形了。一个方法到底被谁调用、什么时候生效,不再写在某处集中的代码里,而是分散在 61 个贴了标签的方法上。新人想找"某类数据是谁处理的",得先知道有这个扫描机制,再去全局搜特性名,而不是直接顺着一条调用链摸过去。
更微妙的是优先级与覆盖。当两处贴了同名标签,谁生效?这种规则往往不在方法旁边,而在扫描器的某段逻辑里。标签越多,这套"看不见的调度表"越难一眼看清。还有一个爱犯的毛病:标签上的代号拼错一个字母,启动时不报错,等到按代号翻花名册才告诉你找不到——编译期查不出,得跑起来才露馅。
贴标签省了登记的力气,代价是把"谁在上岗"这个答案,从一处明账变成了 61 处分散的小纸条。约定优于配置不是免费午餐,它只是把配置的成本,挪到了"你得记住有这个约定"的脑子里。