A valid usage of Singleton Pattern (with Null object Pattern)
Tags: programming, oop, tips
Published: 2018-07-07 14:22:23

---
title: A valid usage of Singleton Pattern (with Null object Pattern)
published: true
tags: programming, oop, tips
cover_image: https://thepracticaldev.s3.amazonaws.com/i/j164f9mi3uy997x2l5bq.jpg
canonical_url: https://www.slightedgecoder.com/2018/03/25/a-valid-usage-of-singleton-pattern-with-null-object-pattern/
---

<sub><sup>Photo by <a href="https://unsplash.com/photos/oxVjCyH_ldQ?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Chetan Menaria</a> on <a href="https://unsplash.com/search/photos/loneliness?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></sup></sub>
Singleton has a bad rep for being an anti-pattern.
You might have been burned bad with it.

I learned from [Michael Outlaw](https://www.codingblocks.net/author/outlaw/) from [Coding Blocks podcast episode 16](https://www.codingblocks.net/podcast/episode-16-design-patterns-part-2-oh-behave/) that [Singleton pattern](https://en.wikipedia.org/wiki/Singleton_pattern) can come in handy in conjunction with [Null object pattern](https://en.wikipedia.org/wiki/Null_object_pattern).

Let’s dive in.

## 🤔 Why implement a Null object as a singleton?

42 minutes into the Coding Blocks Episode 16, Michael Outlaw explains two reasons.

> 1. “If you have two versions of null objects, they should be identical, why waste memory to have same nothingness repeated”.
> 2. For equality checks – Each null object can be compared by reference.

Depending on a situation you might not even need to do a equality check as a null object usually does nothing (as you can see in the example below.)

**TL;DR** – You can stop reading here.

## ✍️ An Example Implementation

Here is an example of how you can use a Singleton pattern with a Null object pattern.
Suppose that there is a simple factory (PaymentStrategyFactory) that returns a strategy object instance for processing a payment given a provider name.

{% gist https://gist.github.com/dance2die/aad6b604536afeb10f71771cc42e3853 %}

PayPal & ApplePay strategies return “Successful” or “Failed” process status at random.

{% gist https://gist.github.com/dance2die/8d0f0f6f47f01a516f1657a7e500dd7b %}
{% gist https://gist.github.com/dance2die/496655cf6ec63b4dd74da93c4e6e180b %}


If a provider name is not supported, the `PaymentStrategyFactory` simply returns an object of type `NullPaymentStrategy`, which implements `IPaymentStrategy`.

Singleton instance is achieved with a private constructor and a static `Instance` property.

{% gist https://gist.github.com/dance2die/8ae2a62261d3784c713a44b6eed24b56 %}
{% gist https://gist.github.com/dance2die/dee349d007060c5701652fadfcbc4009 %}

Let’s put them together and process payments.
{% gist https://gist.github.com/dance2die/5897ad07ed0411dfec9cc2c22b0d3fbc %}

Results of `ProcessPayments()`.
{% gist https://gist.github.com/dance2die/1c76839c8c7f358018c2df0fa27ee2a0 %}

You can see that `Braintree` & `BadPaymentProvider` returns `NoOp` because there `PaymentStrategyFactory` returns a singleton instance `NullPaymentStrategy.Instance` as there is no matching payment strategy.

### 👋 Conclusion
Googling [Singleton Anti Pattern](https://www.google.com/search?q=singleton+anti+pattern) results in many reasons why Singleton pattern is bad.
But when used judiciously, it can improve your code quality/memory/speed.

Source code is available on [GitHub](https://github.com/dance2die/blog.NullObjectSingletonPatterns).