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

Java 所有静态方法还是单个实例?,java,static,instance,Java,Static,Instance,有时,由于集合的存在,我会想到一个类的单个实例就足够了。我的解码器类就是一个例子: public class Decoder { private static final Decoder instance = new Decoder(); private final HashMap<Client, State> states = new HashMap<Client, State>(); private 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;
    }
}
公共类解码器
{
私有静态最终解码器实例=新解码器();
private final HashMap states=new HashMap();
专用解码器()
{
}
公共数据包解码(客户端、字节缓冲数据)
{
返回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;
    }
}
公共类解码器
{
私有静态最终HashMap状态=新HashMap();
公共静态数据包解码(客户端、字节缓冲数据)
{
返回null;
}
}

两种设计有效地完成了相同的任务。这两者有实际区别吗?什么时候我会用一个而不是另一个?谢谢。

我认为在客户机类中编写代码时,使用静态方法更简单

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

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

我认为在客户机类中编写代码时,使用静态方法的时间更短

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

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

如果您想对使用
解码器
(或任何其他“实用工具”对象)的类进行单元测试,您可能需要模拟它-也就是说,用行为已知的虚拟对象替换
解码器
。这样,如果
解码器
类发生更改,单元测试就不会中断

如果
解码器
是一个实际对象,那么这将更容易实现。如果
解码器
是一个充满静态方法的类,那么您就不能轻松地对其进行模拟(尽管有模拟框架可以通过处理字节码来实现这一点)


简而言之,静态方法是一种可测试性反模式。我强烈建议不惜一切代价避免它们。如果你想阅读更多关于这方面的内容,试试看——在这个网站上还有很多关于可测试性的好建议。

如果你想对一个使用
解码器(或任何其他“实用程序”对象)的类进行单元测试,你可能想模仿它——也就是说,用一个行为已知的虚拟对象替换
解码器。这样,如果
解码器
类发生更改,单元测试就不会中断

如果
解码器
是一个实际对象,那么这将更容易实现。如果
解码器
是一个充满静态方法的类,那么您就不能轻松地对其进行模拟(尽管有模拟框架可以通过处理字节码来实现这一点)


简而言之,静态方法是一种可测试性反模式。我强烈建议不惜一切代价避免它们。如果你想了解更多关于这方面的信息,试试看——这个网站上还有很多关于可测试性的好建议。

我会使用所有静态方法,除非你认为需要实现一个接口,例如,这样你就可以模拟或替换你的实例

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;
    }
}
公共枚举解码器实现IDecoder{
实例;
私有最终映射状态=新HashMap();
公共数据包解码(客户端、字节缓冲数据){
返回null;
}
}

公共枚举解码器{;
私有静态最终映射状态=新HashMap();
公共静态数据包解码(客户端、字节缓冲数据){
返回null;
}
}

我将使用所有静态方法,除非您认为需要实现接口,例如,这样您就可以模拟或替换实例

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;
    }
}
公共枚举解码器实现IDecoder{
实例;
私有最终映射状态=新HashMap();
公共数据包解码(客户端、字节缓冲数据){
返回null;
}
}

公共枚举解码器{;
私有静态最终映射状态=新HashMap();
公共静态数据包解码(客户端、字节缓冲数据){
返回null;
}
}

这是一个重复的问题。所有这些都谈到了singleton在实现接口等方面是多么有用。我的场景不需要这样的功能。不过,谢谢你指出那些重复的问题。这是一个重复的问题。所有这些都谈到了singleton在实现接口等方面是多么有用。我的场景不需要这样的功能。不过,谢谢你指出那些重复的,我也是这么想的。静态方法比较短-你只需点击静态修饰符。这也是我的想法。静态方法较短-只需单击静态修改器即可。