tags:

views:

114

answers:

6

Hi,

I am wondering about programming decision - which I think is matter of style. I need to have single instance of class which has only methods and no attributes. To obtain that in java I have two options:

  1. create an abstract class with static methods within, thus it will not be possible to create any instance of the class and that is fine,
  2. use a singleton pattern with public methods.

I tend to go for second approach although met with 1. Which and why is better of those, or there is third option.

+3  A: 

Would it make sense for that singleton to implement an interface, allowing you to mock out those methods for test purposes?

I know it goes against testing dogma these days, but in certain situations I think a static method is fine. If it's the kind of behaviour which you're never going to want to fake for test purposes, and which is never going to be polymorphic with other implementations, I don't see much point in making a singleton. (Singletons are also generally the enemy of testability, although if you only directly refer to them in the injection part of your code, they can implement appropriate interfaces so their singletoneity never becomes a problem.)

It's worth mentioning that C# has "static classes" for this kind of situation - not only do they prohibit other code from deriving from or instantiating the class, but you can't even use it as a parameter. Basically it signals the intent very clearly.

I would definitely suggest at least having a private constructor to prevent instantiation by the outside world.

Jon Skeet
+1  A: 

For option #1, it may not even be that important to restrict instantiation of your static utility class. Since all it has is static methods and no state, there is no point - but neither harm - instantiating it. Similarly, static methods can't be overridden so it does not make sense - nor difference - if it is subclassed.

If it had any state, though - or if there is a chance that it will get stateful one day - it may be better to implement it as a normal class. Still I would prefer not to use it as a Singleton, rather to pass its sole instance around via dependency injection. This makes unit testing so much easier in the long run.

Péter Török
+1  A: 

If it holds a state I would use the singleton pattern with private constructors so you can only instantiate from within the class. If it does not hold a state, like the apache commons utility classes, I would use the static methods.

Peter DeWeese
+2  A: 

My personal view is that the class should contain a private constructor and NOT be abstract. Abstract suggest to a reader that there is a concrete version of the class somewhere, and they may waste time searching for it. I would also make sure you comment your code effectively.

public class myClass {

   /** This class should never be instantiated. */
   private myClass() {
   }

   public static void myMethod() {

   }

   ...
   //etc
   ...
}
Codemwnci
+1 @ Abstract suggest to a reader that there is a concrete version of the class somewhere.
Chankey Pathak
A: 

I've never seen the problem with static methods. You can think of static methods as somehow breaking OO, but they make perfect sense if you think of static as a marker that something is stateless. You find this in the java apis in places like java.Math. If you're worried about subclassing you can always make it final.

There is a danger in that a class like that can end up as a "utility method garbage can", but as long as the functionality doesn't diverge too much then there's nothing wrong with it.

It's also clearer, as there's no need to manage an object lifecycle like you would with a singleton (and since there's no state, what's the point of that anyway?).

Steve B.
A: 

For a single instance, I suggest you have an enum, with one instance.

However, for a class with no attributes, you don't have to have an instance. You can use a utility class. You can use an enum, with no instances and only static methods. Note: this cannot be easily mocked out.

You can still implement an interface if you ever need to mock out the implementation in testing.

Peter Lawrey