Design Patterns in WordPress: The Singleton Pattern

Throughout this series, we're taking a look at the significance of design patterns and the roles that they play in WordPress development.

In the first post in the series, we took a high-level survey and even reviewed the Observer Pattern to see how it's possible to register various functions or objects with certain events that occur within the lifecycle of an application.

In this post, where's going to take a look at the Singleton Pattern.

Specifically, we're going to take a look at the definition of the pattern and how it works, we're going to review a diagram of what the architecture of the pattern looks like, we'll cover some sample code for the pattern, and then we'll discuss the advantages of the pattern as it relates to WordPress development.


The Singleton Pattern

Wikipedia defines the Singleton Pattern as follows:

In software engineering, the singleton pattern is a design pattern that restricts the instantiation of a class to one object.

Perhaps a simpler way of explaining the pattern is this: The Singleton Pattern ensures that a class can only have one instance and it provides a single way to retrieve an instance of itself.

So Why Does This Matter in WordPress?

As far as theme development is concerned, I personally don't see much of a use for it unless you're bundling some type of helper class or library with your theme; however, if you're building plugins, then this can be exceptionally useful.

As of now, there are really only a handful of ways to instantiate plugins (excluding widgets - that's another topic) within WordPress:

  • You can instantiate the plugin at the bottom of your plugin file, but this can lead to an orphaned object
  • You can stick the plugin in the PHP $GLOBALS collection, but this can be dangerous as you could trash something that already exists or it's making the collection needlessly larger
  • If you instantiate it with, say, each page load then the data isn't being persisted unless you serialize and hammer the database each time the plugin is instantiated

None of the above are particularly good strategies (although you could make a case that they all work).

However, we care more than just getting something to work, right? We want it to work and we want an elegant solution to the problem. This is where design patterns - more specifically, the Singleton Pattern - come into play.


What It Looks Like

First, let's take a look at a diagram of the Singleton Pattern. Check out the diagram below, then we'll talk about the specifics after the image:

The Singleton Pattern

So here are the key features of the Singleton Pattern:

  • There is a private, static instance variable defined in the attributes that is used to maintain a reference to the class
  • The constructor has been marked as private
  • There is a public static function named get_instance which is used to return an instance of the class

Nothing too complicated, but I think reviewing the code for the Singleton Pattern goes a long way in making it a bit clearer, so let's do that now:

Obviously, there's been a lot of code left out of the above class, but the pattern's principles remain.

Notice that we have a private, static instance variable that's used to refer to this class. Specifically, it's set in the get_instance function whereas the constructor has been marked as private.

Typically, when instantiating classes, the constructor is the function that is called whenever we initialize classes; however, in this case, the constructor is marked as private.

So what gives?

Notice that we have a public get_instance function just above the constructor. This function literally checks to see if the static instance variable is null and, if so, creates a new instance of the class (which it can do since it's within the context of the class); otherwise, it returns the current instance.

This is how no more than a single instance of a class is created.

Finally, note that we instantiate the class not with the standard new keyword, but by calling get_instance. Not only that, but we also get future references to the class by using the same method.

So, for example, let's say that you're working in another template and you need to call a function - say bar() - that exists in your plugin. In that case, you'd do something like this:

Pretty neat, isn't it?


The Advantages of the Singleton Pattern

Despite the fact that we've covered the Singleton Pattern from an architectural and a practical standpoint, we haven't actually talked about the advantages of the pattern.

Generally speaking:

  • The Singleton Pattern prevents other objects or clients from duplicating instances of the class. This makes sure that there's only one copy of the data maintained at any given time. All access to the object is done so by the single instance.
  • We have a wide array of flexibility when it comes to implementation because we can actually impact the instantiation process (though this is a bit out of scope for this particular post).

Perhaps the largest drawback from using the pattern is lack of clarity that the plugin actually uses the pattern. If someone tries to instantiate the class, instantiation will fail because there's no public constructor.

As such, documentation is key.


Conclusion

Whether you've seen them before or this is your first foray into design patterns, the Singleton Pattern is arguably the simplest design pattern there is. It's easy to implement, and it provides a significant source of functionality when implemented correctly especially as it relates to web applications.

In the next post, we'll take a look at another pattern - the Simple Factory Pattern - which is useful when you have a number of classes each of which has a unique purpose and that will be needed based on certain input criteria.

Tags:

Comments

Related Articles