Singleton or static class? - java

I have the following class :
public class EnteredValues {
private HashMap<String, String> mEnteredValues;
public boolean change = false;
public boolean submit = false;
private static final EnteredValues instance = new EnteredValues();
// Singleton
private EnteredValues() {
mEnteredValues = new HashMap<String, String>();
}
public static EnteredValues getInstance() {
return instance;
}
public void addValue(String id, String value) {
if (mEnteredValues.put(id, value) != null) {
// A change has happened
change = true;
}
}
public String getValueForIdentifier(String identifier) {
return mEnteredValues.get(identifier);
}
public HashMap<String, String> getEnteredValues() {
return mEnteredValues;
}
public void clean() {
mEnteredValues.clear();
change = false;
submit = false;
}
}
This class is used to manage the values that a user has already entered, and the class should be accessible to all classes across the application.
When the activity changes I 'reset' the singleton by calling the clear method.
I chose the singleton pattern without really considering the option of a static class.
But now I was wondering if I shouldn't just use a static class..
What is the common way to handle a class that just manages values?
Is a static class faster as a singleton?
thx

The very fact that you are providing a clear method to reset the state of your Singleton dictates that you should not use Singleton. This is risky behavior as the state is global. This also means that unit testing is going to be a big pain.
One more thing. Never ever declare instance variables as public. Declare them as private or protected and provide getters and setters. Also, there is no need to initialize instance variables with a value that is their default value.

The main difference between a static class and the singleton pattern is that singleton may be used if you need to implement an interface or such. For this particular case I think you might be better off with a static class since you are not implementing any interface. Relating your question if its one faster to the other, I'd say is negligible the difference but using a static class will remove a small overhead of dynamic instantiation of the class.

What is bad in using singleton if you need such a design? If you need exactly one instance of some object designed to do specified things singleton is not a bad choice for sure.
#see Are Java static calls more or less expensive than non-static calls?
Read
http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
From there:
Note: A static nested class interacts with the instance members of its outer class (and other classes) just like any other top-level class. In effect, a static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience.

Just for style
I prefer not to rely on Singleton if I don't need to. Why? Less cohesion. If it's a property you can set from outside, then you can test your Activity (or whatever) with unit testing. You can change your mind to use diferent instances if you like, and so on.
My humble advise is to have a property in each of your Activities (maybe you can define a common base class?), and set it at activity initialization with a new fresh instance.
Your code will not know nothing about how to get it (except the init code and maybe you can change it in the future).
But as I've said... just a matter of taste! :)

Related

Static to non-static refactoring, can't have both?

I have a refactoring situation that I cannot find an elegant solution for...
Disclaimer:
Keep in mind that I am oversimplifying this example to reduce clutter, and not disclose things I am not allowed to disclose :)
As such, please do not assume that this is the ONLY code in my giant codebase, and offer solutions that cut corners or change parts of the design that I mention cannot be changed due to outside constraints.
The facts:
I have a utility class, it has a bunch of static methods, they utilize a singleton resource:
public final class Utility
{
private static final Resource RES = Resource.getInstance();
private Utility() {} // Prevent instantiating Utility
public static boolean utilMethodOne() { return RES.isSomething(); }
public static int utilMethodTwo() { RES.getNumThings(); }
...
public static void utilMethodInfinity() { ... }
}
Utility is in a library JAR that is used by several applications in a large codebase -- let's say on the order of 10,000 calls to its static methods, e.g.: if(Utility.utilMethodOne()) { ... }
Resource is an outside class from another library JAR.
Resource also has a method Resource.getInstance(String name) that will return a named instance, which may relate to a different underlying resource based on the name (internally it keeps the named resources in a Map<String,Resource>).
Resource.getInstance() returns the equivalent of Resoruce.getInstance(""), aka the default instance.
The situation:
The Utility needs to be enhanced to now execute against one of several resources, so my plan is to make the Utility an instantiable class with a non-static Resource member variable. Something like this:
public final class Utility
{
private Resource res;
public Utility(String resName)
{
this.res = = Resource.getInstance(resName);
}
public boolean utilMethodOne() { return this.res.isSomething(); }
public int utilMethodTwo() { this.res.getNumThings(); }
...
public void utilMethodInfinity() { ... }
}
Now all this is great, and I can start creating Utility objects that access their specified resource instead of just the default one. However, as I mentioned, there are 10-100K method calls that are now invalid as they were calling static methods!
The problem:
My plan was to keep the static methods in Utility, and have them use the default instance from Resource, while adding in non-static variants for the instantiated Utility objects that use their "local" resource reference.
// Best of both worlds:
public static boolean utilMethodOne() { return RES.isSomething(); }
public boolean utilMethodOne() { return this.res.isSomething(); }
Maybe I can't have my cake & eat it too:
error: method utilMethodOne() is already defined in class Utility
public static boolean utilMethodOne(String sql)
So it seems I am going to have to either...
Introduce a whole new BetterUtility class for places that want to use the named-resources.
Update 10,000 places to instantiate & use the revised Utility object.
...? (hint: this is where your suggestions come in!)
I really don't like 1 or 2 for a variety of reasons, so I need to ensure there is no better 3 option before settling. Is there any way to retain a single class that can provide both the static & non-static interfaces in this case?
UPDATE 2020-06-01:
I am coming to the realization that this magical option 3 doesn't exist. So out of my original two options I think #2 is best as it's just one time "just get it out of the way and be done with it" type effort. Also incorporated some of your suggestions in the design(s).
So now that I have a direction on this, I am left with [hopefully only] one more key decision...
Update all the calls to create new objects
// For a one-off call, do it inline
boolean foo = new Utility("res1").utilMethodOne();
// Or when used multiple times, re-use the object
Utility util = new Utility("res1");
boolean foo = util.utilMethodOne();
int bar = util.utilMethodTwo();
...
Given the amount/frequency of usage, this seems like a whole lot of wasted efforts creating short-lived objects.
Follow the pattern that Resource itself uses, creating my own named-singleton map of Utilities (1:1 with their respectively named Resource)
public final class Utility
{
private static final Map<String,Utility> NAMED_INSTANCES = new HashMap<>();
private Resource res;
private Utility(String resName)
{
this.res = Resource.getInstance(resName);
}
public static Utility getInstance(String resName)
{
synchronized(NAMED_INSTANCES)
{
Utility instance = NAMED_INSTANCES.get(resName);
if(instance == null)
{
instance = new Utility(resName);
NAMED_INSTANCES.put(resName, instance);
}
return instance;
}
}
public boolean utilMethodOne() { return this.res.isSomething(); }
public int utilMethodTwo() { this.res.getNumThings(); }
...
public void utilMethodInfinity() { ... }
}
// Now the calls can use
Utility.getInstance("res1")
// In place of
new Utility("res1")
So essentially this boils down to object creation vs. a synchronization + map lookup at each usage. Probably a little bit of premature optimization here, but I'll probably have to stick with this decision long term.
UPDATE 2020-06-29:
Didn't want to leave an "Internet dead end" here...
I did eventually get all the call sites updated as described above (including option #2 from the 2020-06-01 update). It has made it through all testing and been running in production for a week or so now in various applications.
It seems that you may want to turn the Utility into a singleton map that will have the same static methods that access the singleton without any arguments on for the function invocations (just like you have now)
The singleton will support a static method of adding a new resource, you will then add it to the map.
In addition you can overload the existing methods to also accept an argument resource name, that will then use a particular resource from the map, otherwise will use the default entry from the map.
Keep the old methods and the new methods static.
private static final String DEFAULT = "RESOURCE1";
private static Map<String, Resource> resources = new HashMap();
static{
// initialize all resources
}
public static boolean utilMethod() { return resources.get(DEFAULT).isSomething(); }
public static boolean utilMethod(String resourceName) { return resources.get(resourceName).isSomething(); }

What if the benefit of using a final instance in the classic singleton pattern (if any)?

In the below snippet, Singleton1#INSTANCE is not final, while Singleton2#INSTANCE is:
public class Singleton1 {
private static Singleton1 INSTANCE = new Singleton1();
private Singleton1() {}
public static Singleton1 getInstance() {
return INSTANCE;
}
}
public class Singleton2 {
private static final Singleton2 INSTANCE = new Singleton2();
private Singleton2() {
public static Singleton2 getInstance() {
return INSTANCE;
}
}
What is the benefit of Singleton2 over Singleton1 (if any)?
There is none, Java wise. Class initialization happens atomically, within locks. No thread will be able to see Singleton1#INSTANCE partially created.
At this point, use final to clarify (to developers) that this field should not change.
I'm fairly certain that the answer is none for performance. It could prevent a bug if someone were to try and modify the reference at some point during the maintenance cycle.
final is basically used for two purposes in java -
1) For immutability - If a field is final, then it can only be initialized only once. So, if INSTANCE is not final then you can reinitialize creating one more object but this can only be done as constructor is private. So, basically final can avoid any other bugs which can be introduced at later stage as mentioned by Elliott.
2) To ensure that object is properly constructed before publishing (it is in context of multithreading) but since we are instantiating the INSTANCE on class loading (eager loading). It will not cause any issues. It will be created long before it will be used.

How to use a factory pattern to get the instance of my Database Client?

Below is my Interface -
public interface IDBClient {
public String read(String input);
public String write(String input);
}
This is my Implementation of the Interface -
public class DatabaseClient implements IDBClient {
#Override
public String read(String input) {
}
#Override
public String write(String input) {
}
}
Now I am thinking to write Thread Safe Singleton Factory to get the instance of DatabaseClient so that I can call read and write method accordingly.. So I wrote like this by following the Initialization On Demand Holder idiom, it is still incomplete -
public class DatabaseClientFactory {
public static DatabaseClientFactory getInstance() {
return ClientHolder.s_instance;
}
private static class ClientHolder {
}
}
And I am not sure how to get the instance of DatabaseClient correctly in my above Factory? Do I need to add another method getClient() to get the instance of DatabaseClient and then call like this -
IDBClient client = DatabaseClientFactory.getInstance().getClient();
client.read(input); // or client.write(input)
You shold use Initialization-on-demand holder idiom, implementing your factory:
public class DatabaseClientFactory {
private DatabaseClientFactory() {}
private static class LazyHolder {
private static final DatabaseClient INSTANCE = new DatabaseClient();
}
public static DatabaseClient getInstance() {
return LazyHolder.INSTANCE;
}
}
This code doesn't need synchronization because of the contract of the class loader:
the class loader loads classes when they are first accessed
all static initialization is executed before anyone can use class
class loader has its own synchronization that make previous two points guaranteed to be thread safe
Here is very a nice description of correct implementation of singleton from Joshua Bloch's (one of the Java's creators) "Effective Java" book. I would strictly recommend to read at least this chapter.
A few comments:
If you want your DatabaseClient to be singleton, you have to move your factory method to this class and make it's constructor private. Otherwise there is no guarantee, that everyone will use your factory and someone won't create the second instance of this class;
Even with such approach there is no guarantee, that someone won't use reflection to create new instance of your "singleton";
If you decide for some reason to make your DatabaseClient serializable - you'll expose another ability of getting the second instance of "singleton" and will have to apply some additional techniques to avoid this (which are also not always effective).
If you still decide to go this way - you can use one of the approaches suggested by "AgilePro" or "user987339" (with moving that logic to the DatabaseClient). I believe method, described by "user987339" is preferable as it will help to make this initialization really lazy. It's not really the case with approach described by "AgilePro" cause each call to some of the static methods of that class will initialize all static fields.
If you want to get really robust singleton - I suggest you to use enums. So your DatabaseClient will look like:
public enum DatabaseClient {
INSTANCE;
DatabaseClient() {
}
public String read(String input) {
}
public String write(String input) {
}
}
And its usage:
final DatabaseClient databaseClient = DatabaseClient.INSTANCE;
P.S. One more note related to all approaches: if you get some exception during initialization of DatabaseClient - you'll get "java.lang.ExceptionInInitializerError" which won't let you to initialize this class any longer (for all further calls to this class you'll get "java.lang.NoClassDefFoundError").
This is all you need:
public class DatabaseClientFactory {
private static final DatabaseClient mySingleton = new DatabaseClient();
public static IDBClient getInstance() {
return mySingleton;
}
}
Note the private static final member that holds the singleton instance. Declaring it final prevents you fromwriting code that might create another instance. In this case we construct as static initialization time which happens before any thread can possibly access it, but you could construct with lazy initialization at run time if you desired. In this latter case you would need to make the method synchronized, which is a bit more overhead.
I made the factory method return the interface, but it could if you wish be declared to return the concrete class instead. If your concrete class has some additional methods beyond the interface you may want to do the latter.
Access it like this
IDBClient client = DatabaseClientFactory.getInstance();
It is thread safe because the variable that holds the singleton object is initialized at static initialization time, before any thread can access it. Since it is never changed after that, there is no possibility of a race condition.
This approach is simpler than that other answer because this involves only two classes, which is all you need: the factory class and the client class. One of the other answers requires three classes. This is a very small difference, since an extra class is a very small overhead, but if you believe that code should remain as simple as possible for maintenance reasons, then using three classes when two would do is a waste.

Singleton instantiation

I have written the code shown below:
public class SiteMapFactory {
public static ISiteMap getSiteMap(Locale loc) {
ISiteMap returnMap = null;
if (loc.equals(Locale.US)) {
returnMap = SiteMap_en_US.getInstance();
}
if(loc.equals(new Locale("es","US"))){
returnMap = SiteMap_en_US.getInstance();
}
if(loc.equals(Locale.CANADA)){
returnMap = SiteMap_fr_CA.getInstance();
}
return returnMap;
}
}
I want to return the same site map for both en_US (English) and es_US (Spanish) of our website. So I am instantiating the US sitemap for both Spanish and English version (a third party vendor is converting our English pages to Spanish). The way the site map is instantiated is using singleton. Singleton object is created as follows:
public class SiteMap_en_US extends SiteMapTree {
private static SiteMap_en_US m_instance;
private SiteMap_en_US() {}
static {
m_instance = new SiteMap_en_US();
m_instance.init();
}
public static SiteMap_en_US getInstance(){
return m_instance;
}
#Override
protected void init() {
//some code
}
}
My question is: can I reuse the same singleton object twice? Is it a valid way of instantiating the singleton object?
Yes, you can reuse the same singleton object.
However: If you do this, you should not have to include any special handling within the object to determine which language it is being used for, it should simply behave the same way all the time.
If you have to make it behave differently, consider creating a subclass of SiteMap_en_US (SiteMap_es_US perhaps) that is derived from SiteMap_en_US and has a small number of behaviors overridden.
It's possible to do all sorts of locale checks within the object to determine its behavior, but I highly recommend considering a different approach that's easier to maintain.
You can create base class SiteMapUS and extend it to create two subclasses SiteMapUSEnglish and SiteMapUSSpanish.
public class SiteMapUS{
protected SiteMapUS(){
}
}
public class SiteMapUSEnglish{
protected SiteMapUSEnglish(){
}
public SiteMapUSEnglish getInstance(){
//return instance
}
}
public class SiteMapUSSpanish{
protected SiteMapUSSpanish(){
}
public SiteMapUSSpanish getInstance(){
//return instance
}
}
place all classes in separate package.
This is the simplest way to achieve your goal. Benefit of using this approach is that you can easily modify/add locale related changes without modifying other code.
This is why many agree that Singleton is an anti-pattern. You need multiple instances of the object, one for each locale. It's not a singleton. I like to say that Singleton is just a euphemism for global variables. You're basically allowing a global way to access the Locales.
Singleton - The anti pattern

Making a class singleton without using static method

I need to create a singleton class without keeping a static method.
How can i do that?
Create an enum with one instance
enum Singleton {
INSTANCE;
private Field field = VALUE;
public Value method(Arg arg) { /* some code */ }
}
// You can use
Value v = Singleton.INSTANCE.method(arg);
EDIT: The Java Enum Tutorial shows you how to add fields and methods to an enum.
BTW: Often when you can use a Singleton, you don't really need one as utility class will do the same thing. The even shorter version is just
enum Utility {;
private static Field field = VALUE;
public static Value method(Arg arg) { /* some code */ }
}
// You can use
Value v = Utility.method(arg);
Where Singletons are useful is when they implement an interface. This is especially useful for testing when you using Dependency injection. (One of the weakness of using a Singleton or utility class substitution in unit tests)
e.g.
interface TimeService {
public long currentTimeMS();
}
// used when running the program in production.
enum VanillaTimeService implements TimeService {
INSTANCE;
public long currentTimeMS() { return System.currentTimeMS(); }
}
// used in testing.
class FixedTimeService implements TimeService {
private long currentTimeMS = 0;
public void currentTimeMS(long currentTimeMS) { this.currentTimeMS = currentTimeMS; }
public long currentTimeMS() { return currentTimeMS; }
}
As you can see, if your code uses TimeService everywhere, you can inject either the VanillaTimeService.INSTANCE or a new FixedTimeService() where you can control the time externally i.e. your time stamps will be the same every time you run the test.
In short, if you don't need your singleton to implement an interface, all you might need is a utility class.
public class Singleton {
public static final Singleton instance = new Singleton();
private Singleton() {}
public void foo() {}
}
then use
Singleton.instance.foo();
Another approach is the singleton holder idiom which offers initialization on demand:
public class Something {
private Something() {
}
private static class LazyHolder {
public static final Something INSTANCE = new Something();
}
public static Something getInstance() {
return LazyHolder.INSTANCE;
}
}
Note that standalone singletons like this should be avoided where possible because it promotes global state, leads to hard-to-unittest code and depends on a single classloader context to name a few possible drawbacks.
Follow the Joshua Bloch enum recipe in "Effective Java" 2nd edition. That's the best way to create a singleton.
I don't understand why this comes up so much. Isn't singleton a discredited design pattern? The GoF would vote it off the island today.
You can use one of IoC containers (e.g. Google Guice) and use your class as singleton(eager or lazy - it depends on your needs). It's easy and flexible as instantiating is controlled by IoC framework - you don't need any code changes if, for example, you will decide to make your class not singleton later.
Use an object factory, fetch your singleton object from this factory.
ObjectFactory factory;
....
MySingletonObject obj = factory.getInstance(MySingletonObject.class);
of course, there are many frameworks to help you to achieve this.
the spring framework is a popular choice.
From within constructor you need to chceck if there is already instance of the class somewhere. So you need to store reference to your singleton instance in static variable or class. Then in contructor of singleton I would always check if there is existing instance of singleton class. If yes I wouldnt do anything if not I would create it and set reference.

Categories

Resources