Dart – implementing the Singleton pattern with factory constructors

Yan Cui

I help clients go faster for less using serverless technologies.

In Dart there is an interesting language feature called ‘Factory Constructors’, which effectively allows you to override the default behaviour when using the new keyword – instead of always creating a new instance the factory constructor is merely required to return an instance of the class, the difference is important.

Factory constructors allow you to implement a number of techniques and patterns without altering code that consumes your class. For instance,

  • Singleton pattern which we will look at more closely.
  • Object pooling, a useful technique for reducing the amount of allocations (and its associated allocation cost and consequent GC pressure) in performance critical applications.
  • Flyweight pattern which is already discussed in more detail in this Idiomatic Dart article.

These are just 3 use cases that I can think of off the top of my head, please feel free to suggest any more that I have missed.

Problems with common Singleton pattern implementations

In other languages (well, the ones that I’m familiar with anyway!), in order to implement the Singleton pattern you have to ensure that the class’s constructor is not exposed publicly and that access to the singleton instance is done via a static Singleton property. Revered C#/Java developer Jon Skeet has a very good article on the various solutions one might adopt to implement the singleton pattern in C#.

Inflexible

These implementations require code that consumes your class to be aware of its implementation of the singleton pattern and create a vast blast radius throughout your application should you one day decide that the singleton pattern is no longer necessary/applicable.

For instance, if assumptions in your application change drastically (and they often do..) and you need to switch to the flyweight or another pattern instead to cater for changing requirements and/or assumptions.

Unintentional tight coupling

In the case of C# (where static members are not allowed on interfaces and abstract classes are un-constructible) the standard singleton pattern also create tight coupling to a concrete implementation where it’s seldom necessary.

You can, to some degree, work around this issue of tight coupling by introducing an IOC container as middle man between your class and its consumers, most IOC containers provide some mechanism for controlling object lifespans (transient, singleton, pooled, etc.). However, you now have tight coupling to the IOC container instead…

Singleton pattern with Factory constructors

You can implement the singleton pattern using factory constructors like this:

the key thing here is that any consuming code is completely oblivious to the fact that we have just implemented the singleton pattern. If we were to continue our mind later or forced to adopt a different pattern because of changing requirement, there will be trivial or no change on all the consuming code!

Links

Idiomatic Dart – Factory constructors

Jon Skeet – Implementing the Singleton pattern in C#


 

Whenever you’re ready, here are 4 ways I can help you:

  1. If you want a one-stop shop to help you quickly level up your serverless skills, you should check out my Production-Ready Serverless workshop. Over 20 AWS Heroes & Community Builders have passed through this workshop, plus 1000+ students from the likes of AWS, LEGO, Booking, HBO and Siemens.
  2. If you want to learn how to test serverless applications without all the pain and hassle, you should check out my latest course, Testing Serverless Architectures.
  3. If you’re a manager or founder and want to help your team move faster and build better software, then check out my consulting services.
  4. If you just want to hang out, talk serverless, or ask for help, then you should join my FREE Community.

 


2 thoughts on “Dart – implementing the Singleton pattern with factory constructors”

  1. Pingback: Year in Review, 2013 | theburningmonk.com

Leave a Comment

Your email address will not be published. Required fields are marked *