使用静态方法和变量 – 好与坏

我正在开发C#和asp.net Web应用程序。

我有一个名为utilities的通用类,我在这个公共实用程序类中有很多公共和静态变量。

由于这个数字逐渐增加,我想知道将实用程序方法和变量存储为公共静态是一种好的做法。

我的代码示例

public class utilities { public static string utilVariable1 = "Myvalue"; public static string utilVariable2 = "Myvalue"; public static string utilVariable3 = "Myvalue"; : public static string utilVariableN = "Myvalue"; public static string UtilMethod1() { //do something } public static string UtilMethod2() { //do something } public static string UtilMethodN() { //do something } } 

static类没有任何固有的错误,尽管它们通常不应该具有状态(字段)。 您对public static字段的使用表明情况并非如此,因此您似乎正在使用稍微滥用static关键字。 如果你的类需要有状态,那么它应该是一个普通的非静态类,你应该创建它的实例。 否则,类上可见的唯一公共字段应该是const (考虑Math类,使用Math.PI等常量 – 很好地使用static方法和字段)。

另一个考虑因素是凝聚力 。 方法通常存在于一个类中,因为它们以某种方式密切相关。 同样, Math类就是一个很好的例子; 那里的一切都与数学有关。 在某些时候,您可能希望将全局实用程序类拆分为多个更小,更集中的实用程序类。 有关凝聚力的一些例子,请参阅维基百科 ,听起来你的用法属于“巧合的凝聚力(最差)”。

这种方法对于方法没有任何问题,但如果变量是静态的和公共的,变量应该是常量。 如果它们可能会发生变化,那么您应该查看由多个组件操纵的变量的不同结构。

就个人而言,我是Singleton模式的粉丝。

static本身并不是一件坏事。 不需要访问任何成员变量或方法的方法应始终声明为static。 这样,代码的读者立即看到方法不会更改成员变量或方法。

对于变量情况不同,除非将它们const否则应避免使用static变量。 Public static变量是全局可访问的,如果多个线程在没有正确同步的情况下访问同一个变量,则很容易引

很难说你的情况是否使用静态是好的或坏的想法,因为你没有提供任何上下文信息。

创建一个类来完成所有操作并不是一个好习惯,建议构建项目,并将属于彼此的东西与随机性分开。

一个很好的例子就是我从同事手中接过的一个项目。 有一个类叫做Methods。 它包含超过10K行的方法。
然后我将它们分类为约。 20个文件,并恢复了结构。

该项目的大多数方法都是validation用户输入,可以很容易地将其移动到static class Validation

我注意到的一件可怕的事情是可变的公共变量和静态变量。 这有几个原因:

  1. 行为不正确,因为如果某些方法改变了这一点,虽然它不应该这样做,但它会导致其他方法行为不正确,而且很难追踪/调试。
  2. 并发,我们如何确保线程安全? 我们是否让它适用于所有与之相关的方法? 如果它是一个值类型,我们会让它们锁定什么? 如果某种方法忘记使其线程安全怎么办?
  3. 扩展能力(我希望你明白我的意思),如果你有一个静态类数据存储所有这些公共静态变量,你不应该。 它可以存储一次,例如,如果你可能稍微改变你的应用程序结构,并说想要在同一个屏幕上加载两个项目,那么很难做到这一点,因为你不能创建两个静态类的实例。 只有一个class级,它将保持这样。

对于数字3,更清洁的解决方案是存储数据类的实例列表,或存储对默认和/或活动数据类的引用。

静态成员和私有静态成员(或受保护的)是一个很好的做法,只要你不创建庞大的类,并且方法是相关的。

如果它们不是真正可变的,那么公共变量和静态变量都可以。
这样做的两种方法是将它们标记为常量( const修饰符)或readonly( readonly修饰符)。

例:

 public class UtilitiesClass { internal UtilitiesClass() { } public void UtilityMethod1() { // Do something } } // Method 1 (readonly): public static readonly UtilitiesClass Utilities = new UtilitiesClass(); // Method 2 (property): private static UtilitiesClass _utilities = new UtilitiesClass(); public static UtilitiesClass Utilities { get { return _utilities; } private set { _utilities = value; } } 

方法1的优点是您根本不必担心线程安全,价值无法改变。
方法2不是线程安全的(虽然它并不困难),但它的优点是允许静态类本身更改对实用程序类的引用。

不,对于大型应用程序来说,这不是一个好的做法,特别是如果你的静态变量是可变的,因为它们实际上是有效的全局变量,这是面向对象编程应该“解决”的代码味道。

至少首先将您的方法分组为具有相关function的较小类 – Util名称不表示您的方法的目的和本身不连贯类的气味。

其次,您应该始终考虑一个方法是否更好地实现为同一对象上的(非静态)方法,其中作为参数传递给该方法的数据存在。

最后,如果您的应用程序非常庞大和/或复杂,您可以考虑诸如Inversion of Control容器之类的解决方案,这可以减少对全局状态的依赖。 然而,ASP.Net webforms非常难以集成到这样的环境中,因为框架本身非常紧密地耦合。