【问题标题】:java singleton pattern, should all variables be class variables?java单例模式,所有变量都应该是类变量吗?
【发布时间】:2010-12-18 13:32:53
【问题描述】:

如果一个类实现了单例模式,所有变量都应该声明为静态吗?

有什么理由不应该将它们声明为静态的吗?有区别吗?

【问题讨论】:

  • 首先,您是否考虑过完全不使用单例模式?它在面向对象编程中被称为反模式。
  • 我从不同意单例模式是一个糟糕的模式。将其用作“神”对象不是一个好主意,但它有它的位置。
  • 很少有地方可以使用单例 - 字符串外部化是我看到的唯一一个有规律的地方,即便如此,当今大多数流行的平台都提供了更好地封装的库或语言功能那个用例。
  • 在许多 SOA 应用程序中,单例非常普遍——尽管它们可能在“幕后”。
  • 好吧,您可能会在此处 (code.google.com/p/google-singleton-detector/wiki/…) 和此处 (stackoverflow.com/questions/137975/…) 找到有关单例的错误参考。

标签: java design-patterns static singleton class-variables


【解决方案1】:

没有。单例模式只是意味着单个实例是唯一的实例——它并不意味着“让所有东西都可以静态访问”。

单例模式为您提供“单一实例”的所有好处,而不会牺牲测试和重构代码的能力。

编辑:

我要说明的一点是,功能的使用方式(取决于上下文)与功能的初始化方式之间存在差异。

在大多数情况下,您的对象可能只有一个实例(例如,在您的最终生产系统中)。但是如果你强迫它成为唯一的选择,还有其他的环境(比如测试)会变得更加困难。

此外,将某些东西设为静态具有更重要的含义,而不仅仅是“我的类的一个实例应该可以访问”——这通常是我们的意图。

此外,在我从事过的软件中,对象的初始化和生命周期通常由其他人控制(我在这里谈论的是 DI)——在这里将某些东西设为静态实际上并没有帮助。

【讨论】:

  • 严格来说,单例模式允许您限制实例的数量,因此它可以为零或更多(如果它被延迟初始化,则为零)。它是一个很常见。如果您希望它是 2 个或更多,则使事情变得静态会变得更加困难。
  • @TofuBeer,如果允许你有两个,那肯定不会是单身。那不是双标吗? :-)
【解决方案2】:

在一种常见的单例模式中,您确实使用静态。您将类编码为使用普通字段,在构造函数中进行初始化,然后安排执行一次 new MyClass(),将结果存储在某个静态位置。

【讨论】:

    【解决方案3】:

    不,唯一通常是静态的就是对单例本身的引用(还有其他方法来存储该引用,例如 JNDI 或依赖注入容器)。

    不将字段声明为静态(即使在单例模式中您只需要它们的一个实例)的原因是,这使您可以灵活地创建通常单例类的另一个稍微不同的实例。您可能希望在特殊情况下执行此操作,例如测试。

    即使您不(认为自己)需要这种灵活性,也没有理由放弃它。将字段声明为静态不会失去任何好处。

    【讨论】:

    • +1 用于在适当的情况下提供单实例访问,而不会放弃“多实例”的好处,当您将所有内容设为静态时会发生这种情况。
    【解决方案4】:

    可以这样做(不一定应该)。但是,即使对于单例,我也倾向于将所有变量设为对象级别而不是类级别,因为:

    • 我可能在某些时候认为单例对于该类来说是个坏主意,并且拥有类级变量会使重构更加困难。
    • 对于对象级变量,它们仅在您实例化单例时才存在。在班级级别,他们总是在那里。

    底线:我从来没有想过将它们作为对象级别的缺点,所以我就是这样做的。上述两个类级别的缺点可能微不足道,但它们就在那里。最终可能归结为个人喜好。

    【讨论】:

    • +1。从技术上讲,静态字段并非“始终存在”——它们在加载类时“存在”。
    【解决方案5】:

    您可以在此处阅读如何(一种可能的方式)在 Java 中创建单例:

    Wikibooks Design Patterns: Java Singleton

    基本上,您不需要(也不应该)仅仅因为您打算将某些东西用作单例,就将类中的所有东西都设为静态。有几个原因

    • 查看 paxdiablo 和 Thilo 的答案
    • 另外不要忘记将其全部设为静态并不会使其成为单例,您还需要删除每个构造函数(并将默认构造函数设为私有)

    【讨论】:

    • 我不知道是否有必要将所有构造函数设为私有。您可以使用单例模式,而无需强制该类永远不能有其他用途。此外,公开可见的构造函数与 DI 等配合得很好。
    猜你喜欢
    • 2011-10-15
    • 1970-01-01
    • 2010-10-14
    • 2011-11-16
    • 1970-01-01
    • 2012-07-17
    • 1970-01-01
    • 1970-01-01
    • 2017-11-27
    相关资源
    最近更新 更多