在这种情况下,我可以使用全局变量吗

Can I use a global variable in this scenario?

本文关键字:全局变量 可以使 我可以 这种情况下      更新时间:2023-10-16

在阅读了一些关于这个主题的SO线程之后:我提出了全局变量/单重项不好的原因。

  1. 越来越难以理解函数的全局状态,随着代码的增长,越来越多的函数将修改该全局状态
  2. 这使得单元测试更加困难
  3. 它隐藏依赖关系
  4. 如果有一天你的全局变量实际上不是一个单一的对象/变量,你将不得不重写代码

我想用C++制作一个游戏,在我的游戏中会有一个"heightmap对象"作为heightmap来代表世界的风景。此高度映射可以更改。我想为它使用一个全局对象。(我不希望遇到静态初始化顺序问题,因为不会有任何其他静态变量引用这个heightmap对象)。

现在,由于上述原因,我知道全局状态是坏的,全局可变状态甚至更糟。但是,做另一种选择似乎真的非常麻烦:在main()范围内创建一个heightmap对象,并将该heightmap对象传递给每个想要使用它的函数

如果我100%确定我的应用程序中只有一个高度图,该怎么办?此外,由于这是一个小型的单独项目,我相信我将能够理解每个函数对全局状态的影响?我看不出在这种情况下使用全局变量会对单元测试造成什么影响。如果我想使用mock heightmap,难道我不能在调用要测试的函数之前先执行globalHeightmap = generateMockHeightmap();吗?

尽管您现在对项目的特性很确定,但我可以向您保证,在未来的某个时候,您需要修改依赖于此全局变量的代码。到那时,全局变量可能会回来,使您更难弄清楚所需的更改,因为状态不是隐藏的(例如,如果您意外地更改了状态而不是从中读取,那么整个程序在未来的某个随机点会受到影响)。对于程序维护和调试来说,最大限度地减少状态突变点是多么重要,我怎么强调都不为过,全局变量与这一目标恰恰相反。

仅仅覆盖单元测试的全局状态映射似乎很脆弱。如果你需要恢复旧状态,或者在测试中的状态之间发生变异,该怎么办?然后,您会得到一堆保存/设置/恢复代码。

如果您想在应用程序中添加线程模型,该怎么办?使用全球状态将使这种转变变得更加复杂。

如果一年后有人帮你做这个项目怎么办?他们能理解代码吗?一年后你能理解它吗(我知道我总是试图写明显的代码,并在不具体的地方添加注释,因为我可能是一年后回来的人,不再记得任何关于机制的事情)。

最后,如果一个非全局变量方法看起来工作量太大或太复杂,这可能意味着你的替代方法太复杂或需要另一个想法/返工。没有理由不能将高度图隐藏到在适当的高级游戏对象中创建的对象中,并根据需要传递/存储在较低级别的对象中。