The Artima Developer Community
Sponsored Link

Design Forum
Singleton Design

8 replies on 1 page. Most recent reply: Sep 19, 2003 5:39 AM by Vincent O'Sullivan

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 8 replies on 1 page
Matt Gerrans

Posts: 1153
Nickname: matt
Registered: Feb, 2002

Singleton Design Posted: Mar 12, 2003 2:17 PM
Reply to this message Reply
Advertisement
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?

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?


Frank Sommers

Posts: 2642
Nickname: fsommers
Registered: Jan, 2002

Re: Singleton Design Posted: Mar 14, 2003 6:18 PM
Reply to this message Reply
> 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."

>
> 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.

Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: Singleton Design Posted: Mar 15, 2003 11:10 AM
Reply to this message Reply
> > 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.

Frank Sommers

Posts: 2642
Nickname: fsommers
Registered: Jan, 2002

Re: Singleton Design Posted: Mar 15, 2003 12:52 PM
Reply to this message Reply
> 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.
>

Yes, but I'd probably keep it static until I needed to pass that object around to other objects. Also, it sounds like Matt wants to track some application-global state, so that would need to remain a singleton. Even if he made the class non-static, he would somehow have to ensure that there's only one copy of the object around. Well, I guess, he could then use a static getInstance() for that...


> 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).

That sounds like part of that object's contract, though - to call close() once, and only once, and to not be able to call close() after that one call.
>

Geoff Sobering

Posts: 13
Nickname: geoffs
Registered: Apr, 2003

Re: Singleton Design Posted: Apr 24, 2003 11:16 AM
Reply to this message Reply
Just FYI, the pattern you describe isn't a Singleton, it's the closely related "Monostate":
http://c2.com/cgi/wiki?MonostatePattern

Cheers,

Geoff Sobering

Manish

Posts: 2
Nickname: manish22nd
Registered: Jun, 2003

Re: Singleton Design Posted: Jun 5, 2003 1:02 AM
Reply to this message Reply
> 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?
>
> 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?

Well, if we were to go with the implementation based solely on static methods, then that class would'nt be a "true Singleton" 'coz static is not associated with any object. Singleton is one of the creational design patterns which means it deals with creation of objects. Hence, having constructor private or protected(for sub-classing) means that this would be a true singleton 'coz then we would be dealing with the actual creation of Singleton instance.

Vlad Roubtsov

Posts: 20
Nickname: vladr
Registered: May, 2003

Re: Singleton Design Posted: Jun 5, 2003 1:12 PM
Reply to this message Reply
Using a Factory-based design (vs a purely static API) allows the singleton instance to implement an interface or derive from an abstract class.

The requirement to be able to close() a Singleton seems at odds with the requirement of this item being a Singleton.

If you do not need a globally accessible/always available single instance ("Singleton") then perhaps what you are really looking for is an object pool/bank that limits the number of instances to 1 max, will create one lazily, and will deallocate it when no client references remain.

The latter can be accomplished using a Factory that gives away proxies to the single instance and uses a Weak/PhantomReference internally to retain the said instance.

More hardcore cleanup requirements (such as cleaning up temp files etc) can be handled via JRE exit hooks (Runtime.addShutdownHook()).

Thomas SMETS

Posts: 307
Nickname: tsmets
Registered: Apr, 2002

Re: Singleton Design Posted: Sep 1, 2003 4:00 PM
Reply to this message Reply
Matt,
Most answers have been provided.
Actually on the project most business class have they constructors hidden & the instances have to be constructed thru' the Factory located on a Manager.
You have therefore something like this :
public interface BankAccount
{
  public float getCash ();
  public void withdraws (float aPositiveAmount)
    throws BusinessException;
  public void add (float aPositiveAmount)
    throws BusinessException;
}
 
public abstract BankAccountManager
{
  private static BankAccountManager instance = null;
 
 
  public static BankAccountManager getInstance ()
  {
     if (instance == null)
       instance = Class.forName (SomeProperty).newInstance (); // This may thrown many Exceptions
 
     return instance;
  }
 
 
  public abstract BankAccount getBankAccountByAccountNumber (double aBankAccountNumber)
    throws BusinessException;
}


This was the result of a weird "business" non-fucntionnal requirments related to a DAO-pattern : Namely be compatible with Versant & Oracle.

Having as few as possible variables shared at the abstract class level makes the code completely error free with respect to Multi-threading & very efficient !

About the closing of the instance...
Why don't you implement the finalizer & request all finalizer to be executed ?

\T,.

Vincent O'Sullivan

Posts: 724
Nickname: vincent
Registered: Nov, 2002

Re: Singleton Design Posted: Sep 19, 2003 5:39 AM
Reply to this message Reply
> About the closing of the instance...
> Why don't you implement the finalizer &
> request all finalizer to be executed ?
>
> \T,.
Does requesting that the finalizer be called do anything useful? Without the request, you can't guarantee when (or if) the finalizer will be run. With the request, you still can't guarantee when (or if) the finalizer will be run.

Vince.

Flat View: This topic has 8 replies on 1 page
Topic: Site to work faster Previous Topic   Next Topic Topic: some thoughts

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use