在Java中再次使用带有参数的单例

时间:2012-02-02 07:10:35

标签: java android oop design-patterns singleton

首先,我必须承认我的问题类似于Singleton with Arguments in Java

我读了它,但解决方案对我不起作用。我知道工厂模式是解决这个问题的最佳方案。

这是我的问题。 我创建了一个“单例”类来提供一些常用功能,例如获取全局配置参数。此类需要一个处理程序来访问系统资源,例如读取配置文件。因为这个类只是作为一个lib,处理程序必须从外部传入,而Handler是一个系统类。

所以,我以这种方式编写代码:

public class SingletonGlobalParameters {
    private static final SingletonGlobalParameters instance = new SingletonGlobalParameters ();

    private boolean initial = false;

    private String aParameter = null;

    private SingletonGlobalParameters () { }

    public static SingletonGlobalParameters getInstance() {
            if (initial == false) {
                throw exception...
            }
            return instance;
    }

    public void init(Handler h) {
        if (initial == false) {
            Handler fileHandler = h;
            aParameter = fileHandler.read(); // something like this
            initial = true;
        }
    }

    public int getParameter() {
        return aParameter;
    }
}

我删除同步内容以明确问题。 这个工具看起来很难看,对吧?该类必须保证在使用前初始化。

有什么好主意吗?非常感谢,这个问题困扰了我一段时间。


OK!我给出了现实世界的问题。这是一个Android问题。

public class Configuration {
    private static final Configuration instance = new Configuration ();

    private boolean initial = false;

    private long timeStamp = -1;

    private Configuration () { }

    public static Configuration getInstance() {
            if (initial == false) {
                throw exception...
            }
            return instance;
    }

    public void load(Context context) {
        if (initial == false) {
            SharedPreferences loader = context.getSharedPreferences("Conf", Context.MODE_PRIVATE);
            timeStamp = loader.getInt("TimeStamp", 0);              
            initial = true;
        }
    }

    public int getTimeStamp() {
        return timeStamp;
    }
}

这会让问题更清楚吗?

2 个答案:

答案 0 :(得分:2)

正确的模式是允许您做所需事情的模式。不要那么教条。带有参数的Singleton被广泛使用并在android环境中被接受(参数通常是上下文)。但是在普通的java环境中,依赖注入会更好 使用你单身的代码来解耦代码,因为它是单例,以及它的创建方式。有很多DI框架,比如picocontainer,spring,google guice - 只需选择你喜欢的

答案 1 :(得分:1)

编辑:当我写这个答案时,问题没有上下文 - 我们不知道它是一个Android应用程序。 可能在这种情况下它不是一个糟糕的解决方案;但我至少会认为关于其他方法。我将在下面留下我的答案,用于更一般的案例。

我会尝试从单身模式转移到开始。

为什么许多地方都需要每个配置参数?你可以封装配置的每个方面(在某些情况下可能在单个方面有多个参数)然后使用依赖注入(例如使用Guice)来使那些封装版本可用于需要它们的组件吗?

当我们真的不知道你正在写什么类型的应用程序时,很难给出具体的建议,但一般来说最好远离全局状态和依赖注入< em>经常提供了一种干净的方式来做到这一点。它不是灵丹妙药,可能在某些情况下你可以用不同的方式重新设计,但这是我的第一个想法。