Nerdy tidbits from my life as a software engineer

Wednesday, February 18, 2009

Singleton vs Repository

The Singleton pattern is probably one of the most common design patterns you’ll see over your career.  Understandably.  But a while ago, I read through Martin Fowlers’ excellent Patterns of Enterprise Application Architecture and discovered the very simple repository pattern – and I’ve found myself using that instead more and more frequently.  So what’s the difference and why do I like it so much?

I don’t know; much if it is semantics I suppose.  But what I like about the Repository pattern is that it’s hiding the singleton nature of a class from it’s consumers.  There’s something about that implementation that, to me, looks very elegent.  In the end, the two patterns accomplish the same thing – but one ends up being just a little bit more convenient to invoke than the other.  And there are benefits to making calls convenient to the consumer of a class.

You might do something like this for a singleton:

public class Singleton
{
    /// <summary>
    /// This is the one and only instance of the singleton.
    /// </summary>
    private static Singleton mInstance;

    /// <summary>
    /// The static constructor creates the one and only instance.
    /// </summary>
    public static Singleton()
    {
        mInstance = new Singleton();
    }

    /// <summary>
    /// Creates the singleton.
    /// </summary>
    private Singleton()
    {
        ...
    }

    /// <summary>
    /// Returns an instance to the singleton.
    /// </summary>
    public static Singleton
    {
        get
        {
            return mInstance;
        }
    }    

    /// <summary>
    /// Access some property.
    /// </summary>    
    public bool SomeValue
    {
        get;
        set;
    }

}

Now when you want to get the one and only value of SomeValue, you do this:

...
if(Singleton.Instance.SomeValue)
{
    ...
}

Now with the repository pattern, you can access singleton-like properties and methods as though the object you were accessing was just a regular object with static methods and properties.  Here’s what the same object looks like as a Repository:

public sealed class Repository
{
    /// <summary>
    /// This is the one and only instance of the repository.
    /// </summary>
    private static Repository mInstance;

    /// <summary>
    /// This bool contains some interesting value.
    /// </summary>
    private bool mSomeValue;

    /// <summary>
    /// The static constructor creates the one and only instance.
    /// </summary>
    public static Repository()
    {
        mInstance = new Repository();
    }

    /// <summary>
    /// Creates the singleton.
    /// </summary>
    private Singleton()
    {
        mSomeValue = true; // or whatever
    }   

    /// <summary>
    /// Get / set some property.
    /// </summary>    
    public bool SomeValue
    {
        get
        {
            return mInstance.mSomeValue;
        }
        set
        {
            mInstance.mSomeValue = value;
        }
    }

}

What’s nice about this is that you no longer need to access the Repository’s one and only instance via the Instance property.  This really helps with readability.  To get the one and only value of SomeValue, you can simply do this:

...
if(Repository.SomeValue)
{
    ...
}

In exchange for this syntax convenience, you are now required to write a bit more plumbing code.  You also, admittedly, lose a bit of flexibility with unit testing.  For instance, one way that I’ve always liked to mock out singletons is by doing something like this:

public interface ISingleton
{
    bool SomeValue
    {
        get;
        set;
    }
}

public class Singleton : ISingleton
{
    /// <summary>
    /// This is the one and only instance of the repository.
    /// </summary>
    private static Singleton mInstance;

    /// <summary>
    /// The static constructor creates the one and only instance.
    /// </summary>
    public static Singleton()
    {
        mInstance = new Singleton();
    }

    /// <summary>
    /// Creates the singleton.
    /// </summary>
    private Singleton()
    {
    }   

    /// <summary>
    /// Get / set some property.
    /// </summary>    
    public static Singleton Instance
    {
        get
        {
            return mInstance;
        }

    }

    /// <summary>
    /// Get / set some property.
    /// </summary>    
    public bool SomeValue
    {
        get;
        set;
    }

}

public class Consumer
{
    public Consumer()
    {
        this.SingletonInstance = Singleton.Instance;
    }

    public ISingleton
    {
        get;
        set;
    }
}

Now in your unit tests, you can create a mock on an ISingleton object, inject it into your code, and test methods on the Consumer class.  I haven’t really looked into how to test repositories – I’m sure there’s a way, but unfortunately, static methods don’t count against an interfaces implementation.  And that’s a bummer, because I figure you’d have to use some sort of wrapper class around a repository so that it could be mocked and tested.

Something to think about.

0 comments: