副标题 / 摘要

全局对象让依赖变隐式,导致难以测试、难以演进。本文用例子说明其危害,并给出可行替代方案。

目标读者

  • 需要提高可测试性的工程师
  • 经常处理“隐式依赖”的开发者
  • 负责代码质量的团队

背景 / 动机

全局对象看似方便,但会让模块互相耦合,导致“改一个地方牵一大片”。
这在大型系统里是灾难。

核心概念

  • 隐式依赖:调用方不明确传入依赖
  • 共享状态:多个模块写同一对象
  • 测试隔离难:全局状态污染测试

实践指南 / 步骤

  1. 识别全局状态
  2. 用依赖注入替代
  3. 通过参数显式传递依赖
  4. 在测试中替换依赖
  5. 消除跨模块共享写入

可运行示例

# 反例:全局对象
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}))

解释与原理

全局对象让依赖隐藏在模块内部,测试时很难替换。
显式传递依赖可以让函数可复用、可测试。

常见问题与注意事项

  1. 配置放全局不是很方便吗?
    方便但危险,建议在初始化阶段注入。

  2. 全局常量也危险吗?
    常量问题不大,主要问题在可变全局状态。

  3. 如何迁移?
    从最核心模块开始逐步消除全局依赖。

最佳实践与建议

  • 用依赖注入替代全局对象
  • 把配置集中在启动入口
  • 尽量避免可变全局状态

小结 / 结论

全局对象是隐藏依赖的温床。
显式依赖是系统可测试与可维护的基础。

参考与延伸阅读

  • Clean Code(隐式依赖问题)
  • Dependency Injection 实践

元信息

  • 阅读时长:6~8 分钟
  • 标签:全局对象、反模式、可测试性
  • SEO 关键词:Global Object, 隐式依赖
  • 元描述:解释全局对象的危害与替代策略。

行动号召(CTA)

挑一个模块,把它对全局对象的依赖改成显式参数。