【问题标题】:Singleton or static class?单例还是静态类?
【发布时间】:2012-09-19 15:01:03
【问题描述】:

我有以下课程:

public class EnteredValues {

private HashMap<String, String> mEnteredValues;

public boolean change = false;
public boolean submit = false;
private static final EnteredValues instance = new EnteredValues();

// Singleton
private EnteredValues() {
    mEnteredValues = new HashMap<String, String>();
}

public static EnteredValues getInstance() {
    return instance;
}

public void addValue(String id, String value) {

    if (mEnteredValues.put(id, value) != null) {
        // A change has happened
        change = true;
    }
}

public String getValueForIdentifier(String identifier) {
    return mEnteredValues.get(identifier);
}

public HashMap<String, String> getEnteredValues() {
    return mEnteredValues;
}

public void clean() {
    mEnteredValues.clear();
    change = false;
    submit = false;
}
}

该类用于管理用户已经输入的值,并且该类应该可供整个应用程序中的所有类访问。
当活动发生变化时,我通过调用 clear 方法“重置”单例。

我选择了单例模式,并没有真正考虑静态类的选项。
但现在我想知道我是否不应该只使用静态类..

处理只管理值的类的常用方法是什么? 静态类比单例更快吗?

谢谢

【问题讨论】:

  • “当活动改变时,我通过调用 clear 方法‘重置’单例。”那你为什么需要一个单例/静态类呢?
  • 好点,实际上只是为了方便访问。
  • 不要在这里堆砌和挑选你的设计,但你所说的“管理用户已经输入的值”到底是什么意思?似乎您只是为了避免使用 Android 的 Bundle 类以及 Activity.onSaveInstanceStateonRestoreInstanceState 来实现这一点。为什么你不能使用它?
  • 每个用户会话都需要一个数据缓存。如果系统是单用户的,一个公共的静态变量就绰绰有余了。在多用户系统中,每个线程必须有自己的引用。
  • @spacemanaki 不是在activity之间传递数据。

标签: java android singleton


【解决方案1】:

您提供了一种清晰的方法来重置 Singleton 的状态,这一事实表明您不应该使用 Singleton。这是一种危险的行为,因为国家是全球性的。这也意味着单元测试将是一个很大的痛苦。

还有一件事。永远不要将实例变量声明为公共的。将它们声明为私有或受保护并提供 getter 和 setter。此外,无需使用默认值初始化实例变量。

【讨论】:

  • “永远不要将实例变量声明为公共” - 我会将其改写为“永远不要将表示内部状态的可变实例变量声明为公共”(在这种情况下仍然如此)。一个无条件的“永远不会”是有争议的(和题外话)
  • 这对我来说绝对是值得深思的:)谢谢。
【解决方案2】:

静态类和单例模式的主要区别在于,如果您需要实现接口等,可以使用单例。对于这种特殊情况,我认为使用静态类可能会更好,因为您没有实现任何接口。如果将您的问题与另一个问题联系起来,我会说差异可以忽略不计,但使用静态类将消除类动态实例化的一小部分开销。

【讨论】:

    【解决方案3】:

    如果您需要这样的设计,使用单例有什么不好的?如果你需要某个对象的一个​​实例来做指定的事情,那么单例肯定不是一个糟糕的选择。

    @见Are Java static calls more or less expensive than non-static calls?

    阅读 http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

    从那里:

    注意:静态嵌套类与其外部类(和其他类)的实例成员交互,就像任何其他顶级类一样。实际上,静态嵌套类在行为上是一个顶级类,为了方便打包,它已经嵌套在另一个顶级类中。

    【讨论】:

      【解决方案4】:

      只为风格

      如果不需要,我宁愿不依赖 Singleton。为什么?更少的凝聚力。如果它是您可以从外部设置的属性,那么您可以使用单元测试来测试您的活动(或其他)。如果你愿意,你可以改变主意使用不同的实例,等等。

      我的谦虚建议是在您的每个活动中都有一个属性(也许您可以定义一个公共基类?),并在活动初始​​化时使用新的实例设置它。

      您的代码对如何获取它一无所知(除了初始化代码,也许您将来可以更改它)。

      但正如我所说...只是口味问题! :)

      【讨论】:

        猜你喜欢
        • 2011-06-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-19
        相关资源
        最近更新 更多