开发者

Ever need to destroy a singleton instance?

By using a singleton, only one instance of it can be created. Do we ever need to destroy that instance?

I have a singleton DBManager, which manages a JDBC connection and query operations. By calling its static newInstance method, I can get the instance of it, then I do some queries. Finally, I want to close the Database connection, and I call another static method close to close the JDBC connection.

Now the connection has been closed, while the instance of DBManager is still alive but not useful. Do I need to destroy it by for example assigning it to null? Otherwise it may be referenced by mistake later on.

If I assign that instance with null, then call newInstance method again, will I get a开发者_开发问答nother new different instance?


I wouldn't get hung up over the semantics of “singleton”—your requirement is that at most one instance of DBManager exist at any time. Once that instance is rendered useless, you can either destroy it so a fresh instance will be created on demand, or else define your newInstance method (which I might suggest be renamed getInstance) to throw an exception (perhaps IllegalStateException) if it is called after the singleton has been rendered useless.

If you are going to destroy it when rendered useless, I suggest that this be done inside the singleton class automatically, with no outside help. You also should consider completely hiding the singleton DBManager and implementing a delegation pattern instead. This will avoid the problem of a client keeping a reference to the stale DBManager instance. You can then make the delegate object a regular singleton.


I'd argue that no, you can't destroy a singleton because there needs to be exactly one instance of it available at all times. And arguably it needs to be the same instance, because otherwise it's not really a singleton (e.g. two different classes could hold references to distinct instances of the class).

But incidentally, this is one of the many reasons why I believe the singleton pattern has little to no use in real software. The odds of you wanting exactly one thing, ever, in all circumstances, to the point where you enforce this by preventing people from calling constructors - is just too rigid. This sounds like a situation where at one point it seemed reasonable to have a singleton, but it's now become evident that multiple instances makes sense.

So think about whether this must be a singleton - can you simply make it a wrapper around the connection that's wired in as appropriate?


I think it would be more in keeping with the Singleton pattern to make the DBManager capable of opening and closing the connection without actually destroying the DBManager itself. You would then keep it around until the next time you need a database connection, and ask the same DBManager object to create the new connection. After all, if it's a DBManager, it manages connections; it doesn't represent any individual connection.


In such cases, we make use of the Connection Pooling mechanism. Each of your operations which query the database must open and close the connection. However, because we're making use of the Connection Pool, the connection is returned to the pool instead of physically getting closed.

There will be a setting on the pool called IDLE_CONNECTION_TIMEOUT or similar which will automatically expire and close the connections if they're unused for the configured period of time. So, little for the developer to worry about in such cases.


Short answer: No.

Longer answer: You cannot destroy a singleton, except you use a special Classloader. If you need to destroy it, you shouldn't use a singleton at all. Maybe you can rewrite it in a way to reopen it - better: avoid the singleton pattern.

Search for anti pattern, or code smell.


The answer should be no you can't destroy a singleton as there should be one and one only. As to your problem, you have a DBManager class, which HASA connection that's closed and become useless.

I'm guessing your aim should be to have one DB connection open at any one time, so I would look at your code here, are you breaking the single responsibility principal and ensure that you split off the Connection responsibility in to a separate class and allow your single the privilege of managing its connections - i.e. closing and reopen it as necessary.


Your DBManager class should handle the cleanup if the db connection is closed. i.e if DBManager has a referrence to Connection class , then you can write a code in the newInstance() method to check if connection is alive then return static Reference. something like this:

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;
}


Create a getter/setter for the class Variable and set it yo null to re-instantiate an object Ex:

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

}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜