How I usually make a singleton in java is by removing the ability to instantiate another instance and providing only one instance to be used via a static method. This is easily done by changing the constructors visibility to private or protected, while making it protected allows for subclasses to be made which could break the rule where as private does not.
public final class Singleton { private static Singleton instance = null; private Singleton() { } public static Singleton getInstance() { if(instance == null) { instance = new Singleton(); } return instance; } }
In my opinion if you need to make a subclass of a singleton to override functionality then singleton is the wrong pattern. Also use of the final keyword will ensure there are no subclasses or anonymous classes can be made. Which of these you use depends entirely on the responsibilities and usage of the class. The core java package has a few singletons ones that come to mind are the Runtime, Toolkit, and Desktop. System almost seems like one as well, though it isn't instantiated so it's not a singleton and more akin to a C library in C++.
There is a lot of good material out there discussing the pitfalls and implementation issues associated with Singletons and their instantiation. But before I go into those I will answer why I recommend staying away from them. You first must be absolutely certain without any shadow of a doubt you won't need two of those objects. Secondly only use a singleton if there are variables that you are using to store data that is imperative to the objects behavior and needs to alter as time goes on, this I believe is referred to as saving state or containing state. Thirdly you have to think of threading since a non-thread safe singleton is paramount to suicide you will inevitably restrict any function that uses the singleton to not be thread safe (dangerous and limiting).Fourthly you are automatically granting access to the singleton to any piece of code that imports it which will create a binding contract with the singleton which is not good since most of the time you don't know what your overall end design is going to look like or what your going to add next.
The only reason for creating one is if you have your full set of requirements and features upfront and know 100% your not going to want two or more of them. Sometimes the singleton is used to create a set of library style functions or functionality that is really designed for more of a customized command type language in a generic object oriented language. Here are some resources to get you more answers on different implementation strategies of Singletons in Java.
http://www.javaworld.com/javaworld/jw-04-2003/jw-0425-designpatterns.html?page=6
http://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons
If those fail resort to google.
The stackoverflow post gives a good concise explanation of the design problems around singletons. The alternative I use is more along the lines of simple dependency injection which is more flexible and forces you to define relationships between objects that need the would be singletons functionality and how to give them access to it. Singletons and Static methods in Java circumvent having to define relationships between objects by providing global access which in turn creates coupling where ever they are used unless you design your objects to use any instance instead of the one and only instance of the singleton. Example would be
constructor(Singleton s) { // not globally accessed so singleton can be any instance }While this is still coupling it's more flexible than say this
constructor() { Singleton.getInstance().use(); }I hope this helps give some resources and explanation of singletons. Let me know the reasons or situations where you've used singletons even if you didn't know what they were. Each situation in coding has some level of constraints to it whether it be working with an existing system where you need to add functionality without redesigning a lot of code so Singletons were used as a way of circumventing necessary design activities or to reduce the amount of work involved in order to add unanticipated features, and I've seen this a lot in code where no solid unit tests exists so redesign causes significant risk to existing code so public global access to new features is easier than the redesign. Cheers!
No comments:
Post a Comment