The Monostate pattern

Most people are quite familiar with the Singleton pattern. This is probably one of the most widely used and widely abused patterns in existence today. The Singleton pattern forces its users to only access a single instance of a class. This is usually accomplished by making the constructor of a class private and then providing a static property or method through which this single instance can be accessed. A simple implementation would look like this:

public class Singleton
{
    private static Singleton instance;
 
    private Singleton()
    {
    }
 
    public static Singleton Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new Singleton();
            }
            return instance;
        }
    }
 
    public String DataItem { get; set; }
}

In this example I have included a single data member to show you that these are just normal instance members like you would have in any class. Then you can see that we have a static Instance property and a static instance private data member. You would consume this class like this:

Singleton single = Singleton.Instance;
single.DataItem = "value";

There are several complaints that people have about this pattern. First of all is the way in which it is instantiated. Calling Singleton.Instance to get your class is not exactly a standard, what happens when you one day decide that this class should no longer be a singleton? Well, you have to touch every part of your application that calls the “Instance” property. You’d probably be better off wrapping your Singleton creation inside of a factory method to begin with. At least then you won’t have to change every part of your code that accesses your singleton.

Other complaints that people have involve memory leaks, holding onto resources that should be let go, global variables, testing, etc… There are quite a few people who feel very strongly about the fact that Singleton is actually an anti-pattern. Well, let me first say that Monostate will not make any of these people happy.

The Monostate pattern tries to accomplish something similar, but in a very different way. Generally speaking, the Monostate pattern attempts to hide the fact that a class is only operating on a single instance of data by using static data members. This way, consumers of this class will feel as if they are instantiating their own instance, but in fact will be accessing static data.

The Monostate pattern is nothing new. As far as I can tell, it was first described in the September 1996 issue of the now defunct “C++ Report” magazine. I will first start off by showing you how the Monostate pattern is instantiated and used:

var single = new Monostate();
single.DataItem = "value";

You may be looking at this and saying, well, he is just creating a new class. I’m not sure how this helps me with the Singleton pattern. And you have inadvertently unearthed the single biggest complaint that is unique to the Monostate pattern. You cannot tell when you are using a Monostate object other than to look at its internal implementation. This is how that above code would be implemented:

public class Monostate
{
    private static string dataItem;
    public string DataItem
    {
        get { return dataItem; }
        set { dataItem = value; }
    }
 
    public Monostate(){ }
}

As you can see, all we do is use instance properties with static private data members. It is quite the sneaky little pattern. Everyone who uses the class will not know that they are dealing with a single backing data item. This could be good or bad depending on how you look at it.

The Monostate pattern does not solve all of the problems that the Singleton pattern has, but it does provide an interesting way to keep single data values, while still allowing your classes to have multiple instances. Monostate classes are also easier to inherit from and modify than their Singleton counterparts, and can be swapped out for true instance classes without modifying any external code calling the class. Monostate also don’t have quite as many multi-threading issues as Singleton classes, since there truly is no way to accidentally get multiple copies of the data with Monostate. A careless Singleton implementation could end up with several instances if called simultaneously from multiple threads. Both patterns require locking on their data members though.

One thing to also keep in mind when implementing a Singleton or Monostate pattern is that you want to make sure that you are using the pattern because the data requires that it not be copied in two places. If you are implementing Singleton because you want to save the cost of object instantiation, think again. If you are implementing either of them because it makes the logic more simple, then think again. The only reason to use these patterns is because your data dictates that it cannot be out of sync.

So, there you have it, hopefully another useful addition to your pattern tool belt. And like always, if you liked it, please kick it!

Be Sociable, Share!

5 comments

  1. Here is a solution that should not allow for more that one instance of you singleton class. It is thread safe as fast as I can tell.

    public class Singleton
    {
    private static Singleton instance = new Singleton();

    private Singleton()
    {
    }

    public static Singleton Instance
    {
    get
    {
    return instance;
    }
    }

    public String DataItem { get; set; }
    }

    Agreed, if you want to be really picky, you would also want to Reader Writer Lock the “Data Item”. With the advent of multi-core machines, data corruption happens much more often.
    I agree my biggest issue with the mono-state is that you really can’t tell it has singular state under the hood. If I was going to use one, I would write a custom attribute that generates a complier warning on the DataItem Property. That way the user of your object would have to suppress the warning in every usage. However, I still don’t know if that is the most elegant solution.

  2. @Yezdaan Yep, it looks like that will guarantee only one instance, but since you are using a type initializer to initialize this type you could end up instantiating the instance earlier than you expect. It isn’t a big deal (unless your application is *very* memory sensitive), but if you add an empty static constructor then your class won’t be marked with "beforefieldinit" and therefore you are guaranteed that your Singleton will only be instantiated right before any static member of this class is accessed. (And no, I didn’t know this off the top of my head, had to do a little research) :)

  3. Hey Justin, it was great seeing you this evening at the Speakers Forum for the upcoming Richmond Code Camp 2008.1. I’m looking forward to hearing you speak there (assuming I’m not speaking during your presentation slots).

    On this topic, you should check out how C++ allows you to set the new handler and mode and then write overloaded new and delete operators on any unmanaged type. By switching what "new" means for a class, you can create singletons, monostate objects and nearly any other pattern you care to think of. If you think about it rationally, the instancing mode for a class is ultimately dependent on the decisions made by the underlying allocator. C++ just lets you take control of the allocator globally or on a class by class basis.

    You and I were speaking tonight about the performance improvements in the latest Firefox BETA. I wouldn’t be surprised if some of the memory allocation techniques you alluded to include the use of overloaded new and delete operators in the Firefox BETA. I’ll have to download the source and check it out when I have the time. With C++, you can set up pools of heap memory dedicated to specific object types, thereby reducing heap fragmentation dramatically. By writing custom, thread-safe heap management routines in C++, you can make your code scream.

    There’s a reason that C++ jobs still outnumber C# jobs worldwide by nearly 2 to 1. ;-)

  4. @Kevin I’ll have to check that out, but my practical experience with C++ is quite small. :) Sounds very interesting though, I’ll certainly have to look into it.

  5. Kevin,
    You are exactly right about the pre loading; I have noticed it before when assessing memory management in my applications. Then again we just bought a set of servers with two quad core processors and ten gigs of ram, just silly. Not that I am an advocating misuse of memory, but it is just so cheap now. The real issue might be your load time. Depending on what is being done in the private constructor, the “jiting” might take a while.
    On a tangent, have you looked at the castle framework? There is a concept of a lifestyle; it basically governs the instance returned from the container when doing dependency injection. Currently, in my blog I am writing a road map of my design to extend this framework. I will probably be writing about the “lifestyle” topic soon.

Leave a comment