所有静态方法还是单个实例?

时间:2012-04-28 05:31:04

标签: java static instance

有时,由于集合,我想出了一个类的单个实例就足够了的情况。一个例子是我的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;
    }
}

两种设计都有效地完成了同样的事情。两者有什么实际区别吗?我何时会使用一个而不是另一个?感谢。

3 个答案:

答案 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;
    }
}