Java static methods can be a code smell

Definition of code smell (from Wikipedia):



“any symptom in the source code of a program that possibly indicates a deeper problem.”

In Java,
static methods allow you to execute code at a “class scope” as opposed to an instance scope like member methods. This means, they rely on class-level variables (if any), parameters passed to the static method, or any other globally accessible data. They are NOT object oriented. An object has state associated with it and can be manipulated only through methods that implement the object’s “behavior.” Static methods do not operate on state, they are not object oriented, and in fact they are procedural.

Is this bad?

No. Although Java is object oriented, there will be times when procedural-like programming in Java is necessary and/or preferred. The real power in any object-oriented language is the ability to closely implement a model of real-life systems in code (see my
post about object-oriented modeling). But even in the most hard-core object models, there will mostly likely be some glue code, or infrastructure code that will be implemented in a procedural style.

So if procedural-like programming in Java isn’t “that bad” and static methods are a form of procedural programming, are static methods bad?

Ahh… the answer isn’t as simple as a “yes”, or a “no” regardless of what you may read on other blogs But I could probably ramble on and on about why it’s really a decision that has to be made in context, so let’s keep this article focused by examining a set of statements that I encountered in
“How to Mock Static Methods” from Michael Minella’s blog:

“Something that has become a fundimental [sic] piece of the language (all you need to do is look at the Apache Commons project to see that) is so bad that it must be avoided at all costs in the name of testing. Gosling (or someone on his team) put it in the language for a reason and to avoid those uses solely because your toolset doesn’t support the testing of it is nonsense. Time to get a new toolset.”

First, I’d like to point out that just because something has become a fundamental piece of a language doesn’t mean it’s “good” or something that should be done. Take a look at
checked exceptions for reference. I recall EJB 1.x and 2.x becoming a “fundamental” piece of Java EE in the past, so look at that for reference too.

Second, although I do agree with Michael in theory that avoiding a particular language feature because your tools don’t support it is silly, his premise is focused on static methods. Avoiding static methods because your tooling doesn’t support them is NOT nonsense at all. In fact, the type of impedance caused by some of the good testing and/or mocking frameworks (of which
Mockito is my favorite
:) ) and static methods can be confidently identified as a code smell. This does not mean we should not do it, but we should exert extra effort to understand why we are doing it and explore alternatives if there are “deeper problems.”

There are at least two types of static methods that I would like to point out don’t usually show much impedance with testing/mocking frameworks. The first type is static methods used as utility methods, as those found in a lot of the
apache commons libraries, or your own internal commons libraries. These are usually routines that are supportive of a particular method’s objective, and mocking/stubbing them out of a unit test wouldn’t make sense. They are part of the implementation, and should be tested as such. The second type is static methods used in place of constructors as Joshua Bloch showed in his book
“Effective Java.” This use of static methods allows you to construct a new object using a method with a very descriptive name, among some other advantages. An offshoot of this second type of static method could include factory methods, but that would depend on context.

The most glaring code smell as a result of static methods and testing-framework impedance arises when a unit relies on a static method that performs logic outside the scope of the responsibility of that unit. In these cases, your testing framework will fight you because you cannot stub/mock the out-of-scope logic because it is “hardcoded” via a static method. This can be considered a “deeper problem” and is the focus of most blogs that tell you not to use static methods because testing becomes abnormally difficult or impossible. Changing the design approach to follow the Dependency Inversion Principle is one alternative. A better understanding of how to test the unit is yet another.

I assert strongly that in the case of static methods, the push-back you may get from your testing frameworks is indicative of a code smell, not that you need to try and find a framework that uses complex trickery with class loader remapping as a solution. One should be poised to evaluate the use and fundamental drawbacks of a particular approach in their design. Michael’s blog entry lends the reader to too easily assume a new tool/framework just because Java supports static methods and your current testing frameworks illuminate an impedance — in this case, the impedance reflects a code smell and some deeper, more critical thinking is required.


Reference:
Java static methods can be a code smell from our
JCG partner Christian Posta at the
Christian Posta Software blog.

Source : http://www.javacodegeeks.com/2012/05/java-static-methods-can-be-code-smell.html

Code comments gone wrong

Adding code comments is supposed to be good practice, but here is why it often fails:
  • Code is the single authoritative source of truth in a program!
  • There is no way to ensure that code comments are correct at all times (not always updated as code changes).
  • Comments are written in human language which can be prone to misinterpretation.
First put your good intentions into writing simple and readable code.


Write self descriptive code ! Your code should be read like sentences. Avoid smart shortcuts and tricks because they break the reading. Expect the reader to have solid programming knowledge but no knowledge about the purpose of your code. If code is too compact add extra code steps to document it, for example:
...
final Person dummyPerson = new Person("Joe", "Bloggs");
return dummyPerson;
Instead of using a comment:
...
// Return dummy person.
return new Person("Joe", "Blogs");
Ok ok, this example was a bit silly but you got the idea.

Using long names is considered bad practice, I disagree. Prefer using long explicit names over short meaningless names which require code comments. Sometimes long names are really annoying, for example when they keep appearing everywhere in some algorithm, in that case you could use a comment.

Consider using more columns:

The default max of 80 columns is terrible, use a wide screen and use 120 columns or more, the code will be more readable because long lines will not wrap anymore and you can use longer more explicit names.

Use assertions to document pre and post conditions instead of lengthy comments.
public List<String> listFiles(final String folderUrl) {
assert folderUrl!= null;
assert folderUrl.endsWith("/");
  ...
}
If you write an API a good documentation is necessary but for internal code I think comments should not replace good naming and code clarity. I use code comments when the code is not really self documenting. Comments should convey what code cannot. They should explain the reasons for a specific design decision, they should explain what code is supposed to achieve and why.

Learn how to use the Javadoc, it not only looks better, it can also help automatically update some documentation. When referring to code try using the link tag. Your IDE may automatically update the linked method and class names during renaming which ensures that some of your documentation stays up to date.
/**
* Use the link tag: {@link SomeClass#someMethod}
*/
Links:


Reference:
Code comments gone wrong from our
JCG partner Christophe Roussy at the
Javarizon blog.

Source : http://www.javacodegeeks.com/2012/05/code-comments-gone-wrong.html