副标题 / 摘要
全局对象让依赖变隐式,导致难以测试、难以演进。本文用例子说明其危害,并给出可行替代方案。
目标读者
- 需要提高可测试性的工程师
- 经常处理“隐式依赖”的开发者
- 负责代码质量的团队
背景 / 动机
全局对象看似方便,但会让模块互相耦合,导致“改一个地方牵一大片”。
这在大型系统里是灾难。
核心概念
- 隐式依赖:调用方不明确传入依赖
- 共享状态:多个模块写同一对象
- 测试隔离难:全局状态污染测试
实践指南 / 步骤
- 识别全局状态
- 用依赖注入替代
- 通过参数显式传递依赖
- 在测试中替换依赖
- 消除跨模块共享写入
可运行示例
# 反例:全局对象
CONFIG = {"rate": 0.1}
def calc(price):
return int(price * (1 - CONFIG["rate"]))
# 改进:显式注入
def calc_with_config(price, config):
return int(price * (1 - config["rate"]))
if __name__ == "__main__":
print(calc(100))
print(calc_with_config(100, {"rate": 0.2}))
解释与原理
全局对象让依赖隐藏在模块内部,测试时很难替换。
显式传递依赖可以让函数可复用、可测试。
常见问题与注意事项
配置放全局不是很方便吗?
方便但危险,建议在初始化阶段注入。全局常量也危险吗?
常量问题不大,主要问题在可变全局状态。如何迁移?
从最核心模块开始逐步消除全局依赖。
最佳实践与建议
- 用依赖注入替代全局对象
- 把配置集中在启动入口
- 尽量避免可变全局状态
小结 / 结论
全局对象是隐藏依赖的温床。
显式依赖是系统可测试与可维护的基础。
参考与延伸阅读
- Clean Code(隐式依赖问题)
- Dependency Injection 实践
元信息
- 阅读时长:6~8 分钟
- 标签:全局对象、反模式、可测试性
- SEO 关键词:Global Object, 隐式依赖
- 元描述:解释全局对象的危害与替代策略。
行动号召(CTA)
挑一个模块,把它对全局对象的依赖改成显式参数。