单例模式 vs 静态变量

3

我需要在我的应用程序中使用一个全局计数器,每次请求时都会增加计数。我打算将此计数器放在一个单独的类中,类似于以下内容:

public class Counter{  
  private static int count = 0;  
  public synchronized static update()
  {
    count += 1;
  }  

  public synchronized static int getCount()
  {
    return count;
  }  
}

应用程序的整个生命周期中只存在一个计数器。既然只有一个,将其设置为单例模式是否有任何好处?创建单个实例而不是具有静态变量的类是否更有意义?这样做会有什么好处呢?


类似于:https://dev59.com/b2035IYBdhLWcg3wK8wm - Sanjay T. Sharma
在您上面发布的代码中,将update()getCount()设置为静态的更有意义。而且由于计数是静态变量,因此不需要使用this.count - kdabir
4个回答

6
我会将其设为静态(字段和方法)或非静态。您似乎有一个混合的组合,这很容易让人感到困惑。
在这种情况下,我会使用一个 AtomicInteger
public enum Counter {
    public static final AtomicInteger COUNTER = new AtomicInteger();
}

以便您可以做

import static Counter.COUNTER;

int num = COUNTER.incrementAndGet();

2

我认为没有必要把它做成单例或静态的。在逻辑上合适的位置(比如请求生成类的实例变量)实例化一个新的Counter并从那里使用它。这样,如果需要,Counter类仍然可以在其他地方重复使用,并且您不必担心其他人会获取和更新您的计数器...


2
如果您可以按要求创建计数器,我会使用AtomicInteger。 - Peter Lawrey
我不是Java专家,但看了这个类之后,我认为这是正确的选择。没有必要编写已经存在并经过测试的代码! - Kendrick

1

当类具有状态(即具有字段)时,使用单例更为常见。当类是无状态的时,它是一个实用类,通常其方法是静态的。


1

没有看到这是一个被标记为Java而不是C++的问题;

无论如何,除非有人想要删除它,否则我将在此处保留它。

静态类成员的问题在于它们与类紧密耦合,而不是与类实例紧密耦合。换句话说,静态变量只有一个内存分配,将共享在该类(类对象)的所有实例之间。

在上面的代码中,在getCount()方法中,你会

return this.count;

请记住,静态成员没有这个指针,这意味着当从类外部访问时,它们应该使用classname::static_member进行访问,并且仅在定义类方法时使用变量名,就像你上面做的那样。 因此,你的代码应该看起来类似于:

return count;

如果你希望对于创建的任何类对象数量,仅有一个类成员的副本,则最好使用静态方法和静态方法只能操作静态成员。

如果你不喜欢静态方法和静态成员,单例模式也不是一个坏的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接