Tuesday, February 19, 2008

Singletons, Good Design or Global Disaster?

Singletons are objects that are instantiated only once throughout the life of your application. Singletons can be very useful, but like most things if they are over used they can create problems. In most cases if you can avoid using a singleton you should. With that said lets take a look at singletons and you can decide for yourself where and when to use them.

In C# a declaration of a singleton is very simple. It is simply a static object. Example:


public static MyClass MySingleton;

When you reference MySingleton you will always receive the same object from anywhere within your application. There are exceptions to this. In C# you must be in the same application domain. To ensure that other developers can't instantiate MyClass elsewhere you can make the constructor private.

Since singletons are globals and as such can be referenced anywhere in the application instantiation of the singleton is critical. I will describe 3 methods to instantiate your singleton: automatic, lazy and managed. There are strengths and weaknesses to each.

Automatic instantiation is when the singleton is created on application start. Example:

public static MyClass MySingleton = new MyClass();

This instantiation can't be used if the class constructor requires variables that are not available during application start. If you can change the MyClass constructor you can change it to not take variables, but it would not be ready to use until you set the required properties. Another option is lazy initialization.

Lazy initialization is when you instantiate your singleton on first use. Example:

public class MyClass
{
private static MyClass _mySingleton = null;

public static MyClass MySingleton
{
get
{
if (_mySingleton == null)
_mySingleton = new MyClass();

return _mySingleton;
}
}
}

In this example you would call MyClass.MySingleton to get the instance of MyClass. This is the method I prefer, but it can get messy if you have dependences. If you need more control of the initialization process you should use managed initialization.

Managed initialization gives you total control of initialization of a singleton. You get to/have to manually initialize the singleton. This means that you need to ensure that you have fully initialized your singleton before you use it. Example:

public class MyClass
{
private static MyClass _mySingleton = null;

public static MyClass MySingleton
{
get { return _mySingleton; }
set { _mySingleton = value; }
}
}

This just exposes the MySingleton object as a property. You would need to new up a MyClass object and assign it to MySingleton. Example:


MyClass.MySingleton = new MyClass();


With managed initialization you need to ensure that you initialize the MySingleton object before you try to use it. You could help ensure the MySingleton object is initialized by including an error when trying to use the MySingleton object without first initializing it. Example:

public class MyClass
{
private static MyClass _mySingleton = null;

public static MyClass MySingleton
{
get { return _mySingleton; }
set
{
if (_mySingleton == null)
throw new Exception("MySingleton has not been initialized yet.");

_mySingleton = value;
}
}
}

This will just help identify runtime errors quicker and easier.

So as you can see you can use any class as a singleton. Singletons can be initialized in a few different ways. The main advantage to Singletons can be it's weakest and strongest benefit. Singletons, because they are just a global variable, can be called anywhere in your application. This can be very helpful for classes that need to be used in many different places. This can be a problem when it comes to testing. If your testing a method that calls anything in a singleton the singleton needs to be setup for the test as well, and thus is tested as well. This also prevents the use of mock objects in testing. If you would like to learn more about mock objects check out this paper.

Singletons are a simple design pattern that can be a great tool, just consider the risks when using them.

Save to del.icio.us Add to Technorati Add to dzone

Friday, February 15, 2008

String is a reference or a value type?

I've had a number of discusions about value types and reference types in .NET. Some developers have a good dictionary meaning of a reference type and a value type. Getting down to the nitty gritty of reference types and value types seems to stump even some of the brightest developers.

A few years ago I was interviewing for a software development position at a larger company and the interviewer asked what is the difference between a reference type and a value type. Wanting to make a good impression I whipped out my detailed dictionary answer: "A reference type is a pointer to a place in memory where a class or other object is located. A value type is the binary value." The interviewer then wanted to verify my knowledge by showing me this method:

void Calc(int x)
{
   x = 3;
}

and asking what would be outputted if he ran:

int x = 2;
Calc(x);
Console.WriteLine(x.ToString());

And I answered that it would output 2. This is true because the x value is copied to the Calc method. In the Calc method the x value is in a completely different memory location, so changing x in the Calc method doesn't do anything to the original value passed in.

The interviewer then declared a class:

public class MyObject
{
   public int x;
}


He changed the method to be:

void Calc(MyObject myObject)
{
   myObject.x = 3;
}

And asked what would be outputted in this code:

MyObject myObject = new MyObject();
myObject.x = 2;
Calc(myObject);
Console.WriteLine(myObject.x.ToString());


I answered that the output would be 3. This is true because myObject.x in the WriteLine statement points to the same myObject.x in the Calc method. This is because the myObject reference, despite being copied into the Calc method, still is a reference. A pointer to the myObject class instance. A different pointer, but to the same memory location.

The interviewer then changed the Calc method:

void Calc(MyObject myObject)
{
   myObject = new MyObject();
   myObject.x = 3;
}


He asked again what does the following code output:

MyObject myObject = new MyObject();
myObject.x = 2;
Calc(myObject);
Console.WriteLine(myObject.x.ToString());


I answered 2. That is because since the myObject reference in the Calc method is set to a new MyObject instance the x value that changes isn't the instance in the myObject that was passed into the Calc method. So why doesn't the myObject value change to the new instance? Because the myObject reference is a copy of the reference that was passed in. Meaning that the myObject reference in the Calc method points to the same class instance, but if itself is changed to point to something else the copied value that was passed into the Calc function still will not change.

The interviewer then asked what if you wanted to be able to new up new objects in the Calc method and have them affect the myObject that was passed in what would need to be changed?

I said the myObject value would need to be passed in by reference and I made the following code changes:

void Calc(ref MyObject myObject)
{
   myObject = new MyObject();
   myObject.x = 3;
}

MyObject myObject = new MyObject();
myObject.x = 2;
Calc(ref myObject);
Console.WriteLine(myObject.x.ToString());


Now it would output 3. This is because the myObject is now the same inside the Calc method as it is when it is passed in. It is no longer copied.

The interviewer then changed MyObject to string. Here is the code:

void Calc(string x)
{
   x = "3";
}

string x = "2";
Calc(x);
Console.WriteLine(x);


Then the interviewer asked what was x?

So what is it? Looks similar to the int example doesn't it? String isn't a simple value. String is a reference type. And when you assign "3" to it you are essentially pointing the reference to a new memory location containing "3". And since we did not copy the string by reference the x assignment in the Calc method doesn't affect the output. The original "2" assignment is displayed.

The Interviewer then asked what would the following output:

public class MyObject
{
   public MyObject(int x) { this.x = x; }
   public int x;
}

MyObject a = new MyObject(1);
MyObject b = new MyObject(1);
Console.WriteLine(a == b);

I answered it would output false. Even though the values in the class are the same the equals operator compares the reference or the pointer (the area in memory) not the values since it is a reference type.

Then he asked then what about this:

string a = "1";
string b = "1";
Console.WriteLine(a == b);

It's a reference type, but you know that they are equal. Why? Because strings overloaded the equals operator to compare the string value and not the reference which is the default behavior for reference types.

So strings along with classes, arrays and delegates are reference types. Values types include all numerics (int, double, etc...), bool, char, date, struct (even if they include refs) and enumerations (enum).

Save to del.icio.us Add to Technorati Add to dzone

Tuesday, February 12, 2008

Family Website with Blog and Pictures

Seems like a simple request, right? Well it wasn't an easy choice for me because I had previously created a ASP web album and family web site that had some unique features. Single or groups of pictures could be tagged. Pictures could be searched based on people in the picture, tag and date range. I created a VB6 app to upload and label the pictures which was converted to C#. It worked fairly well, but I eventually stopped maintaining the web site. A few years ago I tried to revive it from the dead, but it was past it's prime. My first thought was to just do something similar in ASP.NET. Well after I had outlined what I wanted to do it would be quite a bit of work. There has to be others out there that want the same type of web site, so I scowed the internet to see what was available. I tried dotNetNuke. It was close to what I wanted so I went to find a host. Since my domain was registered with godaddy I gave their hosting a shot. Well long story short it wasn't going to be easy to get dotNetNuke up and running. I did get it limping along, but this needed to be quick and take as little time as possible. I tried a few other things: WordPress, Weebly, Familiva. I ended up using blogger with Picasa's web albums. This is easy to use. Maybe in the future I'll have some time to whip up a snazzy family site again. If you want to check out my family's blog visit www.jjesnroth.com.

Save to del.icio.us Add to Technorati Add to dzone