全局静态类和方法都不好吗?

时间:2010-06-30 17:26:15

标签: c# .net language-agnostic oop

人们普遍认为,应该避免严重依赖全球性的东西。不会使用静态类和方法是一回事吗?

10 个答案:

答案 0 :(得分:45)

全球数据不好。但是,使用静态方法可以避免许多问题。

我将在这个问题上采取Rich Hickey的立场,并解释如下:

在C#中构建最可靠的系统使用静态方法和类,但不使用全局数据。例如,如果您将数据对象交给静态方法,并且该静态方法不访问任何静态数据,那么您可以放心,给定输入数据,函数的输出将始终相同。这是Erlang,Lisp,Clojure和其他Functional Programming language所采取的立场。

使用静态方法可以大大简化多线程编码,因为如果编程正确,一次只有一个线程可以访问给定的数据集。而这正是它归结为的。拥有全局数据是不好的,因为它是一个可以由谁知道什么线程,任何时候都可以改变的状态。然而,静态方法允许非常干净的代码,可以以较小的增量进行测试。

我知道这会引起激烈的争论,因为它面对C#的OOP思维过程,但我发现我使用的静态方法越多,我的代码越干净,越可靠。

This video比我能更好地解释它,但展示了不可变数据和静态方法如何产生一些极其线程安全的代码。


让我澄清一下全球数据的一些问题。常量(或只读)全局数据并不像可变(读/写)全局数据那样大。因此,如果拥有全局数据缓存是有意义的,请使用全局数据!在某种程度上,使用数据库的每个应用程序都会有这个,因为我们可以说所有SQL数据库都是一个保存数据的大型全局变量。

所以像我上面那样做一个全面的陈述可能有点强。相反,让我们说拥有全局数据会引入许多问题,而这些问题可以通过使用本地数据来避免。

某些语言(如Erlang)通过将缓存放在一个处理该数据所有请求的单独线程中来解决此问题。这样您就知道对该数据的所有请求和修改都将是原子的,并且全局缓存不会处于某种未知状态。

答案 1 :(得分:10)

static并不一定意味着全球化。类和成员可以是static private,因此仅适用于特定类。也就是说,拥有太多public static成员而不是使用适当的方式来传递数据(方法调用,回调等)通常是糟糕的设计。

答案 2 :(得分:6)

如果你试图对你的OO开发做一些纯粹主义,那么静力学可能不符合模具。

然而,现实世界比理论更混乱,而静力学通常是解决某些发展问题的非常有用的方法。在适当的时候使用它们,并适度使用。

答案 3 :(得分:3)

可变静态变量很糟糕,因为它们只是全局状态。关于这个is here, under the heading "Why Global Variables Should Be Avoided When Unnecessary"的最佳讨论。

静态方法有几个缺点,往往使它们不受欢迎 - 最大的缺点是它们不能以多态方式使用。

答案 4 :(得分:2)

作为对其他任何内容的补充,final static变量就好了;常数是一件好事。唯一的例外是当/如果你只是将它们移动到属性文件,更容易改变。

答案 5 :(得分:2)

首先,为什么旧​​的全局变量如此糟糕?因为它是可以随时随地访问的状态。难以追踪。

静态方法没有这样的问题。

留下静态字段(变量)。如果你在一个类中声明了一个 public 静态字段,那真的是一个全局变量而且它会很糟糕。

但要使静态字段私有,大​​多数问题都解决了。或者更好的是,它们仅限于包含类,这使它们可以解决。

答案 6 :(得分:2)

静态方法用于在Scala中实现traits。在C#中,扩展方法(它们是静态的)在part中履行该角色。正如DCI的支持者所说,可以看出这是"higher order form of polymorphism"

此外,静态方法可用于实现功能。这是F#用于实现modules的内容。 (还有VB.NET。)函数对于(不出所料)函数式编程很有用。有时它们只是应该建模的方式(如Math类中的“函数”)。再次,C#comes close在这里。

答案 7 :(得分:2)

public class Foo
{
    private static int counter = 0;

    public static int getCounterValue()
    {
         return counter;
    }
    //...
    public Foo()
    {
        //other tasks
        counter++;
    }
}

在上面的代码中,您可以看到我们计算了创建了多少个Foo对象。这在许多情况下都很有用。

static关键字不是全局的,它告诉你它是在类级别,这在各种情况下都非常有用。因此,总之,类级别的东西是静态的,对象级别的东西不是静态的。

答案 8 :(得分:1)

我认为关于全局变量的坏处是拥有全局状态的想法 - 可以在任何地方操纵变量,并且往往会在程序的偏远区域引起意外的副作用。

静态数据与全局变量类似,因为它们引入了一种全局状态。静态方法虽然没有无状态,但并不是那么糟糕。

答案 9 :(得分:0)

不完全。静态实际上确定实例化事物的时间,地点和频率,而不是谁有权访问它。