为什么OOP中静态类的最佳实践有所不同?

时间:2014-09-02 06:40:30

标签: java c# oop static

我目前正在阅读有关Java最佳做法的内容,我发现根据this book,我们必须支持静态类而不是非静态。我记得在C#最佳实践中我们必须根据Dennis Doomen的C#3.0,4.0和5.0编码指南来避免这种情况:

  

AV1008 - 避免使用静态类

     

除了扩展方法容器之外,静态类通常会导致代码设计错误。除非你愿意使用一些非常糟糕的工具,否则它们也很难(如果不是不可能的话)进行单独测试。注意如果您确实需要该静态类,请将其标记为静态,以便编译器可以阻止实例成员并实例化您的类。这使您无需创建显式的私有构造函数。

我发现这两个用于C# answerJava answer何时使用和避免静态类,但仅仅是出于好奇 - C#和Java都是OOP语言,为什么它完全不同于那么最佳实践?

更新 我无法从Java书中复制这么多页面,但最重要的是:

  

如果您声明一个不需要访问的成员类   封闭       实例,总是将静态修饰符放在其声明中,使其成为静态       而不是非静态成员类。如果省略此修饰符,则每个实例都将       对其封闭实例有一个无关的引用。存储此参考成本       时间和空间,并且可以导致封闭的实例被保留       否则将有资格进行垃圾收集(第6项)。你应该吗?       需要分配一个没有封闭实例的实例,你将无法做到       所以,因为非静态成员类实例需要有一个封闭的实例。       私有静态成员类的常见用法是表示组件       由封闭类代表的对象。

仅关于绩效吗?

注意这个问题更多是关于静态类和OOP ,而不是Java和C#之间的差异。

2 个答案:

答案 0 :(得分:4)

JoshuaBloch给出的建议也适用于c#,并且给出的c#建议也适用于java(在他们谈论静态类的时候)。

  

为什么要使用静态成员?

  • 他们不需要一个实例来称呼他们
  • 在c#中,他们使用call opcode,它不需要检查null(这是微优化)而不是实例方法(使用callvirt opcode)。我相信java中也会有类似的东西。
  • 如果不使用实例,他们就不会阻止来自GC的内容。
  • 也没有将this引用传递给隐藏的所有方法的开销。

如果您已经习惯了Visual Studio的Resharper生产力工具,它将提供与JoshuaBloch给出的相同的建议,在c#中说 Method can be made static 是合理的在给定的链接中。

  

为什么不使用静态成员?

  • 他们不可测试(轻松)。
  • 他们无法实现接口成员。
  • 不能通过依赖注入注入它们。
  • 他们没有参与多态(在面向对象语言中非常需要)。
  • 在c#中,静态类不能作为参考传递。

因此,如果你了解它们并同时申请这两种语言,这两个建议都是好的。在适当的时候使用它们,并在它们不适合时使用它们。

答案 1 :(得分:3)

  1. 我认为第二个文本片段全部是member classenclosing,这是特定于Java的功能(如何实现)。
  2. 静态类或字段(如在C#中)实际上是糟糕的设计实践 - 看看OOP和SOLID。此外,它可能导致CLR级别的一些性能问题。但私有静态方法没有错。我记得,Resharper建议将私有方法独立于具体实例静态。它增加了可读性并且没有副作用。而且你不需要单元测试私有方法。这也是不好的做法。
  3. 最后,一些作者简要介绍了技术和一些 - 关于设计原则。通常这些观点之间存在矛盾(但描述的两个片段与此无关)。