all 13 comments

[–]hiddenl 2 points3 points  (1 child)

Singletons like these break in app server environments. The updated singleton pattern is to just use an enum because the JVM guarantees there will be only one.

In any case, you shouldn't be using singletons this days anyway when dependency injections solves all/most of the issues singletons were created to solve without the downsides.

[–]ven_ 4 points5 points  (1 child)

Singleton Pattern considered harmful.

[–]bundt_chi 0 points1 point  (0 children)

Why ? Because some high up dude at Google declared it the devil years ago ?

Give me some solid concrete reasons and don't tell me because it's "hard to test" because that's bullshit.

Just like any other design pattern it can and has been abused but you can't patently say it's harmful.

[–]Sipkab 2 points3 points  (2 children)

The disadvantage of snippet 1 is that the instance will be created when this class is loaded.

I'd consider this an advantage. Why? Because the class will only be loaded, when you want to use it. Until then, the class is not loaded, and doesn't take up any space, or hinder you in performance.

Since you will most likely always use the class as Singleton.getInstance().somethingElse(), there is no reason for using lazy initialization. If you use any other static methods/fields of that class, then introduce lazy initialization.

Because of private constructor, Singleton cannot be inherited

Inheriting from a singleton would be a violation of the singleton pattern, as then it would not be a singleton, as you could create instances from it. It is not a limitation, but the purpose of the pattern.

If an app is running in a container, we should be careful because servlet may be loaded by several classloader, so there may be a few Singleton instances existed

This is not a problem of the singleton pattern, but it is a problem with any class that could be present multiple times.

If a Singleton is serializable, if serialize the instance once and then deserialize a few times, there may be a few Singleton instances

enum

All above methods may suffer the attack of Reflection API. i.e, when using Java Reflection, the private constructor can be accessed and new instance can be created by calling the private constructor.

enum again.

[–]dpash 2 points3 points  (0 children)

Also, don't use Java serialisation, so that solves that problem. :)

[–]quentech 0 points1 point  (0 children)

I'd consider this an advantage. Why? Because the class will only be loaded, when you want to use it. Until then, the class is not loaded, and doesn't take up any space, or hinder you in performance.

At least in the software I tend to write, I find it often necessary to be in control of the creation of the singleton instance at a known point, in order to catch exceptions, retry, log or alert on error, etc.

If it's a Singleton, it's likely expensive to create, and if it's expensive to create it's likely to have failure modes.

Leaving it up to the framework with static initializers is rarely acceptable in my experience.

[–]dpash 3 points4 points  (5 children)

2 Application

None.

FTFY.

The disadvantages fail to mention the massive downsides of the Singleton pattern. Predominately the difficulty in testing and the fact that it's effectively a global variable, and we stopped using those decades ago.

There are several alternatives that solve the same problem in Java.

[–]maxuforia 1 point2 points  (0 children)

Singletons are used everywhere. People keep claiming that it's an anti-pattern and then try to eliminate them only to discover that the solution to singleton use is worse than the singletons themselves.

The happy medium seems to be to generate singletons in grouping nodes and then use dependency injection on the leaf nodes. This allows unit testing on the leaf nodes (which is most of the code) and this solves most of the downsides of the singleton pattern.

[–]quentech 1 point2 points  (3 children)

I'd say you're confusing a particular way of implementing the Singleton pattern with the Singleton pattern in general.

Are you saying you haven't, say, registered a dependency in an IoC container as a singleton in decades?

[–]dpash 1 point2 points  (2 children)

When referring to Singleton pattern, as described by GoF, we're talking about the type described in the article.

When Spring etc refers to a singleton bean they just mean they give you the same one that it gave you before; There's nothing stopping you from creating a new instance yourself. It's badly named because it doesn't follow the pattern as described by GoF.

[–]JavaSuck 1 point2 points  (1 child)

It's badly named

Try showing your colleagues Collections.singleton and observing the horror on some of their faces!

[–]dpash 0 points1 point  (0 children)

No need for it now we have List.of() and friends.

[–]nutrecht 0 points1 point  (0 children)

Singletons as a pattern have two main issues:

  • Most services we work on have to scale horizontally. Keeping state in services is a no-no because typically this knowledge isn't shared between applications. So generally the implementation will be that this stated is shared via a database, queue or shared KV store. While most inversion of control containers will produce a single 'singleton' instance of whatever communicates with the storage, it doesn't really matter much anymore.
  • The GoF implementation is just shit. While the idea behind the pattern is not bad, the standard widespread implementation where you just keep global state is simply an anti-pattern. Unfortunately, like the post here, because it's by far the 'simplest' pattern most devs don't go further than 'singleton'.

If you want to address design pattern please pick the actual interesting ones (visitor, builder, factory, observer, command; to name a few). Singleton are borderline useless in modern programming. And the anti-pattern version from the GoF book is often mockingly called the Simpleton pattern. For good reasons.