3

我有一个类将充当单身人士。
此类将获得一个文件作为构造函数的一部分。之后就可以上课了。所以目前我使用双重检查锁定习语并通过即经典方式
获取单例的实例。 我的问题是,目前我经常这样做: static getInstance()

MySingleton.getInstance(theFile);

并且theFile仅在第一次构造单例时才需要。之后,即一旦构建了单例,我就不需要传入theFile.
我该怎么做?
我想创建一个MySingleton.getInstance(); ,但这仍然行不通,因为调用者必须MySingleton.getInstance(theFile); 第一次调用来构造一个有效的类。
我怎样才能更好地设计这个?

4

7 回答 7

9

声明一个init()使用文件处理初始化的方法。

简化getInstance()以返回实例,但抛出一个尚未调用的IllegalStateExceptionif 。init()

例如:

public class MySingleton {

    private MySingleton INSTANCE;

    // private constructor is best practice for a singleton 
    private MySingleton(File theFile) {
        // initialize class using "theFile"
    }

    public static void init(File theFile) {
        // if init previously called, throw IllegalStateException
        if (INSTANCE != null)
            throw new IllegalStateException();
        // initialize singleton 
        INSTANCE = new MySingleton(theFile);
    }

    public static MySingleton getInstance() {
        // if init hasn't been called yet, throw IllegalStateException
        if (INSTANCE == null)
            throw new IllegalStateException();
        return INSTANCE;
    }

    // rest of class
}

请注意,尽管这不是线程安全的,但只要init()在服务器启动过程中尽早调用,竞争条件确实很少(如果有的话)。

于 2013-04-02T06:50:23.153 回答
3

在典型的依赖注入环境中,您的文件名将是与此单例类对应的单例 bean 的属性,范围为单例。然后,您只需将该 bean 注入任何需要它的类中。

如果您的程序没有 DI 容器,则此文件名应该是作为 JVM 参数/通过某些属性文件获得的应用程序级别属性,或者最坏的情况是该单例类中的常量。客户不应该担心这个单例类使用的文件。

于 2013-04-02T06:49:33.823 回答
1

也许您可以提供一种方法来初始化单例。您可以定义一个名为 initialize() 的静态方法,该方法接收文件并创建一个单例对象 - 在应用程序启动时或在适当的位置。之后,您可以使用 getInstance()。

于 2013-04-02T06:48:36.023 回答
0

您可以简单地拥有一个没有文件参数的 getInstance() 方法。

如果在另一个之前调用它,它将引发异常,但这没关系,因为在任何情况下,如果您已经确定之前创建了单例,您只能避免传递文件。

于 2013-04-02T06:48:41.267 回答
0

init()方法+异常的替代方案,

Singleton::getInstance().load(myFile)

只要确保这是在启动时完成的/无论如何。

于 2013-04-02T06:52:28.927 回答
0

首先,带有参数的单音的另一种方法不是单音

要解决这个问题,你有两个选择,第一个是上面链接中描述的第二个是从内部获取资源。

该文件通常与路径相关联,您可以从应用程序启动期间传递/设置的属性存储类型访问该路径。

这种机制的可能实现:

public enum MySingleton {
 INSTANCE;

 private final File theFiel;

 private MySingleton() {
   this.theFile = initialize(MySystemProperties.getValue(MySystemProperties.MY_SINGLETONE_PATH);

 }

 private File initialize(String path) { 
    reutrn new File(path); //

 }

}
于 2013-04-02T12:03:37.540 回答
0

优化它的唯一方法是根本不使用单例模式。

严重地。你在开枪打自己的脚。

每当您开始将未使用的值传递给方法时,都应该响起非常响亮的警钟,提醒您丹麦州的某些东西在架构上已经腐烂了。显然,您可以选择忽略那些警钟(很可能也是这个答案),但这不会让您的代码变得更少。我知道,我在这里是个吝啬鬼。但事实很简单,使用单例会将你的程序变成一大堆热气腾腾的意大利面条。

| 巨额| 帖子| 为什么| 单身狗很烂| 更多的屁股| 比一个| 水蛭_ 一头驴

由于我不知道您到底想通过该课程实现什么,因此很遗憾我无法提供解决方案。

除了这个:不要使用单例。

以后你会感谢我的。它看起来很难,需要大量的阅读和实验,但正确的编码会让你感觉好多了。并且会让你成为一个更好的程序员。

于 2013-04-02T14:27:09.443 回答