Unnecessary singletons are usually a sign that someone, somewhere designed a way too general system that allowed multiple instances of something, then nobody ever used that feature, then someone else came in and made things a bit saner by adding a singleton constraint, leaving vestigial object-ness and meaningless pointers being passed around everywhere.
In a perfect world with perfect programmers you'd never see one so the instinct that they smell bad is correct.
I fail to see how that makes anything saner.
Of course the right thing to do is to simplify the rest of the program to take advantage of the new assumption but maintenance programmers don't always have the luxury.
Whenever I see a discussion of good software design principles given by a PHP programmer, with PHP examples, I roll my eyes and press Back.
Rightly or wrongly, the thought that goes through my head as a former PHP programmer (from versions 3 - 5.x, ending in ~2010) is something like, "if this person knew anything about well-designed software, they'd know enough to use a well-designed language."
I started my career as a .Net developer and still work a great deal with .Net (primarily C#) code. I use PHP for work because that's what WordPress is built on and, without rewriting the platform that powers a huge chunk of the Internet, I have to use it. When in Rome ...
And I never said singletons were a good software design principal - just that they have a place and a purpose (even if rarely).
But, I have to say, at this time the flaws of WP are so well-known, and the direction and style of the WP devs are such a known quantity, that we as users/devs know what it is and we know exactly how good/bad it's going to be. It's never going to be a well-designed MVC application, and it's probably never going to conform to good OOP design either. It will probably continue to look pretty nice on the backend, but remain really annoying to extend for anyone but the greenest noobs. And it will probably have a ton of features which seem like bloat to people who simply want a blog, and like cruft to people who want a full-fledged CMS.
I think, after so many years, the cost of building a reusable system from scratch is starting to outweigh the benefit of just sticking with WP. One of the major pillars supporting WP's proliferation is the ease with which one can find hosting -- just upload your site, if it doesn't have push-button install already -- and I think the ease with which a Python or Ruby app can be deployed has now matched that. At least for a certain range of users.
It doesn't help the productive PHP programmer get a better understanding of other (possibly better) tools that exist, what problems they solve, and how they can transition to those tools.
It also doesn't help the person making the statement convey their expertise in the subject matter. Instead it looks like an easily dismissed statement about PHP, without any real attempt to prove it.
People are out building and shipping stuff in PHP, .NET, Ruby, Python, C and foobar. And it all works. And users don't care.
If you believe all (heck most) PHP developers care that it's a fractal of bad design, then your view is way too narrow.
> "Part of what makes a good developer is the ability to
> choose the tools that work best."
Oh, and the client only wants to spend $1500.
What software are you going to use?
Many PHP projects are driven by momentum. PHP is a language to get things done in, and I know plenty of incredible PHP programmers who use PHP because it has unparalleled adoption and a library of off-the-shelf OSS software that can't be rivaled by any other programming language.
I'm pretty okay with people shitting on PHP, but shitting on PHP programmers is a completely different story. We use PHP because it gives us a leg up that no other programming language currently can.
Unless you've only been a programmer for a few years, you'll understand the libraries matter more than the language when it comes to writing software. In that regard, and with regards to the OSS software written in PHP, it probably comes close to or beats CPAN.
Ruby developers by nature are a lot more experienced and experienced developers like building great architectures and they tend not to be satisfied with "it works, but it's nowhere near perfect." So instead of a few CMSes we get many, and none get enough critical mass. In the PHP world ironically people are more focused on getting something to work even if it's not perfect because they don't even understand perfect. And they are more apt to use somebody else's im-perfect work. I'd argue that's one of the several reasons WordPress has managed to establish itself as the overwhelming marketshare lead for simple web CMS. And that reason is a necessary although by no means sufficient to explain WordPress' dominance.
 Clipper for DOS
 Visual Basic for Windows
 WordPress for the web
In summary Ruby is great for custom systems needed for SaaS but I highly doubt a single CMS will emerge to unseat PHP-based WordPress from it's throne. And end users don't give a crap what it's developed in or the superiority of it's technical architecture; all they care about is "Does it work for me." And PHP-based WordPress does.
There is no way that PEAR/PECL can be reasonably considered more comprehensive than CPAN or PyPI, I don't even know what your frame of reference would have to be in order for you to think that.
I did, after all, say that I haven't used it in years in a nearby post -- I will gladly admit that I don't know much about the recent developments of a POS ecosystem like PHP. I also told you that none of this is related to my point, but hey, have fun using Blub, I never said you can't be very productive and perhaps even successful with it.
You're just not going to change any reasonable minds about whether or not PHP is well-designed, which is why your argument is basically of the form of "but it's already there!" and not "but it's so good!"
There are plenty of good frameworks out there for PHP that allow you to write clean code. Most of them have only existed since PHP4+. I understand where you are coming from, but in reality when you're writing about software design language is generally a moot point.
I'm curious to know why you decided to post something that you knew should not be posted? If anything, it suggests that any advice or commentary you add is equally worthless because your standards are poor at best.
I'm not sure that your conclusion follows, either. How are my standards poor? And how would that render all advice and commentary worthless? Suppose -- to reduce your claim to absurdity -- that I had posted a proof that P == NP. It would have been totally irrelevant to the thread, but hardly worthless.
I remember writing some code in C a few years ago and I needed a place in a function where cleanup is performed, and in case there were errors caught in multiple places before you get to the cleanup area, I used a goto statement to jump there after printing the error message and turning on a special error flag.
How would you solve that problem without goto?
if (fail) continue;
} while (0);
edit: Other usually-bad alternatives to goto are the pyramid-of-nested-ifs or a set of running "bad" flags/enum that disables each operation downstream of the error until the cleanup is reached.
In the example you gave, the problem is that C lacks something like exceptions and that there is no automatic way for cleanup code to be called. In Java, you can use try...finally, and so you can put your cleanup code in the finally block, and other languages have similar constructs. Unfortunately, in many languages, throwing an exception from a finally block will cause one of the exceptions (often the first) to be "forgotten," which is probably a bad thing; this is also hard to deal with in C, however, since an error that occurs in your cleanup code would need to be signaled somehow, but you can only return one value from the function -- so would you return the error that triggered the cleanup, or the error that resulted from the cleanup?
That's a good question. Fortunately, I don't do anything complicated in the cleanup zone - mostly closing handles and freeing memory.
Closing handles could cause an error! Take a look at the close manpage; there are three error conditions:
* The argument is a bad file descriptor
* The call was interrupted by a signal
* An I/O error occurred while reading or writing
Reading or writing? Yes, as it turns out, closing a handle may involve I/O to perform the last synchronization of the file.
It sounds like you would ignore errors caused by closing the handle, and you would signal whatever error caused the cleanup to be entered.
At the same time, if your methods are complicated enough to possibly require multiple exit points, I'd argue that they should be refactored and broken apart a bit more.
I don't think there's anything wrong with using goto in such a case, though, if it makes the code more understandable.
I wouldn't bother trying, at least in C.
Static fields and static methods on classes should be used sparingly, but if you're going to use them, just use them. Why half-assedly try to hide the fact that you're using them by wrapping them into a singleton?
This is a(nother) thing I like about Go, the design of the language allows for the fact that sometimes a function is just a function and doesn't need an object receiver and maybe it even modifies a package level global, so what? Just make sure you properly handle multithreading situations. In Go code you don't find a lot of patterns where people are trying to sweep what they are doing under a rug in order to not anger people who accept "common wisdom" code design guidelines as absolutes.
If you need to write "dangerous" code (and sometimes it is best to write "dangerous code"), do it in the open, out in the light of day, that way at least it can more easily be reasoned about if someone does hit a snag in it.
I may be misunderstanding your context for the above comment but when I use singleton classes for WordPress plugins I do so to avoid potential namespace collisions with other WordPress plugins.
Unless there's any concurrency to the system, that is. Then they're shared state (as fraught with peril as any shared state) except they're shared state which can be broken/corrupted straight from the initialization.
The reason we prefer non-singletons to singletons are as follows:
• Most languages do not provide very good ways to prevent singleton collision. As software has become more complex and open source's success increases the size of the average dependency tree, this problem is exacerbated.
• Singletons force you to confront all the problems shared state concurrency has to offer, with almost no support. DI objects tend to be isolated from one another and do not run into that level of complexity so soon.
• Singletons tend to make it harder to test code unless your language has a method for overriding or mocking singletons within a dynamic scope (or static type checking between types with liskov-substitutable signatures). The most classic exampe of this is one of the most prevalent singletons: your system clock.
Knowing what we know now about how successful software projects tend to be confronted with expectations of concurrency, parallelism, robustness in the face of reuse, and testability; singletons offer a lot of costs for very transient benefits.
Outside of WordPress plugins, I don't currently know of cases where I'd also advocate for singletons. Yes in most other cases singletons are bad but I'm sure there are some other cases where they do make sense. And you can't prove a negative.
Rust doesn't even have singletons or global variables, since they aren't threadsafe. It has thread-local storage, which dynamic variables are built on top of.
That hack only works if execution can never be suspended though. The issue exists in Python where it's possible to fake dynamic scope using threadlocals, but that can blow up if execution is suspended (between `yield`s in a generator, for instance) as the stack doesn't get unwound (merely frozen) and the threadlocal isn't reverted if it's in the frozen part of the stack. Same deal if it's possible to unshift stack frames, the threadlocal will more than likely end up in the wrong state.
An other thing which bothers me with threadlocals is that it's not really possible to introspect currently-bound locals in order to "save" them alongside lambdas (though that may be an API issue more than an issue with the locals themselves), and in my experience async callbacks tend to need their creation stack context more than their callstack context.
The issue with introspection is fair, and it's a gotcha you have to keep in mind whenever you use dynamic variables. They're necessary to make the task system and condition handler system work under the hood, however, so we can't just remove them.
Oh I've nothing against dynamic variables at all and wouldn't want them (or conditions) to be removed from Rust (in fact I wish solid dynamic variables were available in more languages), don't get me wrong.
"Singletons are possibly the single greatest obstacle to good object-oriented design today. They are often at the root of huge intractable design flaws in large systems, and yet many programmers continue to use them and even insist that they are a good design pattern. Many programmers point to the fact that the singleton pattern is a prominent part of the book Design Patterns, but don't realize that at least one of the authors of that book (Erich Gamma) is on record saying that it shouldn't have been.
We argue that Singletons are almost always bad design and almost never needed. In the few cases where singletons seem necessary, the "environment pattern" offers a reasonable alternative. Therefore, we recommend that programmers always avoid singletons and that programming languages ban them or at least provide an option to ban them."
It saves a lot of extra typing when 99% of the time your dependencies are fixed.
Maybe it's time for a dedicated language feature to solve that problem? For example, each object could carry an implicit reference to an "object pool", from which it can fetch other objects by their class/interface. If an object constructs other objects, the "pool" gets passed along implicitly. Test suites could use "pools" filled with mocks. And unless I'm missing something, the presence of all required dependencies could be statically checked at compile time.
Basically it would be like Lisp's dynamic variables, but based on the construction hierarchy instead of the call hierarchy. What do you think?
This is of course useful for unit testing, but also reduces hidden state dependencies between submodules.
Is that why you open with
> I would argue that Singletons are not just useful, but are necessary for robust software development.
No mention of wordpress there, you use it as an example but your assertion is that singletons are downright necessary to software development.
At no point did I find or notice a modifier of the article being an argument for the usage of singletons in wordpress plugins. though I may just have missed it.
I pretty much stopped reading there. Referencing WordPress when making a point about software design does not strengthen your point.
Singletons are the antithesis of dependency injection.