0

Disclaimer: Apologies if this question is too basic.

I'm learning about Singleton and have a quick question its implementation, are these differences purely coding preferences or am I missing something?

Singleton Class

public enum SerialNumberGen {
INSTANCE;

private int count;

public synchronized int getNextSerial(){
    return count++;
}

Example Implementation

.println(SerialNumberGenerator.INSTANCE.getNextSerial());

My implementation

SerialNumberGen gen = SerialNumberGen.INSTANCE;
System.out.println(gen.getNextSerial());

Is my implementation still adhering to the Singleton pattern? Or is this how Enum classes are supposed to be referenced.

Thanks.

Glaube
  • 19
  • 6
  • Possible duplicate of [What is an efficient way to implement a singleton pattern in Java?](http://stackoverflow.com/questions/70689/what-is-an-efficient-way-to-implement-a-singleton-pattern-in-java) – Tom Mar 12 '17 at 13:27
  • [Read this](http://errorprone.info/bugpattern/ImmutableEnumChecker) before considering a mutable enum. – Andy Turner Mar 12 '17 at 13:34
  • Welcome to Stack Overflow! Please take the [tour](http://stackoverflow.com/tour), have a look around, and read through the [help center](http://stackoverflow.com/help), in particular [How do I ask a good question?](http://stackoverflow.com/help/how-to-ask) and [What topics can I ask about here?](http://stackoverflow.com/help/on-topic). - Now, after you have learned about the *Singelton* (Pattern): **forget it!** A Singelton is merily a *global variable* of which we know from 60 years of programming history to be bad idea. – Timothy Truckle Mar 12 '17 at 13:39
  • `SerialNumberGen gen = SerialNumberGen.INSTANCE;` Why did you redundantly set a variable to hold the one and only enum constant of the type, instead of just using the constant directly? – Lew Bloch Mar 12 '17 at 16:50
  • @LewBloch How would you reference it? I did this so I'd only have to type out the shorter: "gen.getWhateverMethod" instead of "SerialNumberGenerator.INSTANCE.getWhateverMethod()" – Glaube Mar 14 '17 at 13:03
  • Worried you might sprain a finger typing all that? – Lew Bloch Mar 14 '17 at 14:39
  • @LewBloch That's a weird way to reference it, thanks though. – Glaube Mar 21 '17 at 14:38

2 Answers2

1

Is my implementation still adhering to the Singleton pattern?

Yes. You still have exactly one instance of SerialNumberGen.

There's no difference between the two, aside from the additional variable in the second case.


You should think carefully about having a mutable enum. The view epoused by Google's Java libraries team is:

Static state is dangerous to begin with, but much worse for enums. We all think of enum values as constants – and even refer to them as “enum constants” – and would be very surprised if any of their state ever changed, or was not thread-safe.

Whilst enums are a convenient way to create thread-safe creation of singletons, they aren't necessarily well-suited to what you're doing here.

For me, the bigger question here is why do you think you need a singleton? I suggest you read and thoroughly consider What is so bad about singletons?.

There's nothing here that really requires a singleton. You can simply have a single instance of SerialNumberGen, which you have injected everywhere that needs it.

Community
  • 1
  • 1
Andy Turner
  • 122,430
  • 10
  • 138
  • 216
  • So it is just a matter of coding preference? I simply didn't want to type out the long line of code so I made an object of the class and referenced it, but that's still cool? – Glaube Mar 12 '17 at 13:39
  • If you don't want such a "long" line of code, consider 1) using a static import; 2) buying a bigger monitor. – Andy Turner Mar 12 '17 at 13:41
  • I'm only learning Design principles/patterns for Java, so there's no real necessity for a singleton, other than learning how it works - I just wanted to check if the example we're given is the best or only way to implement it. Thanks for the help! – Glaube Mar 12 '17 at 13:46
  • "other than learning how it works" A really important thing to learn is why you *shouldn't* use it, really. Singletons are a pain in the derriere. Learn about dependency injection instead. – Andy Turner Mar 12 '17 at 13:46
  • "pain in the derriere"... Made my day. Upvote just for that. – GhostCat Mar 12 '17 at 17:58
0

It is still a singleton.

But please note: the much better approach is to encapsulate the specific behavior into an interface, so that

public enum ServiceProvider implements Service {

so that you can do

Service service = ServiceProvider.INSTANCE

for example. And going from there; I even create an ordinary

class ServiceImpl implements Service {

and then do

public enum ServiceProvider implements Service {
  INSTANCE;

   private final Service delegate = new ServiceImpl()

as that helps to further separate the responsibilities of

  1. providing that service interface
  2. providing a singleton

And it also helps with when writing unit tests.

GhostCat
  • 127,190
  • 21
  • 146
  • 218
  • Thank you, I think we'll be moving onto this kind of implementation down the line, just on the basics for now, but I'll certainly keep it in mind! – Glaube Mar 12 '17 at 14:06
  • You are very welcome. Glad you find my input helpful. – GhostCat Mar 12 '17 at 14:32