有时,由于集合,我想出了一个类的单个实例就足够了的情况。一个例子是我的Decoder类:
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;
}
}
但是我在思考,为什么不这样做它看起来像:
public class Decoder
{
private static final HashMap<Client, State> states = new HashMap<Client, State>();
public static Packet decode(Client client, ByteBuffer data)
{
return null;
}
}
两种设计都有效地完成了同样的事情。两者有什么实际区别吗?我何时会使用一个而不是另一个?感谢。
答案 0 :(得分:3)
如果要对使用Decoder
(或任何其他“实用程序”对象)的类进行单元测试,您可能想要将其模拟出来 - 也就是说,将Decoder
替换为虚拟对象行为已知的对象。这样,如果Decoder
类更改,则单元测试不会中断。
如果Decoder
是实际对象,则更容易实现。如果Decoder
是一个充满静态方法的类,你就不能轻易地模拟它(尽管有一些模拟框架可以通过使用字节代码来实现这一点)。
简而言之,静态方法是可测试性反模式。我强烈建议不惜一切代价避免它们。如果您想了解更多相关信息,请尝试http://misko.hevery.com/2008/12/15/static-methods-are-death-to-testability/ - 此网站上有关于可测试性的许多其他好建议。
答案 1 :(得分:1)
我认为在客户端类中编写代码时使用静态方法会更短
public class Collections {
// Suppresses default constructor, ensuring non-instantiability.
private Collections() {
}
public static <T extends Comparable<? super T>> void sort(List<T> list) {
...
}
}
然后我们有,
Collections.sort(list);
答案 2 :(得分:1)
我会使用所有静态方法,除非你看到需要实现一个接口,例如所以你可以模拟或替换你的实例。
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;
}
}
或
public enum Decoder {;
private static final Map<Client, State> states = new HashMap<Client, State>();
public static Packet decode(Client client, ByteBuffer data) {
return null;
}
}