-1

I'm a fan of static methods in java for eg in Util-classes. But among some colleagues I have met some arguments that a static method should never use external resources. But none could explain why it should be bad or even dangerous. The only reason I have found is that it may be hard to mock that external resource during test. But is that really the only reason?

Below I got an example of a static method. I would love to understand why it should be a bad approach to use it with static.

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

Best regards

user2902165
  • 303
  • 2
  • 14
  • 1
    There is nothing wrong with static methods. It just depends on what you need. There are fantastic tools like apache common, actually StringUtils that has plenty of static methods. If you want to mock static things you can use Powermock. Anyway, this question seems sort of off topic to me since this is more like an opinion based thing. – Federico Piazza Oct 11 '17 at 19:16
  • 6
    `sendBytesMessage` is not marked `static` in your example code – Tom O. Oct 11 '17 at 19:16
  • 4
    Static methods make it hard (or impossible, if you don't want to use something like PowerMockito) to mock out the external resource in tests. Perhaps read [Static methods are death to testability](http://misko.hevery.com/2008/12/15/static-methods-are-death-to-testability/). – Andy Turner Oct 11 '17 at 19:17
  • 1
    "But is that really to only reason?" It's a *pretty big* reason. If you can't test your code without accessing the external resource, your tests either won't have been written, won't be run, or will depend on the state of the static resource. – Andy Turner Oct 11 '17 at 19:31
  • Possible duplicate of [Is using a lot of static methods a bad thing?](https://stackoverflow.com/questions/752758/is-using-a-lot-of-static-methods-a-bad-thing) –  Oct 11 '17 at 19:31
  • There is some business specific configuration in them. This leads to code copies for other uses. It makes sense to have all those magic properties in a declarative way, even if static packing is something I also tend to start with, till I have found a more reusable way. You still could make a business object, bean container and whatever to have a `sendBytesMessage`. – Joop Eggen Oct 11 '17 at 19:37

2 Answers2

0

consider two classes

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);
}

}

class Foo uses utility class, while class Bar uses class which implements Sender interface.

first, as you mention in your question, there is much easier to mock sender for testing purpose. otherwise you need to create infrastructure which can receive message to validate whole process.

Second thing, you are loosing possibility to abstract functionality. imagine situation where you need to change way how you sending message. In first case, you need to make modification in class which handles logic of your system. in second as you abstracted process of sending message, all what you need to do change in module responsible for bootstrapping your application. in some cases that change maybe done in your configuration file and done on live system

user902383
  • 8,420
  • 8
  • 43
  • 63
0

The main problem with static methods is that you can't easily change the implementation. Static methods cannot have interfaces.

This is bad for many reasons but let's focus on accessing external resources.

With static methods testability becomes a big problem. Either you need the external resource for tests OR you test "around" your static methods. If you had some MessageSender interface instead you could easily mock it in the test and only check if it was called as expected.

Then you may sometimes need to decorate access to external resources. For instance, if you have some look-up REST client you may later on decide to add caching to improve performance. This is much easier done with interfaces.

lexicore
  • 42,748
  • 17
  • 132
  • 221