Dart – implementing the Singleton pattern with factory constructors

Yan Cui

I help clients go faster for less using serverless technologies.

This article is brought to you by

MongoDB 8.0 is here to change the game. Faster reads and inserts, and brand-new vector search to support modern AI-powered apps.

Learn More

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 3 ways I can help you:

  1. Production-Ready Serverless: Join 20+ AWS Heroes & Community Builders and 1000+ other students in levelling up your serverless game. This is your one-stop shop for quickly levelling up your serverless skills.
  2. I help clients launch product ideas, improve their development processes and upskill their teams. If you’d like to work together, then let’s get in touch.
  3. Join my community on Discord, ask questions, and join the discussion on all things AWS and Serverless.

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 *