|
Re: Singleton Design
|
Posted: Mar 15, 2003 11:10 AM
|
|
> > I'm working on a project where I just discovered what > is > > really a singleton object, but it is implemented by > making > > all the methods static and having some private static > > data. > > > > Why would someone do it this way instead of the usual > > private constructor, plus getInstance() method? > > Well, I don't see what you'd use getInstance() for. Your > object is initialized when the class is loaded, and then > you can invoke any of the static methods. Having > getInstance() would imply that your object has many > instances. But, in fact, your object has only one > "instance." > I can think of several reasons. One is that your getInstance is in effect a factory method, which could later be changed to return a subclass. Also, by using an object, not a class, you can pass the object to methods, so those methods are more obviously linked to the class via parameters rather than behind the scenes via static method invocations. Once again, in the future you have the option of passing a subclass into those methods. > > > > Another somewhat related question: when you have a > > singleton object, what is a good way of implementing > > close() for it? That is, during the lifetime of the > app, > > it needs to be opened once and closed once, but the > single > > instance will be reused by many objects, so you really > > don't want any of these objects closing it before the > > others are finished with it. It is also not clear who > > will use it first, or last. Should this just be > handled > > with a reference count? > > It sounds like you can design that static object as a > state machine - It would keep track of the application's > state. That includes keeping track of which objects have > used it, and which haven't (assuming you can obtain the > latter information). Every time the state changes, you > could invoke a private (static) method shouldCallClose() > that (a) checks the current state, (b) compares that > current state with the state when close() can be invoked, > and (c) returns whether close() can be called. I wouldn't > call that reference counting, since you may not have > concurrent references to the object, but rather one object > using it after another. > > If you can't know in advance at what state close() can be > invoked, than your only option is to write a finalizer for > your class. That method might or might not be called, > though, when the class gets gc'd. > > In addition, your object may also be concurrent (it sounds > like that), in which case you have to protect access to > the object's state with synchrnonized blocks.
In Java, classes often aren't GC'd until the app exits, and even then they often aren't GC'd. (Knowing Matt's doing C# stuff, this may be a CLR question, not a JVM one.) This is another reason to use a singleton instance rather than a class, though it seems strange to me to "close" a singleton instance, because then it could never be used again until you restart the app (or on the JVM, reload the class into a different namespace).
Anyway, one approach (probably a kind of reference counting) that popped into my head was to have clients "check out" the object when they need to use it, and "check the object back in" when they're done. You could call close anytime you wanted, but it would wait until all objects were checked back in before actually closing the resource. Subsequent calls to checkout after close has been called would throw an exception.
|
|