This was asked in a recent discussion, but was not able to tackle it properly. However I answered it by giving example of Enum but he was looking for some other way. Can you highlight the ways for which we can overcome above question?
This is how you would implement a Singleton with a public field :
public class Singleton {
public static final Singleton INSTANCE = new Singleton();
private Singleton() {}
}
Further reading on the pros and cons of this approach :
Item 3 from Joshua Bloch's Effective Java.
Short answer?
Using a private YourClass constructor and a public YourClass variable with eager instantiation
Long answer
https://en.wikipedia.org/wiki/Singleton_pattern
public class Singleton {
public static final Singleton INSTANCE = new Singleton();
//^ public variable
private Singleton() {}
//^ private constructor
}
It is a bad idea, but if you change the private variable to a public one, you will achieve your goal. You probably should declare the variable as final as well to avoid surprises, but it is not strictly necessary, and doesn't make it a good idea (IMO).
For what it is worth, there is no way to implement a singleton that doesn't involve an explicit variable to hold the instance, or an enum.
Here is what Bloch has to say on the tradeoff between the public and private variable approaches:
"One advantage of the factory-method approach is that it gives you the flexibility to change your mind about whether the class should be a singleton without changing its API. The factory method returns the sole instance but could easily be modified to return, say, a unique instance for each thread that invokes it. A second advantage, concerning generic types, is discussed in Item 27. Often neither of these advantages is relevant, and the final-field approach is simpler."
My argument is that knowing that you won't need to change your mind in the future involves a degree of prescience.
Or to put it another way, you can't know that: you can only predict that. And your prediction can be wrong. And if that prediction does turn out to be wrong, then you have to change every piece of code the accesses the singleton via the public variable.
Now if your codebase is small, then the amount of code you need to change is limited. However, if your codebase is large, or if it is not all yours to change, then this this kind of of mistake can have serious consequences.
That is why it is a bad idea.
Related
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.
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.
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
providing that service interface
providing a singleton
And it also helps with when writing unit tests.
I want to create a class with few methods which can be used anywhere inside a package. I opted to use enum with a single instance after reading that it automatically provides safe instantiation, serialization and protection from instantiating outside the enum. I believe it is the most easy and safe way of creating a singleton. But my superior came back saying that it's dirty programming. Is it really? Do anyone know the disadvantages of using an enum instead of object construction and passing around references using a class? When are enums initialized?
public enum Myenum {
INSTANCE;
public void init(...) {..initialize local variables...}
public method1 (...) {...}
public method2 (...) {...}
}
vs
public class Myclass {
public Myclass(...) {...initialize local variables...}
public method1 (...) {...}
public method2 (...) {...}
}
vs
public class Myclass {
public static void init(...) {...initialize local variables...}
public static method1 (...) {...}
public static method2 (...) {...}
}
In my view the disadvantage of using the second method is that an object reference of Myclass is needed everywhere I need to use methods and synchronization issues while object construction. I am not really using the serialization benefit of enum in my case.
Does enum implicitly provide the benefit of dependency injection? (i.e. Can access Myenum's method1, method2 everywhere inside the package without worrying about instance creation)
One other feature of enum I needed was methods inside an enum cannot be overriden outside of it.
Am I missing some obvious disadvantage here?
An enum gives a semantic signal to other programmers that it's a type with a series of possible values that you could check against, for example, in a switch statement. However, there are a number of compelling reasons why enums can be seen as a better implementation of a singleton pattern than most other patterns people typically use in Java.
If you're positive you want to use a singleton pattern, then using an enum is probably okay. However, there are patterns that tend to be more flexible, unit testable, SOLID, etc. What if one day you decide that you don't actually want this to be a singleton anymore? What if you want it to be refreshable when certain changes are made in the database? Using any singleton pattern is going to lock you into a singleton representation and make it harder to make changes like this in the future.
A Factory pattern would be more flexible than a singleton, but the best pattern of all, in my opinion, would be to use dependency injection. You can singleton-bind your type to avoid the costs of reinstantiating it, but the type itself (and its consumers) need not be tied to a specific lifetime or pattern.
Check out Java Concurrency In Practice and it's static singleton pattern. It looks like this:
public class ResourceFactory {
private static class ResourceHolder {
public static Resource resource = new Resource();
}
public static Resource getResource() {
return ResourceHolder.resource;
}
}
It's safe due to how/when statics are initialized, probably for the same reasons the Enums singleton trick is safe.
In JCIP's example, it's returning a thing, but you can add all the static methods you want that use however many variables you want to initialize in the ResourceHolder. And there's no init() call required.
I found an answer here to why creating a globally accessible pattern is bad instead of passing around references.
Excerpt:
They are generally used as a global instance, why is that so bad? Because you hide the dependencies of your application in your code, instead of exposing them through the interfaces. Making something global to avoid passing it around is a code smell.
They violate the single responsibility principle: by virtue of the fact that they control their own creation and lifecycle.
They inherently cause code to be tightly coupled. This makes faking them out under test rather difficult in many cases.
They carry state around for the lifetime of the application. Another hit to testing since you can end up with a situation where tests need to be ordered which is a big no no for unit tests. Why? Because each unit test should be independent from the other.
I was exploring the singleton design pattern, I have developed a class...
public class SingletonObject {
private static SingletonObject ref;
private SingletonObject () { //private constructor
}
public static synchronized SingletonObject getSingletonObject() {
if (ref == null)
ref = new SingletonObject();
return ref;
}
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException ();
}
}
but synchronization is very costly , so I move to new design of eagerly created instance rather than a lazily created one..
public class Singleton {
private static Singleton uniqueInstance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return uniqueInstance;
}
}
But please advise me how the second design is advantage over the previous design..!!
Josh Bloch recommends using an enum:
public enum Foo {
INSTANCE;
}
For an explanation, see his Effective Java Reloaded talk at Google I/O 2008.
In summary:
"This approach is functionally equivalent to the public field
approach, except that it is more concise, provides the serialization
machinery for free, and provides an ironclad guarantee against
multiple instantiation, even in the face of sophisticated
serialization or reflection attacks. While this approach has yet to be
widely adopted, a single-element enum type is the best way to
implement a singleton."
As you stated, the second solution avoids synchronization costs. It is also simpler and cleaner, so easier to read and maintain. It has a little problem though: you miss a final qualifier for private static Singleton uniqueInstance, which means that it may not be guaranteed to be thread safe in a concurrent environment (although in this concrete case I don't think this would cause any tangible problem in real life... but better be on the safe side regarding thread safety). Luckily this is easy to fix.
Its other drawback is that as soon as the class Singleton is referenced, the singleton object is created, even if it is never actually used. This might be a problem if creation is costly. It can be avoided with the Initialization-on-demand Holder idiom.
Your second design is better in that it is a bit more concise and easier to read. Also, as you mentioned, it avoids the cost of synchronizing every time you wish to use the singleton.
One drawback of your second design is that you incur the memory and cpu cost of instantiating the singleton even if you never use it.
Eager Instantiation vs. Lazy Initialization
Your second design uses eager instantiation instead of lazy initialization. That's not necessarily better or worse, it depends on which is appropriate for your application.
Generally it's better to use lazy initialization if:
If there's a chance that your application won't need to create an instance of your class
If instantiating your class is expensive, and you'd rather defer the operation till as late as possible
Thread Safety and Performance
One other advantage of your second design is that it's more performant. In a multi-threaded environment, your first design will require each thread to acquire a lock before getting the instance, even after it has already been instantiated. You can get around this by using double-checked locking or the Bill Pugh approach.
Enum Way
An approach that is different than both of your designs is the Enum way, which uses an Enum with a single value. Since Enums can have methods and member variables, you can mimic the kind of behavior that a normal class would have. This is a nice, ironclad way to create a singleton, and is recommended by Joshua Bloch.
You should also make the variable pointing to your singleton final.
public class Singleton {
private static final Singleton uniqueInstance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return uniqueInstance;
}
}
This implementation has the ClassLoader instantiate the instance of the singleton, providing thread safety. An alternative pattern uses an enum, but I personally consider that implementation to be a code smell.
Few notes:
Your first example does not work as expected in multi-threaded scenario. Your ref should be volatile variable and double check with locking is required.
Your second example does not have additional synchronization cost. But you can implement Lazy Singleton instead of eager Singleton effectively.
Refer to below SE question for more details:
Why is volatile used in this example of double checked locking
I've found three ways of instantiating a Singleton, but I have doubts as to whether any of them is the best there is. I'm using them in a multi-threaded environment and prefer lazy instantiation.
Sample 1:
private static final ClassName INSTANCE = new ClassName();
public static ClassName getInstance() {
return INSTANCE;
}
Sample 2:
private static class SingletonHolder {
public static final ClassName INSTANCE = new ClassName();
}
public static ClassName getInstance() {
return SingletonHolder.INSTANCE;
}
Sample 3:
private static ClassName INSTANCE;
public static synchronized ClassName getInstance()
{
if (INSTANCE == null)
INSTANCE = new ClassName();
return INSTANCE;
}
The project I'm using ATM uses Sample 2 everywhere, but I kind of like Sample 3 more. There is also the Enum version, but I just don't get it.
The question here is - in which cases I should/shouldn't use any of these variations? I'm not looking for lengthy explanations though (there's plenty of other topics about that, but they all eventually turn into arguing IMO), I'd like it to be understandable with few words.
The most secure and easy way to implement a singleton in java is by using enums (like you mentioned):
public enum ClassName {
INSTANCE;
// fields, setters and getters
}
The enum semantics guarantees that there will be only one INSTANCE
If not using the enum approach, you must take care of quite a lot aspects, like race conditions and reflection. I've been breaking singletons of some frameworks, and abusing them, because they weren't properly written. The enum guarantees no one will break it.
Sample 1 does not use lazy initialisation.
Sample 2 and 3 are both lazy. Sample 2 uses the Initialization on demand holder idiom (IODH) which has no synchronisation overhead. Therefore it is faster than Sample 3.
In Effective Java (Item 3), Joshua Bloch recommends that a single-element enum type is the best way to implement a singleton.
However, if you are unsure about the enum type, stick with IODH.
First of all, make absolutely sure that you need a singleton, and that you want to provide "global-level" access to the singleton. I've found that in many cases clients of the singleton have no need to know that it is a singleton. Rather, they just need to get a service when they are instantiated.
Thus, regardless of how you obtain the singleton (if at all), consider changing the way your classes gain access to this object. While this means modifying constructors and changing "distribution changes", I've found that dependency injection frameworks reduce the cost. The DI framework can also then take care of singleton instantiation (e.g., Guice does that).
Aside from that. option 3 is the typical and most common (and thread safe) version that I'm familiar with. Option 1 is mostly for non-lazy initialization (not always acceptable). I've never seen 2 used.
Sample 1: Use if you don't need a lazy Singleton.
Sample 2: Never use - it gets confusing with too much classes. And an inner class just to hold one variable seems to be a bit unnecessary.
Sample 3: This is a lazy Singleton. Use it if you need it.
Can anyone provide an example of a singleton pattern and explain why they are necessary?
Before going the singleton route, reconsider. Do you really need a singleton? If you're asking for scenarios when you need to implement singletons, it's because the need for them didn't really express. You're better off not introducing singletons in your code base just because it feels cool to follow design patterns.
Clean Code Talks - Global State and Singletons
Once Is Not Enough
Performant Singletons
However, what's really worth knowing is Dependency Injection.
Now if you really want to implement singletons in Java, I would recommend Joshua Bloch's "Effective Java" way of implementing them:
public class Singleton
{
public static Singleton getInstance() {
return SingletonHolder.instance;
}
private Singleton() {}
private static final class SingletonHolder {
static final Singleton instance = new Singleton();
}
}
The JLS guarantees the JVM will not initialize instance until someone calls getInstance();
Final note, the Double Checked Locking Pattern is broken in Java up to Java 5. The Java 5 memory model makes the DCL pattern thread safe but it makes it slower than the SingletonHolder class method while the original intent was performance optimization.
EDIT: As #Luno pointed out, since the second edition of the book, the preferred way is:
As of release 1.5, there is a third approach to implementing singletons. Simply make an enum type with one element:
// Enum singleton - the preferred approach
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() { ... }
}
This approach is functionally equivalent to the public field approach, except that it is more concise, provides the serialization machinery for free, and provides an ironclad guarantee against multiple instantiation, even in the face of sophisticated serialization or reflection attacks. While this approach has yet to be widely adopted, a single-element enum type is the best way to implement a singleton.
Basically, in Java you implement singleton by giving a class a private no-args constructor (private MyClass()), and statically (or lazily) initializing a single instance of the class which is returned by a static MyClass getInstance() method.
You would use this when you want there to be no more than a single instance of your class throughout the entire application.
danben has a pretty good summary of what a singleton is, so I won't rehash it.
As far as uses go, singletons are often thinly veiled implementations of global variables (which is a bad idea). They can be useful for things like message routers or manager classes (among other things).
'Simply Singleton' at JavaWorld
And if you really want to get into the trenches, start reading about "static vs singleton" on the groups, or Google it. Always a hot topic to say the least!
One often underappreciated place where singletons are good is when you want to abstract away the existence of state. An example is a random number generator. At the level of the abstraction, it just generates random numbers and doesn't have any state that the caller should need to care about. At the implementation level, though, state is involved. Another is when a function caches results or intermediate computations, but you want to hide this detail from the caller.
There is a significant tradeoff here. If you make things like these singletons, you decrease the amount of implementation details the caller of your function has to care about, thus decreasing coupling in that direction. However, at the same time you strongly couple your function to the singleton object, making it harder to test, etc. The decision about whether to use a singleton should be made based on which direction you care about reducing coupling in more.
assume you have only one printer in office and you need Ensure a printer class has only one instance
printer{
private static printer instance =null;
private printer(){}
public static printer getinst(){
if( instance==null){
instant = new printer();
}
return instance;
}
}
in the main
printer v=printer.geti();