为什么不使用静态方法来处理外部资源?
问题描述:
我是Java中静态方法的粉丝,例如在Util-classes中。但在一些同事中,我遇到过一些静态方法不应该使用外部资源的论点。但没有人能解释为什么它应该是坏的甚至是危险的。我发现的唯一原因是在测试过程中可能很难嘲笑外部资源。但是,这真的是唯一的原因吗?为什么不使用静态方法来处理外部资源?
下面我有一个静态方法的例子。我想知道为什么它应该是一个不好的方法来使用它与静态。
public class JmsUtil {
public static String sendBytesMessage(byte[] messageBytes) throws JMSException, NamingException {
String jmsMessageID = null;
Connection connection = null;
try {
Context context = new InitialContext();
ConnectionFactory connectionFactory = (ConnectionFactory) context.lookup("ourfactory");
Queue queue = (Queue) context.lookup("ourqueue");
connection = connectionFactory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer messageProducer = session.createProducer(queue);
BytesMessage bytesMessage = session.createBytesMessage();
bytesMessage.writeBytes(messageBytes);
messageProducer.send(bytesMessage);
jmsMessageID = bytesMessage.getJMSMessageID();
} finally {
if (connection != null) {
connection.close();
}
}
return jmsMessageID;
}
}
问候
答
考虑两类
class Foo extends Blob{
public void someMethod(){
byte[] message = createMessage();
JmsUtil.sendBytesMessage(message);
}
}
class Bar extends Blob{
Sender sender;
public void someMethod(){
byte[] message = createMessage();
sender.sendBytesMessage(message);
}
}
类Foo
使用实用工具类,而Bar类使用类,它实现Sender
接口。首先,正如你在你的问题中提到的那样,为了测试目的而嘲笑发送者更容易。否则您需要创建可以接收消息来验证整个过程的基础结构。
第二件事,你失去了抽象功能的可能性。想象你需要改变发送消息的方式。在第一种情况下,您需要在处理系统逻辑的类中进行修改。在您抽象发送消息的过程中,所有您需要在模块中进行的更改负责引导您的应用程序。在某些情况下,可能会在配置文件中完成更改并在实时系统上完成
答
静态方法的主要问题是您无法轻松更改实现。静态方法不能有接口。
这很糟糕,原因很多,但让我们专注于访问外部资源。
随着静态方法的可测试性成为一个大问题。无论您需要外部资源进行测试,还是测试“围绕”您的静态方法。如果你有一些MessageSender
接口,你可以轻松地在测试中嘲笑它,只检查它是否按预期调用。
然后你可能有时需要修饰对外部资源的访问。例如,如果您有一些查找REST客户端,您稍后可能会决定添加缓存以提高性能。这通过接口更容易完成。
静态方法没有错。这取决于你需要什么。有很多很棒的工具,比如apache common,实际上有很多静态方法的StringUtils。如果你想嘲笑静态的东西,你可以使用Powermock。无论如何,这个问题对我来说似乎有些偏离主题,因为这更像是一个基于意见的事情。 –
在您的示例代码中'sendBytesMessage'没有标记为'static' – tommyO
静态方法使得在测试中模拟出外部资源变得困难(或不可能,如果您不想使用类似PowerMockito的东西)。也许阅读[静态方法是可测试性的死亡](http://misko.hevery.com/2008/12/15/static-methods-are-death-to-testability/)。 “ –