知识卡片
注册表是"有罪推定"的全局数据
内容
注册表本质上就是全局数据,即便包了一层方法封装,用起来也没那么轻松,作者的态度是:能靠常规的对象间引用找到目标对象,就尽量不用注册表,只有在实在没有其他可行路径时才考虑它。有两种更值得优先尝试的替代方案。参数传递:把常用数据作为参数一路传下去——缺点是很多时候这个参数并不是直接调用的方法要用,而是调用链更深几层之后的某个方法才真正需要,结果90%的传递工作都花在了”只是路过”这件事上,而注册表恰恰能省下这部分无谓的参数搬运。构造函数注入:在对象创建时把指向公共数据的引用一并传进去——代价是构造函数会多几个参数,但这份开销只发生一次(构造时),比起处处传参更集中;如果某份数据只被一部分类用到,这个办法尤其值得尝试,虽然多数情况下这样做仍然得不偿失。如果最终还是要用注册表,还有一个具体的实现选择:用一个显式的注册表类,还是直接用一个裸的映射(map)来存全局数据?作者倾向于显式类——因为它暴露的是一组具体、看得见的方法,你能直接从类的源码或文档里确认”能拿到什么、该用哪个方法”;而裸映射是未封装的,唯一能确定用了哪些键的办法是把系统里所有读写这个映射的地方都翻一遍,一旦要把某份数据的作用域从进程级改成线程级,裸映射的重构难度会明显更高。作者用一句很好记的原则收尾这整套讨论:任何全局数据在被证明无辜之前,都符合”有罪推定”原则——换句话说,默认怀疑、需要具体理由才能采用,而不是默认可用、需要具体理由才拒绝。
参考来源
- 位置:《企业应用架构模式》第二部分"模式"之"第18章 基本模式"之"18.5.2 使用时机"(源文件:_epub-src/OEBPS/Text/000221.html)
- 结论依据:原文说明"尽管经常在应用程序中见到可以使用注册表的某些形式,我还是尽可能通过常规的对象间引用来访问对象。基本上只有当没有其他可行途径时才可以使用注册表……我倾向于使用注册表这种显式的类……注册表还是有其用武之地的,但是务必牢记:任何全局数据在被证明无辜之前都符合'有罪推定'原则",直接支撑本卡结论。
- 原始内容:注册表还是有其用武之地的,但是务必牢记:任何全局数据在被证明无辜之前都符合"有罪推定"原则。