views:

340

answers:

10

I have an application that has several classes used for storing application-wide settings (locations of resources, user settings, and such). Right now these classes are just full of static fields and methods, but I never instantiate them.

Someone suggested I make them Singletons, What's the case for/against?

+6  A: 

Effective Java says:

Singletons typically represent some system component that is intrinsically 
unique, such as a video display or file system.

So if your component warrants single instance accross the entire application and it has some state, it makes sense to make it a singleton

In your case, the settings of the application is a good candidate for singleton.

On the other hand, a class can only have static methods if you want to group certain functions together, such as utility classes, examples in jdk are java.util.Arrays java.util.Collections. These have several related methods that act on arrays or collections

naikus
How does this provide an advantage over a static class?
Borealid
@Borealid You gain control over the construction/destruction of the class, which can be important if you maintain state. Static classes should be stateless, like utility classes.
Jake
@Borealid In most cases the advantage is readilibility and oo elegance. An instance of a class represents actual initialized state. Where as static methods and fields make more sense where you want to group certain functions together and you cannot have them for a particular instance or type. Se my updated answer
naikus
You should incorporate these comments into the answer. Or I've created an answer that deals with these comments. Feel free to vote it up :-)
DJClayworth
A: 

If you don't ever need to instantiate them, I don't see the point of singletons. Well, I should amend that - if these classes cannot be instantiated, then it doesn't make sense to compare them to singletons - the singleton pattern restricts instantiation to one object, and comparing that to something that cannot be instantiated doesn't make sense.

I find my main use of singletons generally involves a class that has static methods that, after maybe preparing an environment, instantiate an instance of themselves. By utilising private constructors and overriding Object.clone() to throw CloneNotSupportedException, no other classes can create a new instance of it, or if they're ever passed an instance of it, they cannot clone it.

I guess I'd say that if your application settings are part of a class that is never instantiated, it's not relevant to say "It should/shouldn't be a singleton."

JBirch
There's actually a really cool way to do singletons in Java that doesn't require overriding `Object.clone()`, in which a private inner class has an instance of the singleton class. When you call a `getInstance()` method, you then point it to the inner instance.
JBirch
+1  A: 

Singleton will give you an object reference, that you can use all over your app... you will use singleton if you want objects and/or polymorphism...

Garis Suero
Having an object reference that you can use all over you app is not necessarily a good thing. In pre-object oriented days we called those "global variables" and they made maintenence very difficult.
DJClayworth
A: 

I think you no need to create signleton class. just make this class constructor private. Like Math class in java.

public final class Math {

    /**
     * Don't let anyone instantiate this class.
     */
    private Math() {}

//static fields and methods

}
Vivart
That is not a singleton class but rather the usage of an abstract class (which cannot be intantiated). A singleton class is instantiated exactly once and has a static instance getter.
f1sh
yeah i know what is singleton class.he is asking that should he go for singleton and i am telling that no need to go for singleton.But you should make your class's constructor private for accidental class instantiation.
Vivart
Vivart, there are cases where a Singleton is useful. See my answer.
DJClayworth
A: 

Singletons often show up in situations like you're describing- you have some sort of global data that needs to live in some place, and you'll only ever need one, preferably you want to make sure that you can only have one.

The simplest thing you can do is a static variable:

public class Globals{
   public static final int ACONSTANT=1;

This is fine, and ensures that you'll have only one, and you have no instantiation issues. The main downside, of course, is that it's often inconvenient to have your data baked in. It also runs into loading issue if, for example, your string is actually built, by, say, building something from an outside resource (there's also a gotcha with primitives - if your static final is an int, say, classes that depend on it compile it inline, which means that recompiling your constants may not replace the constants in the app - e.g., given public class B{ int i = Globals.ACONSTANT; } changing Globals.ACONSTANT and recompiling only Globals will leave B.i still =1.)

Building your own singleton is the next simplest thing to do, and is often fine (though look up discussions on problems inherent in singleton loading, e.g. double-checked locking). These sorts of issues are a big reason why many apps are built using Spring, Guice, or some other framework that manages resource loading.

So basically: Statics

  • Good: easy to code, code is clear and simple
  • bad: Not configurable- you've got to recompile to change your values, may not be workable if your global data requires complex initialization

Singletons fix some of this, Dependency Injection frameworks fix and simplify some of the issues involved in singleton loading.

Steve B.
A: 

Since your class is holding global settings, a pro for a singleton could be that you have more control about creation of the singleton. You could read a configuration file during object creation.

In other cases if methods are static there would be no benefit like in javas Math class which has only static members.

A more obvious need for singletons is when you implement factories as singletons, because you can interchange different implementations of this factory.

stacker
The control over creation also helps for testing components dependent on that singleton.
Frank Schwieterman
A: 
TerryP
+7  A: 

I consider the Singleton pattern to be the most inappropriately applied design pattern. In ~12 years of software development I'd say I've maybe seen 5 examples that were appropriate.

I worked on a project where we had a system monitoring service that modeled our system with a System class (not to be confused with Java's built-in System class) that contained a list of Subsystems each with a list of Components and so on. The designer made System a Singleton. I asked "Why is this a Singleton?" Answer: "Well, there is only one system." "I know, but, why did you make it a Singleton? Couldn't you just instantiate one instance of a normal class and pass it to the classes that need it?" "It was easier to just call getInstance() everywhere instead of passing it around." "Oh..."

This example is typical: Singletons are often misused as a convenient way to access a single instance of a class, rather than to enforce a unique instance for technical reasons. But this comes at a cost. When a class depends on getInstance(), it is forever bound to the Singleton implementation. This makes it less testable, reusable, and configurable. It violates a basic rule I follow and that probably has a common name in some design principles essay somewhere: classes should not know how to instantiate their dependencies. Why? Because it hardcodes classes together. When a class calls a constructor, it is bound to an implementation. getInstance() is no different. The better alternative is to pass an interface into the class, and something else can do the constructor/getInstance()/factory call. This is where dependency injection frameworks like Spring come in, though they are not necessary (just really nice to have).

So when is it appropriate to use a Singleton? In that rare case where instantiating more than one of something would literally ruin the application. I'm not talking about instantiating two Earths in a solar system app - that's just a bug. I mean where there is some underlying hardware or software resource that will blow up your app if you call/allocate/instantiate it more than once. Even in this case, classes that use the Singleton should not know it is a Singleton. There should be one and only one call to getInstance() that returns an interface that is then passed to constructors/setters of classes that need it. I guess another way of saying it is that you should use a Singleton for its "singleness" and not for its "globally accessibleness".

By the way, on that project I mentioned where System was a Singleton... Well System.getInstance() was laced throughout the code base, along with several other inappropriate Singletons. A year later some new requirements came down: "We are deploying our system to multiple sites and want the system monitoring service to be able to monitor each instance." Each instance... hmmm... getInstance() ain't gonna cut it :-)

SingleShot
So, which where the five appropriate situations?
gustafc
Oops, please ignore this comment.
DJClayworth
@gustacf: They were all C++ classes each representing a single piece of custom hardware, tightly coupled to the hardware, that instantiating more than once would make the hardware / software not work. Old school stuff, and still, it didn't prevent multiple process instances from bringing the whole thing down.
SingleShot
A: 

You should use singletons for modularization.

Imagine the following entities in singleton:

Printer prt;
HTTPInfo httpInfo;
PageConfig pgCfg;
ConnectionPool cxPool;

Case 1. Imagine if you did not do that, but a single class to hold all the static fields/methods. Then you would have one big pool of static to deal with.

Case 2.
In your current case, you did segregate them into their appropriate classes but as static references. Then there would be too much noise, because every static property is now available to you. If you do not need the information, especially when there is a lot of static information, then you should restrict a current scope of the code from seeing unneeded information.

Prevention of data clutter helps in maintenance and ensure dependencies are restricted. Somehow having a sense of what is or is not available to me at my current scope of coding helps me code more effectively.

Case 3 Resource identity.
Singletons allow easy up-scaling of resources. Let us say you now have a single database to deal with and therefore, you place all its settings as static in the MyConnection class. What if a time came when you are required to connect to more than one database? If you had coded the connection info as a singleton, the code enhancement would comparative much simpler.

Case 4 Inheritance.
Singleton classes allow themselves to be extended. If you had a class of resources, they can share common code. Let's say you have a class BasicPrinter which is instantiable as singleton. Then you have a LaserPrinter which extends BasicPrinter.

If you had used static means, then your code would break because you would not be able to access BasicPrinter.isAlive as LaserPrinter.isAlive. Then your single piece of code would not be able to manage different types of printers, unless you place redundant code.

If you are coding in Java, you could still instantiate a totally static content class and use the instance reference to access its static properties. If someone should do that, why not just make that a singleton?

Of course, extending singleton classes have their issues beyond this discussion but there are simple ways to mitigate those issues.

Case 5 Avoid information grandstanding. There are so few pieces of info that needs to be made globally available like the largest and smallest integers. Why should Printer.isAlive be allowed to make a grandstand? Only a very restricted set of information should be allowed to make a grandstand.

There is a saying: Think globally, act locally. Equivalently, a programmer should use singletons to think globally but act locally.

Blessed Geek
A: 

Effective Java says:

Singletons typically represent some system component that is intrinsically unique, such as a video display or file system.

So if your component warrants single instance across the entire application and it has some state, it makes sense to make it a singleton.

(The above nakedly borrowed from naikus)

In many cases the above situation can be handled by a 'utility class' in which all the methods are static. But sometimes a Singleton is still preferred.

The main reason for advocating a Singleton over a Static Utility Class is when there is a non-negligible cost involved in setting it up. For example if your class represents the file system, it will take some initialization, which can be put in the constructor of a Singleton but for a Static Utility Class will have to be called in the Static Initializer. If some executions of your app might never access the file system then with a Static Utility Class you have still paid the cost of initializing it , even though you don't need it. With a Singleton if you never need to instantiate it you never call the initialization code.

Having said all that, Singleton is almost certainly the most-overused design pattern.

DJClayworth
may be i am wrong. but what i think is singleton class creates a single instance at class loading time and static block is also run on class loading time. So in both cases initialization code will run only once.
Vivart
A Singleton does not create it's instance at class loading time, it creates it when the first instance is requested. If no instance is ever requested then the initialization code is never run.
DJClayworth