
Question:
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.
Answer1: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;
}
}
Answer2: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 <a href="http://misko.hevery.com/2008/12/15/static-methods-are-death-to-testability/" rel="nofollow">http://misko.hevery.com/2008/12/15/static-methods-are-death-to-testability/</a> - there's lots of other good advice about testability on this site too.
Answer3: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);