Recently I started programming in Groovy for a integration testing framework, for a Java project. I use Intellij IDEA with Groovy plug-in and I am surprised to see as a warning for all the methods that are non-static and do not depend on any instance fields. In Java, however, this is not an issue (at least from IDE's point of view).Should all methods that do not depend onto any instance fields be transformed into static functions? If true, is this specific to Groovy or it is available for OOP in general? And why?
Make methods that do not depend on instance fields, static?
java;object oriented;groovy;static;instance
Note that IDEA has this inspection for Java as well, it is called Method may be 'static',This inspection reports any methods which may safely be made static. A method may be static if it doesn't reference any of its class' non static methods and non static fields and isn't overridden in a sub class...Thing is though that for Java code, this inspection is turned off by default (programmer can turn it on at their discretion). The reason for this is most likely that validity / usefulness of such an inspection could be challenged, based on a couple of quite authoritative sources.To start with, official Java tutorial is rather restrictive on when methods should be static:A common use for static methods is to access static fields.Given above, one could argue that turning on by default mentioned inspection doesn't comply with recommended use of static modifier in Java.Besides, there is a couple other sources that go as far as suggesting a judicious approach on using ideas that lie behind this inspection or even discouraging it.See for example Java World article - Mr. Happy Object teaches static methods:Any method that is independent of instance state is a candidate for being declared as static.Note that I say candidate for being declared as static. Even in the previous example nothing forces you to declare instances() as static. Declaring it as static just makes it more convenient to call since you do not need an instance to call the method. Sometimes you will have methods that don't seem to rely on instance state. You might not want to make these methods static. In fact you'll probably only want to declare them as static if you need to access them without an instance.Moreover, even though you can declare such a method as static, you might not want to because of the inheritance issues that it interjects into your design. Take a look at Effective Object-Oriented Design to see some of the issues that you will face...An article at Google testing blog even goes as far as claiming Static Methods are Death to Testability:Lets do a mental exercise. Suppose your application has nothing but static methods. (Yes, code like that is possible to write, it is called procedural programming.) Now imagine the call graph of that application. If you try to execute a leaf method, you will have no issue setting up its state, and asserting all of the corner cases. The reason is that a leaf method makes no further calls. As you move further away from the leaves and closer to the root main() method it will be harder and harder to set up the state in your test and harder to assert things. Many things will become impossible to assert. Your tests will get progressively larger. Once you reach the main() method you no longer have a unit-test (as your unit is the whole application) you now have a scenario test. Imagine that the application you are trying to test is a word processor. There is not much you can assert from the main method...Sometimes a static methods is a factory for other objects. This further exuberates the testing problem. In tests we rely on the fact that we can wire objects differently replacing important dependencies with mocks. Once a new operator is called we can not override the method with a sub-class. A caller of such a static factory is permanently bound to the concrete classes which the static factory method produced. In other words the damage of the static method is far beyond the static method itself. Butting object graph wiring and construction code into static method is extra bad, since object graph wiring is how we isolate things for testing...You see, given above it looks only natural that mentioned inspection is turned off by default for Java.IDE developers would have a really hard time explaining why they think it is so important as to set it on by default, against widely recognized recommendations and best practices.For Groovy, things are quite different. None of arguments listed above apply, particularly the one about testability, as explained eg in Mocking Static Methods in Groovy article at Javalobby:If the Groovy class you're testing makes calls a static method on another Groovy class, then you could use the ExpandoMetaClass which allows you to dynamically add methods, constructors, properties and static methods...This difference is likely why default setting for mentioned inspection is opposite in Groovy. While in Java default on would be source of users confusion, in Groovy, an opposite setting could confuse IDE users.Hey the method doesn't use instance fields, why didn't you warn me about it? That question would be easy to answer for Java (as explained above), but for Groovy, there is just no compelling explanation.