The case against Singletons in WordPress

Eric Mann wrote a thoughtful and detailed argument for using the Singleton pattern in WordPress development. Given the particular nature of the WordPress development environment, his reasoning is understandable and clearly comes from experience. The criticisms I’ve seen so far in his post comments, and in Hacker News, don’t make good counter-arguments. They are coming from people who either aren’t familiar with the constraints of developing in WordPress, or who are just looking for any opportunity to bash PHP developers.

…So here comes the “but:” I think he’s made a very valuable contribution to the discussion of code design in WordPress, but I don’t agree with his conclusions. I have a few reasons:

1. WordPress is positively bursting at the seams with global state. This is a huge design sin, but a forgivable one, given that WordPress came of age before PHP had a decent object model. However, Eric defends it, arguing in response to a comment that:

PHP applications like WordPress are written in a single-threaded, request-response pattern. Having a global scope is useful, and having instantiated singletons available in that scope is also useful.

I don’t find this persuasive. The vast majority of web applications, written in a variety of languages, are single threaded and follow a request-response pattern (given how HTTP works). That doesn’t make dumping stuff in global scope ok somehow. I won’t go on at length about the evils of globals – it’s been discussed thoroughly by many, and avoiding them is considered axiomatic to good design. A good place to start is Misko Hevery’s Google talk on Global State and Singletons. His examples are in Java, but PHP 5’s object model is very similar, and the examples he provides aren’t all that different from the challenges of working in WordPress.

2. The Singleton pattern doesn’t isolate you from global state. As Misko Hevery explains in his talk, that global state is actually transitive to everything within the Singleton object. Eric outlines some steps to get around that for the sake of unit testing. He asserts that the unit testing difficulties are the only significant problem with the Singleton pattern. But the testing problems are symptomatic of it simply being a bad design pattern. It’s the “S” in PHP expert Anthony Ferrara‘s collection of STUPID anti-patterns (that’s a slideshow, so use your arrow keys to see the bullet points). In Eric’s follow-up post, he’s Asking WordPress developers to create their own Singleton classes by deriving a class from an abstract class, that is in turn derived from an interface. This is a heavy lift for a solution that at the end of the day leaves you right where you started with global state.

3. Eric rejects dependency injection as an alternative by giving an overly simplistic presentation of what it has to offer (I gave a talk on dependency injection at WordCamp Nashville last year). A dependency injection solution can meet all but one of his goals, and lets you do some real, unshackled OO programming. What’s needed is an injection container. A container knows what objects are needed to build other objects, and hands you the object you want when you ask for it. So your calling code never invokes “new” for an object it wants – it simply asks the container to deliver it. The beauty is that objects only need to know how to talk to their immediate collaborators, and the container takes care of the composition (e.g. A House just knows it needs a Door, it doesn’t need to worry about the DoorKnob or the Deadbolt). Now here’s the thing – you can program your container to know whether it should give you a fresh new instance of the object requested, or whether to keep a single instance of that object in memory, and deliver that object when asked for it (like Eric’s WP_Session object).

Here’s a simple example from my Shashin plugin, which displays photos from Picasa, Twitpic, etc:

class ShashinContainer {
//...

    public function getClonablePhoto() {
        if (!isset($this->clonablePhoto)) {
            $this->getDatabaseFacade();
            $this->clonablePhoto = new ShashinPhoto($this->dbFacade);
        }

        return $this->clonablePhoto;
    }

// ...
}

There are a couple things going on here:

  • The container takes care of the composition: it knows that a clonablePhoto needs a dbFacade. The caller doesn’t need to know or care. This approach is very liberating in terms of keeping your system open to future design changes (i.e. composition changes are localized to the container, minimizing the risk of change on the rest of the system).
  • After creating the clonablePhoto, the container object keeps it around as a property. If a caller asks for a clonablePhoto again, it simply sends the same clonablePhoto (in this case it’s an immutable object, so there’s no reason to bother instantiating more than one).

I mentioned this gives Eric all but one thing he wants, and that is the one overriding thing he wants, which drove him to the Singleton pattern: an absolute guarantee that no one can ever, ever create more than one WP_Session object.

How you feel about that depends on what you think is reasonable to expect from people who contribute to WordPress core development. The Singleton pattern is a least common denominator kind of solution – that our choices for design patterns are bounded by what the least capable WordPress code contributor can handle. I prefer to set my sights higher. There are already a whole host of expectations in terms of the security of code that’s contributed, how it conforms to WordPress coding conventions, and its overall quality. I don’t think it’s unreasonable to expect a basic understanding of OO design principles.

Each new version of WordPress adds features, and therefore complexity, to the codebase. My concern is that, with all its global state, the WordPress development process will become ever more arcane and complex: the necessary sequence of operations and the number of simultaneous dependences will likely become overwhelming at some point. Right now that’s mitigated by the fact that the core team is incredibly talented, and there’s a huge pool of people available and eager to spot bugs, contribute fixes, etc. Evolving the codebase to a place where it eventually doesn’t rely on global state will allow the codebase to become more modular and flexible, streamline the development process, and ultimately allow WordPress to keep pace with the ever growing list of things people want it to do.

The transition steps don’t have to be painful, and can be undertaken incrementally:

  • WordPress’ custom hooks and functions will need to stay available as they exist now, for backwards compatibility, but the code in them should be migrated over time, until eventually all those functions are just wrappers for calls to object methods.
  • Put all the WordPress classes that already exist behind injection containers. That hides all the global state, and therefore allows a flexible, OO composition approach to grow and take hold. Then in the long term it allows that global state to be eliminated through incremental redesign. In the end you’d have a main WordPress class that would be instantiated to do all the high-level calls needed to kick things off. Once global state is eliminated, the fun can really begin. For example, with a little extra configuration, you could run multiple simultaneous instances of WordPress from a single codebase.
  • Once the injection containers are in place, code that’s contributed to core should never contain the keywords “global” or “new” (except inside injection containers). I think that’s a pretty simple rule to communicate.

At its heart, object oriented design is really about encapsulation and messaging (the exact opposite of design that relies on global state). It wasn’t created to make someone in an ivory tower happy – it exists to solve the inevitable problems that arise in complex software, and is the child of decades of hard-won experience from many talented people. It’s when you make the leap to understanding this composition approach to design that the benefits really kick in. As explained in the book Growing Object Oriented Software, Guided by Tests:

An object oriented system is a web of collaborating objects… The behavior of the system is an emergent property of the composition of the objects – the choice of objects and how they are connected… Thinking of a system in terms of its dynamic communication structure is a significant mental shift from the static classification that most of us learn when being introduced to objects.

The WordPress codebase has grown to a point of sufficient size and complexity that I believe it will substantially benefit by starting an evolution towards this design paradigm.

12 Comments

  1. Reply
    Mike Schinkel January 22, 2013

    Hi @Mike,

    Nice post, and I agree much of it. On the other I disagree with your conclusion and I also think Singletons are warranted in very selected use-cases within WordPress.

    I can’t speak to the range of use-cases Eric believes are appropriate for Singleton in WordPress but I’ve recently advocated for Singletons for one specific use-case: classes used in a WordPress plugin or theme to encapsulate the class methods used by hooks. For that use-case the concerns about unit testing and dependency injection become moot. You can’t unit test hooks that require a page load (you need to test the HTTP request instead) and the dependency injection concern is not relevant because you simply build a non-Singleton class to manage those aspects.

    Of course your recommendation to migrate hooks to object method calls would address the first issue but I think such a transition would be misguided. If WordPress were to do that it would become much less flexible and have to contend with the fragile base class problem. I use a lot of classes with object methods instead of hooks because it makes it easier to ensure my code is robust, but it also by-nature limits the flexibility of my object so I think it would be a bad idea to see WordPress use an OO approach exclusively.

    If WordPress were to move to a completely OO approach it would also alienate a huge swath of WordPress site builders, such as the one who commented on one of my posts. An important reason WordPress has been successful is because it empowers people who don’t grasp the finer points of development to be able to produce very real solutions for themselves and their clients. Going completely OO would kill that much like Microsoft killed the leading-at-the-time development tool Visual Basic by evolving it to VB.NET where the latter required a much greater skill set to be productive.

    Or for the TL;DR crowd, don’t kill the goose that lays the golden eggs just for purity sake. A balanced approach is best. 🙂

    • Reply
      Mike January 23, 2013

      Thanks for the thoughtful reply Mike. A few things:

      * Your concern about fragile base classes stems from not following the “O” in the SOLID principles: the Open-Closed Principle. Check out Michael Feathers’ post The Active Set of Classes– it provides a good sense of the architecture of a real project (rspec) that follows this principle.

      * My impression, which could be wrong, is that you’re thinking mainly about inheritance in your approach to OO (since you’re using words like fragile and inflexible). What I’m advocating is a composition approach, which is all about providing flexibility. Here’s a pretty good compare and contrast.

      * This is genuine question, not a haughty rhetorical one: is your focus (and Eric’s) on locking things down with Singletons solving a problem that needs to be solved? Do we have examples of developers wreaking havoc by unknowingly instantiating multiple instances of things they shouldn’t? If so, is the Singleton pattern the only solution? An injection container approach gives developers a clear path to do things the right way with objects that should only be instantiated once. It doesn’t provide the absolute certainty of the Singleton pattern (since they could bypass the container), but you also aren’t locking yourself into having to live with all the shortcomings of the Singleton pattern.

      * The focus of my post is WordPress core development. Site builders are dealing with plugins and themes, which is a different matter. I’m all for keeping the barriers to entry low in those areas, in terms of expected levels of technical expertise. Whether plugin developers are calling hooks, static methods, or object methods to get the behavior they want from WordPress doesn’t really matter that much – they’re still just one or two line calls. They don’t need to worry about the internals.

      * However, I think the current architecture of WordPress is actually pretty daunting for budding plugin and theme developers. Personally, it took me a long time to feel like I really knew what I was doing in my plugins. It’s a given that there will always be domain knowledge to learn, regardless of architecture. But becoming a halfway decent plugin developer means learning at least a certain amount of WordPress’ architecture. I had to un-learn some WordPress habits before I got good at OO – my WordPress experience was an obstacle to that learning. I think it would be better to have people learn good OO practices at the same time they’re learning WordPress, instead of acquiring a set of skills that only apply to the particular, peculiar architecture of WordPress as it exists now.

      • Reply
        Taras Mankovski January 23, 2013

        Hi Mike Toppa,

        > Do we have examples of developers wreaking havoc by unknowingly instantiating multiple instances of things they shouldn’t?

        I don’t think that this is the problem that the use of Singleton pattern is intended to solve. At least not as proposed by Mike Schinkel on http://hardcorewp.com. Using singleton pattern as a wrapper for WordPress plugins makes it possible for site builders to unhook plugin’s actions or filters without requiring the site builder to know about the innards of the plugin.

        There is a post on HardcoreWP that describes how this would be done. You can see it here: Enabling Action and Filter Hook Removal from Class-based WordPress Plugins

        > But becoming a halfway decent plugin developer means learning at least a certain amount of WordPress’ architecture. I had to un-learn some WordPress habits before I got good at OO – my WordPress experience was an obstacle to that learning. I think it would be better to have people learn good OO practices at the same time they’re learning WordPress, instead of acquiring a set of skills that only apply to the particular, peculiar architecture of WordPress as it exists now.

        It might be helpful to stress that there is a particular architectural style that is unique to WordPress and this style isn’t necessarily a good fit outside of WordPress environment. With that said, it should be encouraged to extend WordPress following WordPress architectural style. It might be helpful to start discussing what is “WordPress architectural style” or is “WordPress-ish”.

        • Reply
          Eric Mann January 23, 2013

          Do we have examples of developers wreaking havoc by unknowingly instantiating multiple instances of things they shouldn’t?

          Whenever I write a post talking ambiguously about weak developers doing bad things, I’m usually talking about myself and the way I wrote code when I first started. When I was first using WordPress, and didn’t understand exactly what `new` did, I used it all the time to try to unhook filters that were added by class-wrapped plugins.

          Really, if a plugin is built as a class, the only way to unhook any of its actions/filters is to reference the original class. This requires either a global variable, a self-referencing static (like that in the Singleton pattern), or an object factory that keeps track of instances. WordPress uses the first entirely too much. Few people are using the last (and, honestly, it scares the crap out of many newer developers). So I opt for the second as an easy win that a) gives me my instance reference and b) protects from anyone making the same mistakes I made for a couple of years.

          • Mike January 23, 2013

            Something I didn’t say clearly enough before is that I respect the fact that you have real problems to solve in WordPress as it exists now, and you’ve come up with a solution that works within the constraints of the environment. But my outpouring was triggered by the fact that I see a lot of discussion online among really smart WordPress devs, putting energy into painful solutions to painful architectural problems. I don’t see as much discussion about how that architecture could be improved, and I think it takes focusing on a specific aspect of the problem in order to spark conversation in that direction – like we’re doing now 😉

            [Update 1/24: edited for brevity. See the last paragraph of my response to Mike S, which is addressing the same point.]

        • Reply
          Mike January 23, 2013

          Thanks for this Taras. In my post I was responding to Eric Mann’s post about Singletons, where he expressed his concern about developers calling “new” on his core WP_Session object. Mike S is also using the Singleton pattern to address a separate issue for plugins that use classes, as you described. But both their concerns come from the same root cause – the routine use of globals.

          In regard to WordPress architecture, see my comment I just posted below in response to Eric.

          • Mike Schinkel January 24, 2013

            ” But both their concerns come from the same root cause – the routine use of globals.”

            Maybe I’m missing something in my own points but I don’t think my use of Singleton has anything to do with globals, unless you are saying that WordPress’ hook system uses globals? If that’s it then yes, but I’m not trying to re-architect WordPress, I have enough trouble getting the core team to even consider adding in a hook here and there. So I’m trying to accommodate WordPress, not remake it.

            If that’s not what you mean, please elaborate (and get a email notifier for comments so I don’t have to keep checking back. 🙂

          • Mike January 24, 2013

            I was referring to core WordPress routinely using globals – sorry that was unclear. Like I said in my response yesterday to Eric, I am trying to spark a discussion about WordPress itself. The focus in the comments has been shifting to plugins, but in my post I was responding to Eric’s post, which was about WP core development.

            When you leave a comment you should see a checkbox to receive follow-up notifications by email. Is it not showing up for you, or just not working?

      • Reply
        Mike Schinkel January 23, 2013

        Your concern about fragile base classes stems from not following the “O” in the SOLID principles: the Open-Closed Principle. Check out Michael Feathers’ post The Active Set of Classes- it provides a good sense of the architecture of a real project (rspec) that follows this principle.

        His post was interesting, yes and I can relate it to a few projects I've been working on that are hosted at GitHub right now. OTOH I think of myself as a "Code Leaner" (vs. "Visual", "Auditory", and "Kinesthetic" Learners) so I struggle with abstract concepts like SOLID until I see them in code. Yes, this is a cognitive limitation on my part.

        My impression, which could be wrong, is that you’re thinking mainly about inheritance in your approach to OO (since you’re using words like fragile and inflexible). What I’m advocating is a composition approach, which is all about providing flexibility. Here’s a pretty good compare and contrast.

        Your impression was correct, when I said "fragile" I was referring to inheritence. In my OOP experience — which began around 1990 — I've definitely seen huge benefit in composition, but I've also seen benefit in inheritance. From what I've seen use-cases typically call for one or the other but are not typically applicable to both.

        Let's take a look at WordPress' WP_List_Table class and all its child classes. To me that's definitely an inheritance use-case and not one that calls for composition. That said, I'll be the first to admit that I don't know the things I don't yet know. Combine that with me being a code learner and I'll just have to say I need to see actual coded examples of what you are proposing before I can truly have a solid opinion (pun intended. 🙂

        Back to Petter Måhlén's opinion; mine contradicts, but we don't know whose opinion is more correct at this point. Interestingly his example uses C# (I think) which has language features PHP does not have; I'm not sure how one would implement his BodyType example in PHP; how would you? I think the best approach would be a combination of inheritance and composition. If the code is modeled too abstractly then it is hard to grasp as his example is IMO. Go with his recommended approach and maybe you've gained in one direction but definitely lost ground in another very important one; understandability.

        Is your focus (and Eric’s) on locking things down with Singletons solving a problem that needs to be solved? Do we have examples of developers wreaking havoc by unknowingly instantiating multiple instances of things they shouldn’t?

        Actually locking things down is important to me. As a matter of fact Eric criticized my "Using Singleton Classes for WordPress Plugins" post because I didn't lock it down (though I later did in a planned follow-up in part to make my approach more palatable to those who care.) No, I have different reasons for advocating for the use of a Singleton.

        My only reason for using a Singleton class is as a pseudo-namespaced code wrapper for functions/methods used for actions and filters. And an alternate approach would be to use a class that has only static methods, and that's actually what a lot of my earlier WordPress plugin code used. But after a lot of experience I found that approach to be less than ideal.

        The syntax for static is verbose and ugly and it's a pain if you use a debugger because static variables don't automatically appears in the variable windows among other issues. So I moved to wiring hooks to instances and using instance methods, and that implied a Singleton which I wanted to named explicitly so it would be easier to discuss.

        Unfortunately I've since learned how passionately negative some programmers view the idea of a "Singleton" so much that they can't recognize narrow yet appropriate use-cases (I'm talking about the Hacker News response, mostly). So I now feel I have to defend the concept of Singleton as it relates to use for a WordPress plugin rather than write new and more useful posts. 🙂

        If so, is the Singleton pattern the only solution? An injection container approach gives developers a clear path to do things the right way with objects that should only be instantiated once. It doesn’t provide the absolute certainty of the Singleton pattern (since they could bypass the container), but you also aren’t locking yourself into having to live with all the shortcomings of the Singleton pattern.

        To me that's added complexity where there's no value to the complexity. Remember, we are talking a very narrow use-case and we are talking about use in WordPress as a container for plugin hook methods. We are not talking about the architecture for the next great PHP-based MVC framework or a Node.js competitor, we're talking about use with a platform that has 30 million+ self-hosted websites built almost exclusively by people who have never taken a single computer science course in their lives. So rather than overwhelm people and trigger an involuntary mental block that occurs for many people when they read the words "object oriented" I think it's a good idea to make things as simple as possible, but of course no simpler.

        The focus of my post is WordPress core development. Site builders are dealing with plugins and themes, which is a different matter. I’m all for keeping the barriers to entry low in those areas, in terms of expected levels of technical expertise. Whether plugin developers are calling hooks, static methods, or object methods to get the behavior they want from WordPress doesn’t really matter that much – they’re still just one or two line calls. They don’t need to worry about the internals.

        Good point and I'll join with you on that, with a caveat. Moving in a better architecture for WordPress is a really good idea, as long as the API exposured to site builders, theme designers and most plugin developers continues to be simple. For example register_post_type( $name, $args ) is great but it would be awful if we had to move to WP::factory('post_type', $name)->configure($args); or something crazy like that.

        However, I think the current architecture of WordPress is actually pretty daunting for budding plugin and theme developers. Personally, it took me a long time to feel like I really knew what I was doing in my plugins.

        True, but we don't make to make it worse, and ditto.

        It’s a given that there will always be domain knowledge to learn, regardless of architecture. But becoming a halfway decent plugin developer means learning at least a certain amount of WordPress’ architecture.

        True, but let's not use that as rationalization for making things unnecessarily more complex for people who are just trying to get things accomplished.

        I had to un-learn some WordPress habits before I got good at OO – my WordPress experience was an obstacle to that learning. I think it would be better to have people learn good OO practices at the same time they’re learning WordPress, instead of acquiring a set of skills that only apply to the particular, peculiar architecture of WordPress as it exists now.

        I think that's overly idealistic. Most WordPress people don't want to became great coders, then just want to get things done. Those of us who care about both OO and WordPress like you and me are very rare; if you care about OO you are probably working in Ruby, Python, Haskell, Node.js, or one of many other platforms, not WordPress. I'm in WordPress because I'm also an entrepreneur in addition to a coder and for that the efficiency of the WordPress platform speaks to me.

        So IMO having to learn both OO concepts and the WordPress AP is simply too much for those without a technical background. Visual Basic moved in that direction, it abandoned what made it successful and soon there was little difference between VB.NET and C#, so VB effectively died. At one time VB the market leader and in a similar position to WordPress. Let's not kill the goose that laid the golden egg. At least that's my take on it.

        • Reply
          Mike Schinkel January 23, 2013

          Ugh, your comment system stripped my <blockquote>s.

        • Reply
          Mike January 24, 2013

          You’ve got lots of good points here Mike (and your blockquotes are there, my CSS just wasn’t showing them – I fixed it). My responses:

          * We’re all code learners. I learn new stuff all the time – that’s what makes it fun

          * Inheritance definitely has value. I typically use inheritance and composition in projects. When starting a project it can be hard to know which is best for certain concepts you’re trying to represent. But with good unit testing you can refactor as you go.

          * You lost me with “Back to Petter Måhlén’s opinion…” – you didn’t mention his name before that – is there a link you wanted to show me?

          * My post was a response to Eric’s, which was about WP core development. I’m trying to push more of a root cause analysis than see a bunch of painful workarounds applied. I’ve personally seen projects crash and burn once they get to about a dozen years of age, as people just keep piling on patches rather than refactor the architecture (the most well known example is the Window’s transition from XP to Vista – Windows had become so brittle, they had to embark on a massive, multi-year rewrite). I don’t want to see WordPress go the same route. It can be hard to see it coming when you’re deeply involved (the boiling frog problem).

          * Plugins are a different matter, as it’s not realistic to expect a plugin dev to have much say about WP architecture. And I agree it’s not appropriate to expect plugin devs to become programming gurus. But I can’t agree with you and Eric asserting that your Singleton solution is easier for novices to grasp than an injection container (aka factory). You guys are pulling out some real $5 OO words in your implementation – interfaces, abstract classes, static variables, etc. The example in my post is simpler by comparison – it’s a plain ‘ol class that instantiates objects and, if appropriate, keeps them around as properties for later re-use. But I didn’t have your issue in mind in presenting it, concerning actions and filters, so it’s not a solution to that particular problem. That’s not an issue I’ve personally run into yet, so I haven’t given it any deep thought (but I’d be happy to if you’d like further feedback).

  2. Reply
    Eric Mann January 22, 2013

    You’re certainly not the first to suggest refactoring WordPress to use injection containers (some refer to them as a form of object factories as well). I’d like to see this very much myself and have been using a similar pattern in some of my plugin development as well.

    Kudos to a very well-written post!

Leave a Reply