Saturday, April 7, 2012

Using a singleton (anti?)pattern

Some things that always apply to a Singleton Pattern (a pattern that falls into the creational pattern category):
  • Think twice before using a singleton. Singletons can be bad for: parallel unit tests, dependency coupling, scalability, performance, memory management, complex threading issues (see here and here and countless others).
  • Always use interfaces with your singletons.
  • Always return the interface from the default static property.
  • Prefer using a static default property that returns an interface over static methods that access a private static field. (This helps enforce the pattern when other developers add new members to the singleton).
  • Always use a private constructor, this prevents any ad-hoc use of the class bypassing the singleton. (No one can create the class so you can only use the static Default property).
  • Seal your singletons.  This will disallow someone sub-classing it then instantiating it as a transient class and bypassing the singleton.
  • By definition, a singleton should be constructing only when it is first used.

Ok, so you insist on using a Singleton. Very well, lets try to do it with as least smelly code as possible...

All code examples make use of this interface.
namespace SingletonDemo
{
    public interface ISomeSingleton
    {
        void DoSomething();
        string Stuff { get; }
    } 
}


Use a Simple Singleton as a first option. Only use this when you know there will be no thread contention at initialisation time of the singleton. Or maybe it doesn't matter if there is.  This works well for unit testing because you can easily inject a mock singleton using a private accessor (reflection) or you could add a internal setter to the Default property and allow your test project access to internals (see this blog post for more details).

namespace SingletonDemo
{
    public sealed class SimpleSingleton : ISomeSingleton
    {
        private static ISomeSingleton defaultInstance;

        private SimpleSingleton()
        {
            // private ctor to prevent transient usage.
        }

        public static ISomeSingleton Default
        {
            get
            {
                return defaultInstance ?? (defaultInstance = new SimpleSingleton());
            }
        }

        public void DoSomething()
        {
            // omitted...
        }

        public string Stuff
        {
            get
            {
                // omitted...
                return string.Empty;
            }
        }
    }
}

Use what I call a ContentionSingleton when you know there will be thread contention when the singleton is first accessed. This example guarantees only one thread can create the singleton, all other threads wait until it is initialised.

namespace SingletonDemo
{
    public sealed class ContentionSingleton : ISomeSingleton
{
        private static readonly object SyncRoot = new object();
        private static volatile ISomeSingleton defaultInstance;

        private ContentionSingleton()
        {
            // Intialisation code...
        }

        public ISomeSingleton Default
        {
            get
            {
                if (defaultInstance == null)
                {
                    lock (SyncRoot)
                    {
                        if (defaultInstance == null)
                        {
                            defaultInstance = new ContentionSingleton();
                        }
                    }
                }

                return defaultInstance;
            }
        }

        public void DoSomething()
        {
            // Omitted...
        }

        public string Stuff
        {
            get
            {
                // Omitted...
                return string.Empty;
            }
        }
    }
}
Things to note:
  • It is best practise to use a dedicated and separate lock object.  Never use the same lock object for different purposes. The lock object should always be private; no one outside this class should be using it.
  • Declare the singleton instance as "volatile".  This indicates to the runtime that this object might be changed by different threads at the same time. This exempts this field from compiler optimisation that assumes only one thread will access this object at a time. It also guarantees the most up to date value will be in the field at all times.
  • Private constructor.
  • Double check the field both outside the lock and in. This ensures that 2 (or more) threads trying to initialise the singleton at the same time one enters the lock and one waits. Then when the first exits the lock the second will enter the lock, when it does it must not re-initialise the singleton.
  • This still works well with unit testing for the same reasons as SimpleSingleton above.

There is another way to create singleton behaviour which I am not a fan of, Type Initialised Singleton:

namespace SingletonDemo
{
    public sealed class TypeInitialisedSingleton : ISomeSingleton
{
        private static readonly ISomeSingleton DefaultInstance;

        static TypeInitialisedSingleton()
        {
// .NET Runtime guarantees to run static constructors exactly once.
DefaultInstance = new TypeInitialisedSingleton(); // Impossible to intercept during unit testing and mock. } private TypeInitialisedSingleton() { // Connect to Database... // Get data using a bunch of SQL statements... } public ISomeSingleton Default { get { return DefaultInstance; } } public void DoSomething() { // Omitted... } public string Stuff { get { // Omitted... return string.Empty; } } } }


BAD BAD BAD.  There is no way to intercept the static constructor code during unit testing and inject mock behaviour.  As soon as the type is referenced by a piece of code the type initialiser will run.  I would avoid this at all costs.  Even if you don't plan to do unit testing, if you change you're mind later it may be hard to change. Generally speaking type initialisers (OO term for static constructors) should be avoided, and when used only used for simple static member initialisation.  If something goes wrong in the static constructor, even if handled, it can leave the application in a weird state (check this post).



A much improved version of a TypeInitialiserSingleton is the BishopSingleton (named after Judith Bishop and its from her book C# Design Patterns [O'Reilly])

namespace SingletonDemo
{
    public sealed class BishopSingleton : ISomeSingleton
    {
        // Local instance allows for tests to inject mock behaviour
        private static ISomeSingleton localInstance;

        private static class SingletonCreator
        {
            // Despite being internal, this is not visible outside BishopSingleton class.
            internal static readonly ISomeSingleton DefaultInstance;
            
            static SingletonCreator()
            {
                // if localInstance is not-null this will not be called.
                DefaultInstance = new BishopSingleton();
            }
        }

        private BishopSingleton()
        {
            // Initialisation...
        }

        public static ISomeSingleton Default
        {
            get
            {
                return localInstance ?? SingletonCreator.DefaultInstance;
            }
        }

        public void DoSomething()
        {
            // omitted...
        }

        public string Stuff
        {
            get
            {
                // Omitted...
                return string.Empty;
            }
        }
    }
}

This is quite elegant as it doesn't require understanding intricacies locking code and gives a means of tests injecting mock singletons (using private accessors). Although you will get Resharper and Code Analysis warnings that localInstance is never assigned, which feels a little dirty. Which is better? I personally prefer using SimpleSingleton when I know there is no thread contention and ContentionSingleton otherwise.  It is more obvious to the average developer what is going on inside the ContentionSingleton compared to the BishopSingleton in my humble opinion.

Finally, think once, twice, and thrice before using a Singleton, prefer using dependency injection, Inversion of Control, or a query or factory pattern, or even caching data in a shared way (MemCache or AppFabric).

Sunday, April 1, 2012

Juval Löwy's (IDesign.net) Architecture Clinic

Recently I had the privilege of attending the IDesign Architecture Clinic in Sydney. It was a week long intensive mix of the architecture theory, the responsibilities of an architect, and practical coaching.  IDesign runs two similar courses in the software architecture stream: The Architect's Master-Class and the Architecture Clinic. The idea behind the Clinic is to keep the attendee numbers relatively small and have the opportunity to learn from a true master architect.  In Sydney my group was lucky to have Juval himself run the course.

Day one was full on.  Juval gave us a light speed overview of some of the critical material from the Architect's Master-class. The rest of the week was then practical hands-on experience using IDesign's "The Method". Days two, three and four followed the pattern of choose one of the attendee's systems and use The Method to draw up a proposed new architecture. Then Juval and the group will critique. Day five was all about project design, planning, and tracking.

The amount of knowledge and experience imparted during this course was simply incredible.  No other speaker I have ever listened to has packed this amount of information into five days.  There isn't more than a few handfuls of other people in the software industry that have the same level of industry insight and where it is heading in the next 10-20 years. During conversations there were more than a few statements that gave us a glimpse of where the industry is heading.  As a bonus Juval also kindly donated two of his evenings and run us through some other topics in depth, from the Architect's Master-class.

Anyone who has listened to Juval speak will know he is both highly intellectual and controversial. He often makes statements that send murmurs through an audience.  This course was no exception.  Some examples (not direct quotes):

  • Every class as a WCF service.
  • The Method doesn't fit well with Agile.
  • The Architect is the responsible party not the project manager.
  • Most project managers actively kill their projects.
  • Self managing teams don't work.
For most questions the general answer was "there is no time, you need to attend the Architect's Master-class".  Other vague answers sounded as though he was hinting at some future technology now under development but is bound by NDA's. There were some answers, but with anything new and revolutionary every question reveals 3 more.

My personal opinion on this course was that it was worth while (it is definitely not a cheap course), but I would have liked to have completed the Architect's Master-class first.  I also believe that there was too much after-the-fact review based criticism and not enough coaching.  For days two, three, and four we were left to decompose the system and draw up our own plan for the whole day, whereas I would have preferred to have been walked through it from start to completion on day two before the practical on days three and four. Again just my personal opinion, and like I said still very worth while.

So, did I rush back to the office and evangelise all my co-workers and stakeholders? 
No. 
Why?
Because I cannot sell a new idea to my stakeholders without having prepared answers to the questions I know they will ask. Questions like: "We are a Scrum-Software-House, this doesn't fit with Scrum. You are not permitted to undertake projects in this way". Or "We hired you as an Architect not a project manager, you are operating outside your responsibilities". Or "Some of what you are prescribing infringes on senior developers responsibilities of technical design, architects should not be prescribing technical design".  And my favourite: "We don't have enough architects to operate this way and no-one wants to be an architect". The answers to these questions are not the kind you can Google and Juval simply recommends go to the Architect's Master-class.  So I'm filing this learning under "Interesting future insights that can't be used right now".

Can I justify going to the next Architect's Master-class?  
Probably not for a while.  Due to corporate politics its unlikely I can sell another course in the next 12 months just for me given the overall cost of fees, flights and accommodation (planned courses are only in the States). Also given that this one has not set my architecture team on fire with new levels of efficiency.

There's no easy solutions, just broad wholesale change.

Thursday, February 23, 2012

Running Unit Tests in Parallel

Its been possible to run unit tests in parallel for some time now, but it doesn't seem to have taken off. NUnit has had a parallel runner (PNUnit) since 2007, MsTest since 2009. I think running tests in parallel has two distinct benefits:
  1. The test run will complete a little sooner.
  2. It will help to test your system for concurrency issues.
HOWEVER, all your tests must be thread-safe. Writing unit tests that can be run in parallel can be difficult and designing and writing a system that allows parallel unit testing can be even harder. Statics and singletons will be the undoing.

So how do you set up tests to run in parallel?

For MsTest you will need to edit the .TestSettings file with a text editor (or right click in Visual Studio and open with Xml Editor).


Set the number to the number of cores you want to use for running tests. Setting this to a number greater than cores you have in your system will have no benefit. Setting it to 0 will auto-configure and use as many cores as the runner can. Remove the attribute completely to disable.

This will then ensure running the tests from within Visual Studio's Test menu run in parallel. (Make sure the testsettings file you modified is selected as the current active settings file, do this in the Test menu). If you're using Resharper I'm not certain it honour's all the settings in the testsettings file. (I didn't notice any difference with parallel enabled).

Setting it up for NUnit is a bit easier, it simply means you use a different runner. The bad news is that its command-line only with no integration into Visual Studio. See PNUnit for details on downloading the runner.


Friday, February 10, 2012

Optimised binary serialisation and serialisation tips

During some research a colleague of mine (thanks Richard)  has done into serialisation lately, two code project articles came to my attention.

Top Ten Caching mistakes, and
Optimizing Serialisation in .NET

The first one talks about some common mistakes and why they are mistakes and also some mitigation techniques.

The second talks about the problems using XML, DataContractSerialisation (or any text based serialisation for that matter).  Basically, they can be much slower than what you require. Also the binary serialisation and deserialisation process can create unnecessary data.  The article shows a custom binary serialiser that looks very useful.