Hacker News new | ask | show | jobs
by jemfinch 4126 days ago
Singletons were perhaps the worst possible example of code snobbery: code snobs (real code snobs, as in "no true code snob") typically detest the singleton pattern as less maintainable, less testable, and less flexible than dependency injection.
2 comments

Over reliance on singletons can indeed be less maintainable, less testable, and less flexible than dependency injection.

However sometimes a singleton is in fact more maintainable and improves the code massively. Nor do they have to be less testable when implemented well.

None of which detracts from the article which is about consistency in the code base. A knew jerk reaction to the singleton completely misses the point.

I totally agree that the singleton detail is beside the article's point, but what is the modern case for singletons? It seems like singletons are now considered a synonym for global variables. What other purpose do they serve?
I wrote a singleton just the other day. I dont often write these but occasionally they are useful.

It enabled us to decouple some code deep down in our architecture and enforce some constraints around the use of this particular piece.

When you actually need a singleton it's best to use one and call it out as such so people know what they are dealing with. Dependency injection will often be passing around a singleton everywhere without people being aware that it's a singleton and all that that means.

I've never seen a singleton I couldn't refactor away. Removing singletons always makes dependencies between modules more explicit which is a good thing.
I wrote a singleton the other day. Using Java, I had a static utility class that had a function that I wanted to memoize. So I put a static HashMap in the class to do the lookups. There's no reason to have multiple copies, and it's easy to instantiate it only if it is needed.
That's reasonable, but it seems to be equivalent to creating a top-level function and associated global variable in other languages. Java's prohibition of those constructs necessitated the class wrapper, but doesn't appear to provide any benefits over another more generalizable method, namespacing.
That's true. If I weren't using java, I wouldn't have had to use a singleton. That's as much of a problem with singletons as it is an over-reliance on the object-oriented style.

I suspect dependency injection has the same problem: you could achieve the same results in a non-object-oriented language.

In the author's example it's about internal consistency, a bunch of other similar items are already singletons.

Better a consistent-but-suboptimal architecture than a random grab bag of varying quality.

A journey of a thousand miles starts with the first step. If you're committed to code quality, existing low quality code should not prevent you from doing the right thing with new code; on the contrary, doing the right thing with new code will free you to refactor or update the old code to be cleaner.
Again, I refer you back to the original scenario: The inconsistency is presented as accidental or unintentional, not as the first step in a cohesive long-range plan to refactor the codebase.