views:

553

answers:

4

While reading Jon Skeet's article on singletons in C# ( http://www.yoda.arachsys.com/csharp/singleton.html ) I started wondering why we need lazy initialization in a first place. It seems like the fourth approach from the article should be sufficient, here it is for reference purposes:

public sealed class Singleton
{
    static readonly Singleton instance=new Singleton();

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static Singleton()
    {
    }

    Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            return instance;
        }
    }
}

In the rare circumstances, where you have other static methods on a singleton, lazy initialization may have benefits, but this is not a good design.

So can people enlighten me why lazy initialization is such a hot thing?

+9  A: 

In those scenarios where whatever it is you are initializing might not be needed at all, and is expensive to initialize, (in terms of CPU cycles or resources), then implementing a lazy initializor saves that cost in those cases where the object is not required.

If the object will always be required, or is relatively cheap to initialize, then there is no added benefit from a lazy initializer.

In any event, implementing a lazy initializer improperly can make a singleton non-thread-safe, so if you need this pattern, be careful to do it correctly. Jon's article has a pattern, (I think it's the last one), that addresses this issue.

Charles Bretana
Also note that in .NET 4, the preferred method will likely be to use `System.Lazy<T>` (http://msdn.microsoft.com/en-us/library/dd642331(VS.100).aspx)
Pavel Minaev
my problem is that I don't see a use case for lazy initialization -- we always need to initialize a singleton class if we decide to use it, however, if we don't call methods that use singleton object, it does not get created, so I don't see a use case.
Lenik
@Lenik, that sounds like you don't need (and shouldn't) use lazy initialier - not a problem.
Charles Bretana
@Charles, I don't see how anyone needs it. even if I don't use lazy initialization, I still effectively get it since the static property won't get initialized unless I am actually using it.
Lenik
@Lenik, What if someone makes a reference to your class to use some other property or class member that does not need whatever object is being initalized on demand lazilly? Even in a Singleton, (not that this would be good design) but what if the singleton class has a static utility method? It might get called in cases where the Singleton instance is not needed at all... If you initialze the singleton instance in a static initializer, it would get initialized unecessarilly.
Charles Bretana
@Charles, Completely agree with your last comment. In general, I just felt that lazy initialization in singletons was receiving too much attention given how rarely you would actually do something like this in practice.
Lenik
@Lenik, I agree with you, and the edge case I mentioned in my last comment is probably not good design pattern for a Singleton class, as it would clearly violate that "Single Responsibility" principle that a class should be designed to pnly do one simple thing.
Charles Bretana
"If the object will always be required ... then there is no added benefit from a lazy initializer" - not necessarily true, sometimes it's valuable to defer the cost of creation.
Joe
@Joe, "Sometimes it's valuable to defer ... " When? Why? What value? If it has to be created anyway, the only difference is the small memory saved during whatever period of time exists between the first reference to the static singleton Type, (assumning u init it in a cctor), and when it is needed, (if you init it lazilly). Why would that be valuable? If you;re that short of memory, you have other more important issues, no?
Charles Bretana
+1  A: 

I'm not sure that this applies to C# as well, but I'll answer for C++:

One of the ideas behind Singletons is that the order of initialization of static objects is undefined. So if you have a static class that tries to use another static class, you might be in trouble.

A concrete example: Let's say I have a Log class, which I decided to implement as a Singleton. Let's also assume I have a method called LoadDB, which for whatever reason, is a static called at the start of the program. Assuming LoadDB decides it needs to log something, it will call the Singleton. But since the order of static initialization is undefined, it might be doing something that's an error.

A Singleton fixes this, since once you call GetInstance(), no matter where you are in the initialization process, the object is guaranteed to exist.

Again, I don't know if this is relevant, but at least that's the history of it (as far as I remember).

Edan Maor
+2  A: 

You don't need lazy initialization on a singleton, if the only reason you're going to use that type is to reference the instance.

If, however, you reference any other property or method on the type, or the type itself, you will initialize the singleton.

Granted, good design would leave one task for one type, so this shouldn't be a problem. If you make your singleton class to "complex", however, lazy initialization can help keep you from having consequences due to initializing too soon.

Reed Copsey
ok, so I am not crazy then. it just seems that everyone is obsessed with some form of lazy initialization where the reality is that the use case is almost non-existent.
Lenik
Lazy initialization is incredibly useful as a general practice, just not necessarily for singletons.
Reed Copsey
@Reed, totally agree.
Lenik
A: 

From Java DI perspective, lazy initialization is good, there are always (say, spring) beans in another API that you might not want to use, for example, an eagerly loaded singleton cache (something that is shared with everyone using the cache) might not be needed for you although it may be referred as a dependency in your same code. Whats the point in loading the singleton wasting resources?

The lazy initialization implementation choice is tricky, in spring, would you choose lazy-init="true" (spring eagerly instantiates singletons), an init-method/destroy-method, @PostConstruct, InitializingBean - afterPropertiesSet() method or return same spring instance in a getInstance() method?

The choice is a tradeoff of testability over reusability outside the spring container.

Also, tricky is where would you initialize your resources, in the constructor? or in another method that is invoked by the container that returns the same instance each time?
Also, tricky is where would you initialize your resources, in the constructor? or in another method that is invoked by the container that returns the same instance each time? In the case of delegating instantiation, calling initialize(), to spring, unit testing requires explicitly calling initialize() to get a valid instance. Spring, for example, allows creating a singleton using a private constructor, but allows initializing as late as someone calls a getInstance() on this instance. This pushes the initialization into another method rather than a constructor but how would you test/mock?