gpt4 book ai didi

java - 如何实现可配置的单例?

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:43:06 26 4
gpt4 key购买 nike

此问题与Android相关,但也可以在其他情况下提出。我需要创建一个暴露单例的库;或者我想确保只存在我的类的一个实例,并且可以在代码中的任何位置抓取而无需传递引用。

但是那些单例需要一些参数。例如在 Android 中,通常需要一个 Context 对象。我还必须明确一点,因为我提供了一个库,所以我希望用户可以轻松使用并且 我无法控制 Android 中的 Application(这个类可以有时用于管理整个应用程序的对象实例)。

一个已知的解决方案是执行以下操作:

static MySingleton sInstance;
MySingleton.getInstance(Context c) {
if (sInstance == null) {
sInstance = new MySingleton(c.getApplicationContext());
}
return sInstance;
}

但奇怪的是,getInstance 的参数实际上只在第一次创建单例时使用。

我可以给单例提供一个setter,让开发者正确设置需要的参数,但是会出现一些奇怪的情况:

// Good usage
MySingleton.getInstance().setContext(context.getApplicationContext());
MySingleton.getInstance().doSomethingThatRequiresContext(); // OK

// Bad usage
MySingleton.getInstance().doSomethingThatRequiresContext(); // Error!
MySingleton.getInstance().setContext(context.getApplicationContext());

我可以在每个方法开始时检查单例是否正确配置,并在状态不佳时启动一些异常,但 API 使用起来不太简单:

MySingleton.getInstance().setContext(context.getApplicationContext());

try {
MySingleton.getInstance().doSomethingThatRequiresContext();
}
catch(BadSingletonConfiguration e) { }

即使我使用运行时异常,使用起来也是危险的。

除非我善意地要求用户手动创建实例并确保他自己只存在一个实例,否则我看不到好的解决方案。

最佳答案

你可以有一个 createInstance 方法,它接受一个 Context 和一个 getInstance ,如果它们在创建实例之前调用 getInstance ,它将返回 null 或抛出一些有意义的异常。可能会抛出一个 RuntimeException,说明必须先调用 createInstance。

此外,createInstance 如果已经被调用,将只返回已经创建的实例。这是我的想法的代码示例:

public class MySingleton
{
private static MySingleton INSTANCE;
private final Context context;

public static MySingleton createInstance(Context context)
{
if(INSTANCE == null)
{
INSTANCE = new MySingleton(context);
}
return INSTANCE;
}

public static MySingleton getInstance()
{
if(INSTANCE == null)
{
throw new RuntimeException("You must call createInstance first");
}
return INSTANCE;
}

public void doSomethingThatRequiresContext()
{
context.doSomething();
}

private MySingleton(Context context)
{
this.context = context;
}
}

关于java - 如何实现可配置的单例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34642170/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com