You want to store common data that is only needed in one location, using a singleton or static class. Save state between usages and store some caches. The object must be initialized only once and shared. Here we discuss the singleton pattern and static classes from the C# language with examples.

Singletons can be used differently than static classes.
    This design pattern can be used with interfaces.   
    Singletons can be used as parameters to methods.   

Implementing singletons

First, you can implement singletons by using language-specific features, such as the static keyword. Our ideal solution is called the singleton design pattern. As you know, a singleton is a single-instance object, and they simplify complex code. Singletons have a static property that you must access to get the object reference.

=== Singleton implementation (C#) ===

/// <summary>
/// Sample singleton object.
/// </summary>
public sealed class SiteStructure
{
    /// <summary>
    /// This is an expensive resource we need to only store in one place.
    /// </summary>
    object[] _data = new object[10];

    /// <summary>
    /// Allocate ourselves. We have a private constructor, so no one else can.
    /// </summary>
    static readonly SiteStructure _instance = new SiteStructure();

    /// <summary>
    /// Access SiteStructure.Instance to get the singleton object.
    /// Then call methods on that instance.
    /// </summary>
    public static SiteStructure Instance
    {
        get { return _instance; }
    }

    /// <summary>
    /// This is a private constructor, meaning no outsiders have access.
    /// </summary>
    private SiteStructure()
    {
        // Initialize members, etc. here.
    }
}

It has a static readonly member. In the example above, the member called _instance is a static instance of the SiteStructure class. This means it only can be created once by the runtime. Static members only exist in one place. We use this static reference to an actual, regular object.

(See Readonly Field Usage.)

It has an Instance property. The Instance static property allows easy access to the SiteStructure singleton. This is a public property and is also called a getter.

It has a private constructor. Having a private constructor means that a class cannot be created anywhere but inside its own methods. So it must be accessed through the singleton reference. Finally, it uses the sealed keyword decoration to improve some optimization options.

(See Sealed Class Test 1.)

Understanding singletons

There are important differences between the singleton design pattern and the static keyword on classes. Static classes and singletons both provide sharing of redundant objects in memory, but they are very different in usage and implementation.

Making static classes

You can make a static class with the static keyword. In the following example, look carefully at how the static keyword is used on the class and constructor. Static classes may be simpler, but the singleton example has many important advantages.

=== Static class example (C#) ===

/// <summary>
/// Static class example. Note the static keyword usage.
/// </summary>
static public class SiteStatic
{
    /// <summary>
    /// The data must be a static member in this example.
    /// </summary>
    static object[] _data = new object[10];

    /// <summary>
    /// C# doesn't define when this constructor is run, but it will likely
    /// be run right before it is used.
    /// </summary>
    static SiteStatic()
    {
        // Initialize all of our static members.
    }
}

Used for global data. You can use static classes to store single-instance, global data. The class will usually be initialized lazily, at the last possible moment. However, you lose control over the exact behavior and static constructors are slow.

(See Static Constructor.)

Advantages of singletons

Singletons preserve the conventional class approach, and don't require that you use the static keyword everywhere. They may be more demanding to implement at first, but will greatly simplify the architecture of your program. Unlike static classes, we can use singletons as parameters or objects.

=== Using singleton as parameter (C#) ===

//
// We want to call a function with this structure as an object.
// Get a reference from the Instance property on the singleton.
//
SiteStructure site = SiteStructure.Instance;
OtherFunction(site); // Use singleton as parameter.

Using singletons with interfaces

You can use singletons with interfaces just like any other class. In C#, an interface is a contract, and objects that have an interface must meet all of the requirements of that interface.

=== Singletons used with interface (C#) ===

/// <summary>
/// Stores signatures of various important methods related to the site.
/// </summary>
public interface ISiteInterface
{
};

/// <summary>
/// Skeleton of the singleton that inherits the interface.
/// </summary>
class SiteStructure : ISiteInterface
{
    // Implements all ISiteInterface methods.
    // [omitted]
}

/// <summary>
/// Here is an example class where we use a singleton with the interface.
/// </summary>
class TestClass
{
    /// <summary>
    /// Sample.
    /// </summary>
    public TestClass()
    {
        // Send singleton object to any function that can take its interface.
        SiteStructure site = SiteStructure.Instance;
        CustomMethod((ISiteInterface)site);
    }

    /// <summary>
    /// Receives a singleton that adheres to the ISiteInterface interface.
    /// </summary>
    private void CustomMethod(ISiteInterface interfaceObject)
    {
        // Use the singleton by its interface.
    }
}

Reusing the singleton. Here we can use the singleton on any method that accepts the interface. We don't need to rewrite anything over and over again. These are object-oriented programming best practices. You can find more detailed examples on the interface type in the C# language here.

(See Interface Program 1.)

Summary

Here we looked at some aspects of the singleton design pattern in the C# language. Singletons allow you to reuse code and control object state much easier. This improves code-sharing, and can result in a far cleaner body of code. With less code, your programs will usually have fewer bugs and will be easier to maintain.

(Do not copy this page.)

【by Sam Allen - Updated January 24, 2010】

posted on 2010-04-09 19:22  GT_Andy  阅读(354)  评论(0编辑  收藏  举报