Prefer Monostate To Singleton

Photo by Raymond T. on Unsplash

 

Yesterday we explored the famous The Singleton Pattern. Today we’ll look at the Monostate Pattern which we can often substitute for Singleton. Both Monostate and Singleton solve the same problem: 

The data must always be in sync and in a single location. 

That is the only reason we should apply either of these patterns; not because it makes the logic simpler to have only a single instance. Most of the time, you want to use regular instance objects, where each holds its own internal state different from the others. 

OK. Let’s take a look at the Monostate. How do we create a Monostate class?

  • We declare our backing fields as static.

I like to think of static state as utterly separate from instance state. It’s memory that is not part of the instance at all. When we declare a field or property as static, it means we have only a single copy shared by all objects.

Here is a simple Monostate class definition:

  public class Monostate
  {
     private static string data;

     public string Data
     {
        get { return data; }
        set { data = value; }
     }

     public Monostate()
     { }
  }

It looks deceptively like an instance class. But having the backing field declared as static makes all the difference: There is only one copy of the data.

How does our Monostate behave?

var monostate1 = new Monostate();
var monostate2 = new Monostate();

monostate1.Data = "blah";

Console.WriteLine($"monostate1.Data: {monostate1.Data}");
Console.WriteLine($"monostate2.Data: {monostate2.Data}");

And the output will be

monostate1.Data: blah
monostate2.Data: blah

Yet we only set monostate1.Data. monostate2.Data contains the same value since it points to the same backing data.

It means we can create as many instances as we see fit, and they will all represent the same data. 

One of the criticisms the Monostate pattern attracts is that from the outside it looks like a regular class, but on the inside it behaves differently. My view differs – I believe that this is a strength. It’s an example of object-orientation (OO) at its best – using Abstraction and Encapsulation

We should ask the question: Why do the callers need to know the internal implementation? It’s none of their business. The static backing state is encapsulated and hidden from callers of the class. The class does its job – how it does, is not a concern of the calling code.

OK, here are some further points comparing Monostate and Singleton:

  • Singletons use a static factory method to return the single instance. Monostate objects can be instantiated the usual way – using the new operator.
  • Both Singletons and Monostate are classes and can implement interfaces. When working with the abstracting interfaces, both can be mocked in unit tests easily enough. On the other hand, when we must overcome instantiation of Singleton (static method) or Monostate (new operator) in a chunk of code we are trying to unit test, then this is equally awkward and difficult.
  • Suppose we want to move away from Monostate to a regular, instance class implementation. In that case, we can inject an instance class against the interface without having to modify the calling code.
  • With multiple concurrent threads accessing the Singleton instantiation logic, we could end up with more than a single instance. Monostate does not have this problem; simultaneous threads can safely create Monostate objects. 
  • Both Monostate and Singletons require locking on access to static fields to be threadsafe.

Monostates objects look and feel like instance objects, but their implementation differs to suit their ‘single copy data’ requirements. Why should we need to use a different programming paradigm (i.e. Singleton) because we desire a different implementation? We don’t;

Prefer Monostate to Singleton.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply