1

Sometimes, I come up with situations where a single instance of a class is enough, thanks to collections. An example would be my Decoder class:

public class Decoder
{

    private static final Decoder instance = new Decoder();
    private final HashMap<Client, State> states = new HashMap<Client, State>();

    private Decoder()
    {

    }

    public Packet decode(Client client, ByteBuffer data)
    {
            return null;
    }
}

But I was thinking, why not just make it so it looks something like:

public class Decoder
{

    private static final HashMap<Client, State> states = new HashMap<Client, State>();

    public static Packet decode(Client client, ByteBuffer data)
    {
            return null;
    }
}

Both designs effectively accomplish the same thing. Is there any practical difference in the two? When would I use one over the other? Thanks.

Martin Tuskevicius
  • 2,590
  • 4
  • 29
  • 46
  • This is a duplicate question. http://stackoverflow.com/questions/519520/difference-between-static-class-and-singleton-pattern http://stackoverflow.com/questions/3532161/what-is-the-difference-between-a-singleton-pattern-and-a-static-class-in-java – David Apr 28 '12 at 05:37
  • All of those speak of how singleton is useful for implementing interfaces and such. My scenario does not require such. Thanks for pointing out those duplicates, though. – Martin Tuskevicius Apr 28 '12 at 05:42

3 Answers3

3

If you want to unit test a class that uses a Decoder (or any other "utility" object), you may want to mock it out - that is, replace the Decoder with a dummy object whose behaviour is known. That way, your unit test won't break if the Decoder class changes.

This is much easier to achieve if the Decoder is an actual object. If the Decoder is a class full of static methods, you can't really mock it easily (although there are mocking frameworks that can achieve this by mucking around with the byte code).

In short, static methods are a testability anti-pattern. I strongly recommend avoiding them at all costs. If you want to read more about this, try http://misko.hevery.com/2008/12/15/static-methods-are-death-to-testability/ - there's lots of other good advice about testability on this site too.

Dawood ibn Kareem
  • 77,785
  • 15
  • 98
  • 110
1

I think that use static methods is more short when you code in the client class,

public class Collections {
   // Suppresses default constructor, ensuring non-instantiability.
   private Collections() {
   }

   public static <T extends Comparable<? super T>> void sort(List<T> list) {
       ...
   }
}

Then we have,

Collections.sort(list);
Paul Vargas
  • 41,222
  • 15
  • 102
  • 148
1

I would use all static methods, unless you see the need to implement an interface e.g. so you can mock out or replace your instance.

public enum Decoder implements IDecoder {
    INSTANCE;

    private final Map<Client, State> states = new HashMap<Client, State>();

    public Packet decode(Client client, ByteBuffer data) {
            return null;
    }
}

or

public enum Decoder {;
    private static final Map<Client, State> states = new HashMap<Client, State>();

    public static Packet decode(Client client, ByteBuffer data) {
            return null;
    }
}
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130