只有懒惰的人还没有写过有关全局变量如何有害的文章。 它始于1973年,当时W. Wulf等人。 声称 “非局部变量是难以理解的程序的主要贡献因素。”
从那时起, 许多其他理由建议说服程序员停止使用全局变量。 我想我读了全部 ,但是没有找到最困扰我的一个:可组合性。
简而言之,全局变量使代码难以或不可能以与原始作者所期望的方式不同的方式进行编写。
我最近在Sinatra上用Ruby为Zold编写了Web Front。 这是Web服务器根据其文档启动的方式:
App.start!
从这里start!
是App
类的静态方法,您必须将其声明为其默认父Sinatra::Base
的子代。 要告诉应用程序要监听哪个TCP端口,您必须对其进行预配置:
require 'sinatra/base'
class App < Sinatra::Base
get '/' do
'Hello, world!'
end
end
App.set(:port, 8080)
App.start!
如果要启动两个Web服务器,该怎么办? 为了进行测试,这可能是很合乎逻辑的要求。 例如,由于Zold是一个分布式网络,因此有必要测试许多服务器之间如何通信。 我做不到! 绝对没有办法。 因为Sinatra的设计假设是在整个应用程序范围内只能存在一台服务器。
这真的可以解决吗? 让我们看看他们的代码 。 Sinatra::Base
类本质上是Singleton ,不应具有多个实例。 当我们调用App.set(:port, 8080)
,值8080
将保存到单个实例的属性中。 数字8080
可用于Sinatra::Base
所有方法,无论从何实例调用它们。
我相信,他们没有使用真正的 Ruby全局变量,因为他们知道它们是不好的。 他们到底为什么不好,以及替代方案是什么?
从技术上讲,他们的设计是“全球范围的”。 Sinatra::Base
将整个应用程序视为其可见范围。 无论是谁调用它,所有内容都是可见的,包括先前调用和先前实例化的对象中创建的内容。 这个“类”是一大堆全局变量。
每个全局变量都是这种麻烦制造者。 尽管应用程序很小,并且测试覆盖率很低,但是全局变量可能不会受到损害。 但是,应用程序越大,其自动化测试方案越复杂,根据全局变量,单例或类变量来组合对象的难度就越大。
我的推荐? 在任何情况下都不会考虑任何全局变量。
翻译自: https://www.javacodegeeks.com/2018/07/whats-wrong-global-variables.html