Tip #48 避免使用全局变量,尤其是可变变量

原始链接:Golang Tip #48: Avoid Global Variables, Especially Mutable Ones.

全局变量是我们放在函数或方法之外的变量,可供我们代码的任何部分使用和更改。

001

现在,我并不是说所有全局变量都是坏消息,但它们带来的麻烦往往大于其价值。

原因如下(使用上面的代码示例):

  • 难以跟踪变化:当代码的任何部分都可以改变 featureConfig.NewCheckoutProcessEnabled 时,识别它被改变的位置会很困难。
  • 测试变得棘手:假设您正在测试新旧结帐流程。如果两个测试都涉及相同的全局 featureConfig,则您无法独立测试它们,因为其中一个测试会干扰另一个测试。
  • 并发问题:当多个请求同时尝试读取或更改 featureConfig 时,可能会导致不一致(竞态条件)。

“那么,解决方案是什么?”

答案是依赖注入。

这是一种从外部满足对象需求的方法,而不是让它自己创建或从全局变量获取:

002

是的,这种方法确实使事情变得有点复杂,但它也使得维护代码、测试代码和查找错误变得容易得多。

通过依赖注入,测试启用和禁用功能这两种场景变得非常简单:

003

但是如果您的全局变量不会改变,不需要测试并且必须这样工作,那么在这些情况下坚持使用全局变量可能会更好。

此外,如果您使用在运行时发生变化的全局变量,请确保使用同步技术(如互斥锁)来保证顺序。

简而言之,从全局状态转移到依赖注入可以让您的代码保持灵活性,并且不会过度依赖或紧密 “耦合”。