Singleton Design Pattern and Dependency Injection, Part 1

The Singleton Design Pattern is something that I’ve talked about before in previous articles.

As Wikipedia so eloquently defines it:

In software engineering, the singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system.

If you’ve done any work with object-oriented programming and familiar design patterns, then it’s likely that you’ve come across it (if you haven’t used it).

Depending on who you ask, the singleton design pattern may be treated as an anti-pattern, like some weird use of a “poor man’s namespace,” or one of the many other negative views of it.

Though these perspectives aren’t necessarily wrong, there are times where it’s okay to use it.

The Singleton Design Pattern

To me, the singleton design pattern isn’t problematic in and of itself. If that were the case, I don’t believe that it would have ever become one of the patterns as documented by the Gang of Four.

It’s the way that it’s used (or misused, to be more precise) that becomes a problem. For example, if your goal is to use object-oriented programming but you use the singleton design pattern more often than not, then you’re not so much leveraging the advantages of object-oriented programming.

An Example of The Pattern

Ultimately, I’m going to walk through an example of how the pattern can be used as [an admittedly weak] dependency injection container (which I’ll cover in more detail later in this article and the second and third part of this series).

This has nothing to do with the singleton design pattern. But I thought the pattern was nice.
This has nothing to do with the singleton design pattern. But I thought the pattern was nice :).

But before I do that, I think it’s worth taking a look at what the pattern looks like and talk about some of the key points so that everyone reading this is on the same page.

And before reviewing the code, note that there are minor variations of the pattern. What I’ve included below is my preferred way of setting it up, though others have their preferences, as well.

I’d like the think the comments are clear but I know that some who read this are coming from other backgrounds or are new to object-oriented programming, so I want to highlight a few things in the code that are worth noting:

  1. Because this is an object-oriented pattern, all of the functionality exists in a class. If you’re familiar with namespaces, this can also be placed in a namespace (and often should be if you’re managing your code regarding packages or modularity).
  2. The only property the class maintains is a reference to an instance of the class. Normally, these are not static but because of the nature of the pattern, this property is. Note that static indicates the data isn’t related to multiple instances of an object. Since the singleton pattern is, by definition, limited to a single instance, the reference to the object should be marked as such.
  3.  The constructor is marked as private because the pattern dictates there should only be a single instance of the object (which is counterintuitive, I know). It’s marked as private so no external classes can instantiate it. Instead, only internal methods can do so.
  4. The only public function that’s available is that of get_instance which looks to see if the property [discussed above] is referencing a value (which should be an instance of the class). If it’s not, then, it sets it. After that, it will return a reference to the instance.

Depending on your level of experience, you may hear static variables are terrible, that the singleton pattern should never be used, that the design pattern is an anti-pattern and all of that.

All of that to say, there is no consensus. Whatever the case, the pattern is used, and it’s worth understanding so you can work with it even if you hate it or plan never to use it in your work.

Dependency Injection

If you’re working with WordPress, the odds that you’ve seen anything around dependency injection containers, and the like are pretty small. Not unheard of, but small.

And though the basics of the pattern are above, it doesn’t really relate to dependency injection nor does it relate to and how I think it can be used as a dependency injection container (at least in an intermediate stage of development).

To be clear, I recognize that this is not the final form a container should take nor does it feature any type of functionality that a container normally maintains. But remember the goal of this is to show the pattern and to show one way that it can be used when you have limited time or resources when working on a solution.

That is, you need interstitial functionality and that’s what I’m hoping to achieve with the next post.

2 Replies to “Singleton Design Pattern and Dependency Injection, Part 1”

  1. Hey Tom,

    Ah, the venerable Singleton pattern… I personally don’t like it at all. But before going on a rant here about the what’s and why’s (which can be read all over the interwebs) or the reasons why the pattern is nevertheless used so frequently (which can be read all over the interwebs), I prefer taking your specific example and offering an alternative approach. Most of the times, the Singleton addresses a specific need, and bashing it without offering an alternative solution is not very productive.

    More specifically, I want to concentrate on the fact that the Singleton pattern violates the Single Responsibility Principle in SOLID, and there’s an easy fix to avoid that.

    The violation from the Single Responsibility Pattern comes from the fact that, in your example above, the class is responsible for acting as a container AND responsible for limiting the instances of itself. As soon as you let an object manage its own instantiation, plus let it do any other task, you violate this principle.

    You use the Singleton Pattern here because you want to limit the number instances being used. You could also say you want to share a common instance, or you want to always pass the same instance around.

    There’s a different pattern that concerns itself with instantiation, and does nothing else: the Factory. So, as an alternative, how about having your Container be a normal object, with all the benefits that provides, but provide a Factory to retrieve an instance of it. That Factory can then always pass the same, shared instance of the container. The Factory is responsible for instantiation, the Container is responsible for “Container-y Things”.

    Instead of having code like this:

    $container = Container::get_instance();
    $container->do_something();

    …you’ll have code like this:

    $container = ContainerFactory::get();
    $container->do_something();

    Looks pretty similar, is conceptually much cleaner though. It also opens up your code to be able to pass around different containers, as your code is now tightly coupled only to ContainerFactory, not the Container itself.

    Another immediate benefit: You freed up the constructor, so you can for example use dependency injection to inject a logger into your container to log the happenings inside.

    Ok, I hope this was not just another “Singletons are bad!” rant, and that some people might find this alternative alluring.

    1. Most of the times, the Singleton addresses a specific need, and bashing it without offering an alternative solution is not very productive.

      Agreed! I think it’s a pattern that’s overused, abused, and that generally prevents us from creating better architectures. But I also admit that time can constrain us and that it’s always good to have an alternative solution other than just saying “bah, it sucks!”

      As soon as you let an object manage its own instantiation, plus let it do any other task, you violate this principle.

      +1

      I try to communicate this in the post (and definitely so in the later two parts) but that this is not an ideal solution. It’s something that is better than many alternatives gives time constraints, but it’s not something that I recommend as something to follow when the requirements allow for more time.

      Even still, explaining how this violates the principle is important so I’m glad you took the time to do that — thanks for that!

      That Factory can then always pass the same, shared instance of the container.

      I’ve generally used factory patterns and the single when I’m working with the simple factory pattern, but not with the abstract factory pattern. I’ve not really considered alternatives from that — I’d be curious on your thoughts, though.

      Sometimes I think the word “factory” gets overloaded when a simple version of it would suffice. But I digress.

      Ok, I hope this was not just another “Singletons are bad!” rant, and that some people might find this alternative alluring.

      Not at all! Always appreciate your insight on this kind of stuff :).

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.