曾经需要破坏单例实例吗?

时间:2011-03-17 16:47:32

标签: java singleton instance destroy

通过使用单例,只能创建一个实例。我们是否需要销毁该实例?

我有一个单例DBManager,它管理JDBC连接和查询操作。通过调用它的静态newInstance方法,我可以得到它的实例,然后我做一些查询。最后,我想关闭数据库连接,然后调用另一个静态方法关闭JDBC连接。

现在连接已关闭,而DBManager的实例仍处于活动状态但没有用处。我需要通过例如将其分配给null来销毁它吗?否则稍后可能会错误地引用它。

如果我将该实例赋值为null,那么再次调用newInstance方法,我会得到另一个新的不同实例吗?

8 个答案:

答案 0 :(得分:10)

我不会对“单身”的语义感到困惑 - 你的要求是任何时候最多只有DBManager的一个实例存在。一旦该实例变得无用,您可以销毁它以便根据需要创建一个新实例,或者定义您的newInstance方法(我可能建议将其重命名为getInstance)以抛出异常(或许IllegalStateException)如果在单身人士被渲染为无用之后被调用。

如果要在渲染无用时将其销毁,我建议这可以在单例类中自动完成,没有外界帮助。您还应该考虑完全隐藏单例DBManager并实现委派模式。这将避免客户端保持对陈旧DBManager实例的引用的问题。然后,您可以使委托对象成为常规单例。

答案 1 :(得分:5)

我认为没有,你不能销毁单身,因为它需要一直有一个实例可用。并且可以说它需要是相同的实例,因为否则它不是真正的单例(例如,两个不同的类可以保存对类的不同实例的引用)。

但顺便提一下,这是我认为单例模式在真实软件中几乎没有用的众多原因之一。在任何情况下,你想要完全一件事的可能性,通过阻止人们调用构造函数来强制实施这一点 - 太过僵化了。这听起来像是一种情况,在某种程度上,拥有一个单身似乎是合理的,但现在很明显,多个实例是有道理的。

那么想想这个是否必须是一个单身人士 - 你能不能简单地把它作为适当连接的连接的包装器?

答案 2 :(得分:2)

我认为更符合Singleton模式,使DBManager能够打开和关闭连接而不会实际破坏DBManager本身。然后,您将保留它,直到下次需要数据库连接时,并请求相同的DBManager对象创建新连接。毕竟,如果它是DBManager,它管理连接;它不代表任何个人联系。

答案 3 :(得分:2)

在这种情况下,我们使用连接池机制。查询数据库的每个操作都必须打开和关闭连接。但是,因为我们正在使用连接池,所以连接将返回到池而不是实际关闭。

池中将有一个名为IDLE_CONNECTION_TIMEOUT或类似的设置,如果在配置的时间段内未使用它们,它们将自动过期并关闭连接。因此,在这种情况下,开发人员很少担心。

答案 4 :(得分:0)

简短回答:不。

更长的答案:除了使用特殊的类加载器之外,你无法销毁单例。如果你需要销毁它,你根本不应该使用单身。也许你可以用重新打开它的方式重写它 - 更好:避免单例模式。

搜索反模式或代码气味。

答案 5 :(得分:0)

如果数据库连接已关闭,您的DBManager类应该处理清理。即如果DBManager引用了Connection类,那么您可以在newInstance()方法中编写代码来检查连接是否处于活动状态,然后返回静态引用。像这样的东西:

static DBManager manager;
static DBManager newInstance(){
if (manager == null) manager =new DBManager();
else if ( manager !=null && connection ==null) //if connection is closed 
manager =new DBManager();

return manager;
}

答案 6 :(得分:0)

答案应该是 no 你不能销毁单身,因为应该只有一个和一个。至于你的问题,你有一个DBManager类,这个HASA连接已关闭并变得无用。

我猜你的目标应该是在任何时候打开一个数据库连接,所以我会在这里查看你的代码,你是否打破了单一责任主体并确保你将连接责任分成了一个单独的类,允许你的单一权限管理它的连接 - 即关闭并在必要时重新打开它。

答案 7 :(得分:-1)

为类Variable创建一个getter / setter并将其设置为null以重新实例化一个对象 例如:

//Singleton support ...
private static A singleton = null;
    public static A get() {
        if (singleton == null){
        singleton = new A();
    }
        return singleton;
}
public static A getSingleton() {
    return singleton;
}
public static void setSingleton(A singleton) {
    A.singleton = singleton;
}

//Re instantiate 
public class Test(){
....
....
    A.setSingleton(null);

}