通过静态方法访问单例的字段

5

我有一个单例类。

当访问该类的方法时,我有两种选择。

  1. 将这些方法创建为实例特定的,然后获取该实例并调用它们
  2. 将这些方法创建为静态方法并调用它们,它们将获取该实例

例如:

Class Test{

 private int field1;

 Test instance;

 private Test(){};

 private Test getInstance(){
    if (instance == null)
       instance = new Test();
    return instance;
 }

 public int method1() { return field1;}
 public static int method2() {return getInstance().field1;}
}

现在,我可以在其他地方写入。
 int x = Test.getInstance().method1();
 int y = Test.method2();

哪个更好? 我可以想到第三种选择,直接在静态方法中使用“instance”,然后捕获异常(如果为null)并实例化它,然后重新调用自身。
理论上,我可以将整个程序都设置为静态。但是,当活动关闭时,序列化不会保存静态内容,这会给我带来问题。

我会选择Test.method2();,因为它表明method2()是一个静态方法。 - TheVillageIdiot
4个回答

2

你应该避免将所有东西都设为静态的。有些人甚至会说单例模式已经过时了。


必须是单例模式,因为我需要在许多地方使用它,并且必须是同一个。 - theblitz
那么你应该选择“int x = Test.getInstance().method1();”的解决方案,因为field1根本不是静态的。 - ChristopherS

2

我认为第一个更加简洁。

但是需要注意,在某些特殊情况下,Android可能会销毁您的静态实例。例如,请参考:http://code.google.com/p/acra/

我在某个地方找到了一个解决方法,即在应用程序类中也保留对单例的引用。但我不知道这是否完全可靠。


当你说“kill”时,我认为你是在谈论关闭活动。 - theblitz
1
不,我说的是静态实例被销毁。当活动结束时,你不应该感到惊讶,但当静态实例消失时,你应该感到非常惊讶 - 在Java中不会发生这种情况。 - zmbq

2
单例模式的整个意义在于您可以更改实现。在大多数情况下,您使用它来保持将来“挂钩”此功能的其他实现的可能性。

阅读:当决定支持单例时,也要为setInstance方法做出决策,而不仅仅是getInstance。-如果这没有意义,只需使用普通的静态类。

另一方面,如果您想时髦并且与众不同,则单例已经过时了。搜索“消除全局状态”。还有一些由Google赞助的讲座。简而言之:您的代码将更易于测试,并帮助您避免某些依赖关系混乱。(除了时尚和所有这些之外,这绝对是朝着正确方向迈出的一步)。


0

在我个人看来,拥有静态方法本身就是不好的设计。当然,这取决于程序本身,但允许一个类拥有静态方法将对整个设计产生影响。以下是我陈述的一些理由:

  1. 如果静态方法可以轻松更改某个对象的状态,迟早会出现错误
  2. 如果您发布了带有静态方法的程序,则使用它的每个客户端都将对您的代码具有非常强的依赖性。如果您决定在某一天删除或更改此方法-您将破坏使用您的类的每个单个客户端。

所以,如果可以-请避免使用静态方法

如果出于任何原因,您坚持要使用静态方法,我想第一种解决方案更好。这就是单例应该工作的方式。您应该通过静态方法获得对单例对象的引用,但是应根据面向对象编程的所有原则使用此对象。


(1) 当然,静态方法只应用于不改变对象状态的操作,但这并不是禁止使用静态方法的理由。 (2) 这是对所有公共方法的批评,而不仅仅是静态方法。两个类之间解耦的程度有限,否则将完全失去交互! - Tommy Herbert

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