Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我怎样才能改善这个单身汉?_Java_Oop_Design Patterns_Singleton - Fatal编程技术网

Java 我怎样才能改善这个单身汉?

Java 我怎样才能改善这个单身汉?,java,oop,design-patterns,singleton,Java,Oop,Design Patterns,Singleton,我有一个类将充当singleton。 此类将获得一个作为构造函数一部分的文件。之后,课程就可以开始了。 因此,目前我使用双重检查锁定习惯用法,并通过一个静态getInstance()即经典方式获取singleton的实例。 我的问题是,目前我经常: MySingleton.getInstance(文件) 只有在第一次构造singleton时才需要文件。在此之后,即,一旦构造了单例,我就不需要传入文件 我该怎么做? 我想创建一个MySingleton.getInstance()但这仍然不起作用,因

我有一个类将充当singleton。
此类将获得一个作为构造函数一部分的文件。之后,课程就可以开始了。
因此,目前我使用双重检查锁定习惯用法,并通过一个
静态getInstance()
即经典方式获取singleton的实例。
我的问题是,目前我经常:

MySingleton.getInstance(文件)

只有在第一次构造singleton时才需要文件
。在此之后,即,一旦构造了单例,我就不需要传入
文件

我该怎么做?
我想创建一个
MySingleton.getInstance()
但这仍然不起作用,因为调用方必须调用
MySingleton.getInstance(theFile)第一次构造有效类。

如何更好地设计它?

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

您只需使用一个没有文件参数的getInstance()方法即可


如果在另一个之前调用它,它将抛出一个异常,但这是可以的,因为在任何情况下,如果您已经确定singleton是在之前创建的,则只能避免传递该文件。

在典型的依赖项注入环境中,您的文件名将是对应于该singleton类的singleton bean的属性,范围为singleton。然后将这个bean注入任何需要它的类中

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

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

简化
getInstance()
以返回实例,但如果尚未调用
init()
则抛出
IllegalStateException

例如:

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()
,竞争条件(如果有的话)就会非常少

Singleton::getInstance().load(myFile)


只要确保这是在启动时完成的。

首先是一种替代方法

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

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

这种机制的可能实施:

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); //

 }

}

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

真的。你在开枪打自己的脚

无论何时开始将未使用的值传递给方法,都应该发出真正的响亮的警钟,提醒您在丹麦的体系结构上有问题。显然,您可以选择忽略这些警钟(很可能也是这个答案),但这并不会让您的代码更糟糕。我知道,我是个卑鄙小人。 但事实很简单,使用单例将使您的程序变成一大堆热气腾腾的意大利面

| | | | | | |

因为我不知道你想要通过这个课程实现什么,很遗憾我不能提供一个解决方案

除此之外:不要使用单例

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

你在开玩笑吧。。你在iphone上输入了全部代码!!感谢你对贡献的热情。。