This post originated from an RSS feed registered with .NET Buzz
by Paul Vick.
Original Post: Singletons and Default Instances
Feed Title: Panopticon Central
Feed URL: /error.aspx?aspxerrorpath=/rss.aspx
Feed Description: a blog on Visual Basic, .NET and other stuff
In my previous entry, I described what default instances are but left open the question of why we're re-introducing them into the language. So let me spend a moment discussing that.
A default instance is, more or less, an instance of the design pattern called a singleton. A singleton is a type that only ever has one instance (hence the "single" part of "singleton"). Forms are often an excellent example of singletons because there is usually only ever going to be one instance of the form (with the exception of less common situations like MDI windows). For example, you only need one instance of the File Open dialog because there will only ever be one File Open dialog on the screen at a time. Rather than having to allocate an instance of the dialog every time you need one, or holding on to the same instance in some random place in your application, a singleton has a central location where the single instance is stored.
In most languages, you have to manage singleton objects yourself. This is usually accomplished by sealing the type (i.e. making it NotInheritable), making it uninstantiable (i.e. making its constructor Private) and exposing a shared property called something like DefaultInstance that returns, well, the default instance. If only the language would do that management for you automatically, how nice would that be? If only...
So now we arrive at the rationale for default instances, aka singletons: we think it's a more natural way of working with objects that always or almost always have a single instance.
I've been using forms as an example up until this point, but let me expand the scope a little bit to illustrate my point. Web services are another example of a natural singleton object. When an application interfaces with a remote web service, there is typically only ever going to be one web service proxy instantiated. In VB 2002 and 2003, it is necessary to create a new instance of a web service proxy and then hold on to that instance for as long as you wish to use the service. If you wanted to share the service across multiple objects, you had to make sure to store the instance somewhere where everyone who needed it could get at it. And, truth be told, all of this management code had nothing to do with your program logic. It was just boilerplate that everyone has to write again and again and again.
In constrast, VB 2005 adds a default instance to web services. When you add a reference to a web service Bob, you automatically get a default instance at My.WebServices.Bob. No need to remember to create an instance of the proxy. No need to sock that proxy away somewhere so that everyone can get at it. It's just... there. Without you having to do anything to make it so.
This seems like a good thing, but don't just take my word for it. After all, you can go read about how to implement the singleton pattern in C# and how to implement singleton forms in C#. And then you can come back to VB and find that we already did it for you... (I should add that Justin's singleton form entry touches on a specific problem having to do with the design of WinForms that I'll address in the next entry.)
Well, that's about it for the moment but we're not done yet... I still need to cover the problems and issues that have been raised around default instances, which I will cover next. That entry, tentatively titled "Default Instances Considered Harmful" is coming soon.