全局静态类和方法都不好吗?
人们普遍认为,应该避免严重依赖全球性的东西。 不会使用静态类和方法是一回事吗?
全球数据不好。 但是,使用静态方法可以避免许多问题。
我将在这个问题上采取Rich Hickey的立场,并解释如下:
要在C#中构建最可靠的系统,请使用静态方法和类,而不是全局数据。 例如,如果您将数据对象移交给静态方法,并且该静态方法不访问任何静态数据,那么您可以放心,给定输入数据,函数的输出将始终相同。 这是Erlang,Lisp,Clojure以及其他所有函数式编程语言所采取的立场。
使用静态方法可以大大简化multithreading编码,因为如果编程正确,一次只有一个线程可以访问给定的数据集。 而这正是它归结为的。 拥有全局数据是不好的,因为它是一个可以由谁知道什么线程,任何时候都可以改变的状态。 然而,静态方法允许非常干净的代码,可以以较小的增量进行测试。
我知道这会引起激烈的争论,因为它面对C#的OOP思维过程,但我发现我使用的静态方法越多,我的代码越干净,越可靠。
这个video比我能更好地解释它,但展示了不可变数据和静态方法如何产生一些极其线程安全的代码。
让我澄清一下全球数据的一些问题。 常量(或只读)全局数据并不像可变(读/写)全局数据那样大。 因此,如果拥有全局数据缓存是有意义的,请使用全局数据! 在某种程度上,使用数据库的每个应用程序都会有这个,因为我们可以说所有SQL数据库都是一个保存数据的大型全局变量。
所以像我上面那样做一个全面的陈述可能有点强。 相反,让我们说拥有全局数据会引入许多问题,而这些问题可以通过使用本地数据来避免。
某些语言(如Erlang)通过将缓存放在一个处理该数据所有请求的单独线程中来解决此问题。 这样您就知道对该数据的所有请求和修改都将是primefaces的,并且全局缓存不会处于某种未知状态。
static
并不一定意味着全球化。 类和成员可以是static private
,因此仅适用于特定的类。 也就是说,拥有太多public static
成员而不是使用适当的方法来传递数据(方法调用,回调等)通常是糟糕的设计。
如果你试图对你的OO开发纯粹主义,那么静力学可能不适合模具。
然而现实世界比理论更混乱,而静力学通常是解决一些发展问题的非常有用的方法。 适当时和适度使用它们。
可变静态变量很糟糕,因为它们只是全局状态。 我所知道的最好的讨论就在这里,标题为“为什么在不必要的时候应该避免全局变量” 。
静态方法有几个缺点,往往使它们不受欢迎 – 最大的缺点是它们不能多态使用。
作为对所说的其他内容的补充, final static
变量就好了; 常数是一件好事。 唯一的例外是当/如果你应该将它们移动到属性文件,更容易更改。
首先,为什么旧的全局变量如此糟糕? 因为它是可以随时随地访问的状态。 难以追踪。
静态方法没有这样的问题。
这留下了静态字段 (变量)。 如果你在一个类中声明了一个公共静态字段,那真的是一个全局变量而且它会很糟糕。
但要使静态字段保密 ,大多数问题都解决了。 或者更好的是,它们仅限于包含类,这使它们可以解决。
public class Foo { private static int counter = 0; public static int getCounterValue() { return counter; } //... public Foo() { //other tasks counter++; } }
在上面的代码中,您可以看到我们计算了创建了多少个Foo对象。 这在许多情况下都很有用。
static关键字不是全局的,它告诉你它是在类级别,这在各种情况下都非常有用。 因此,总之,类级别的东西是静态的,对象级别的东西不是静态的。
静态方法用于在Scala中实现特征 。 在C#中,扩展方法(静态) 部分地履行了该角色。 正如DCI的支持者所说,可以看出,这是一种“更高阶的多态性forms” 。
此外,静态方法可用于实现function。 这是F#用于实现模块的内容 。 (还有VB.NET 。)函数对于(不出所料)函数式编程很有用。 有时候它们只是建模的方式(比如Math
类中的“函数”)。 再一次,C# 就在这里。
我认为全局变量的坏处是拥有全局状态的想法 – 可以在任何地方操纵变量,并且往往会在程序的偏远区域引起意外的副作用。
静态数据类似于全局变量,因为它们引入了一种全局状态。 假设它们是无状态的,静态方法虽然不是那么糟糕。
不是完全。 静态实际上确定实例化事物的时间,地点和频率,而不是谁有权访问它。