Java – Static Methods

I currently work in a code base where static “utility” methods are used fairly often.  This probably stems from the legacy of the code base.  Back when the company was just getting started, there were only a couple of developers (including myself).  While we all knew how to write Java code (syntax), none of us knew how to write good Java code (Object Oriented, encapsulated objects, etc.).  So we wrote a bunch of static utility methods trying to keep the code clean.

Ten years later, I’m still with the company (as are 2 of the other 3 original developers) and we are still working in the same code base.  The company has grown steadily and there has never been available resources to take on a whole system re-write.

The original code from 10 years ago isn’t the only problem.  The development team has grown significantly over the years as well.  Most of the team consists of developers that have very little experience in Object Oriented Java before joining our team.  So they tend to use the existing code as an example of how to write new code, which means more static utility methods and the cycle continues.

So what’s wrong with Static Methods?

If used in the right context, there is nothing wrong with them.  But using them to often or in the wrong places has several issues.

Automated Unit Testing

Static methods make implementing automated unit testing very difficult.  There is no easy way to stub out the methods.  There isn’t an interface to program to, and you can’t use polymorphism to override the static method to return a specific result for testing.  So when writing unit tests on code that uses static methods, you end up testing the not only the code in the method you are trying to test, but the code in the static method(s) as well.  This is often the biggest reason given for not using static methods.  The company I work for doesn’t use automated unit testing (I’ll post about that another day), so this doesn’t work as a reason not to use them for us.

Object Oriented

Static methods do not extend any other class or methods and cannot be extended.  So the code in them can not be reused – unless it does exactly what you need it to do already. Static methods are not Object Oriented in anyway. I’m not saying they can’t be utilized in OO code, just that they themselves are not.

Readability

Static Methods alone don’t make for hard to read code, If they are over used or the class or method name is long it can certainly detract from readability:

// Harder to read
User user = new User(StringUtility.removeSpecialCharacters(firstname), StringUtility.removeSpecialCharacters(lastname));

// Easier to read
User user = new User(firstname.removeSpecialCharacters(), lastname.removeSpecialCharacters());

Passing the same object to multiple static methods to have it just return the same object (with modified data/state) quickly becomes difficult and tedious to read.

// Harder to read
order = CartUtility.calculateTaxes(order, billingState);
order = CartUtility.calculateOrderTotal(order)
print("OrderTotal:" + order.getOrderTotal());

// Much easier to read
order.calculateTaxes(); //better yet, make this part of calculateOrderTotal()
print(“OrderTotal:” + order.calculateOrderTotal());

So when SHOULD I use a static method?
You should use a static method if (and only if) ALL the following are true:

You are writing utility class and they are not supposed to be changed.
The method is not using any instance variable.
You aren’t passing in a parameter and getting the same object returned. Generally this means the method should be put in the object you are passing/returning.
It just doesn’t make sense to create them as instance methods for some reason.
You are sure that the definition of the method will never be changed or overridden.

What are your thoughts? Leave a comment below and let us know

Advertisements

// TODO: Add comments?

// My story

When I went to college I was taught that commenting my code was a “good thing”.  Comments help you understand your code when you come back to it, and also make it easier for others to understand what the code does.

While in college, I never really saw the benefit of the comments, since all of our projects were of the variety of write it, get a grade, and throw it away.  But still, I diligently commented my code, partially because it was part of my grade, but also because it was a best practice.

For many years I worked in companies that had different rules around comments in the code.  Often there was a large comment block at the top of each class explaining what the class was, and how it was to be used, as well as a log of who changed it, when and why.  At one such company, the build would throw a warning when these comments were missing.  So, in an effort to reduce the number of build warnings, I started going through the code adding comments where the build complained.  I made a huge impact on the number of warnings…but I’m not sure I did anything to actually improve the quality of the code with that effort.

Then, I started at a company where the developers didn’t believe in comments.  At first I was surprised by this practice.  Then, I was excited because I had a growing sense that these massive comment blocks at the top of classes were pretty useless anyway.

As I continued to work with these developers, I found I didn’t need to leave comments when I paid attention to how the code was written.  I could often understand, even months or years later, what the code was doing given the method and variable names, and the associated tests.  In our considerable code base, we only had a handful of comments.

I now fall into the “comments are a code smell” camp, though I am likely not as extreme as some others, I try to avoid commenting as much as possible.  I am much more likely to refactor a piece of code to make it more readable than to add a comment.  And, if I find comments in the code telling me what a snippet of code does, I am likely to remove it!

// When to use comments

As I said above, I don’t believe in commenting my code.  However, there are times when comments are necessary (or at least useful).

You may be asking “How do I decide whether I should add a comment or not?  What types of comments do I leave?”.  There are only a few situations where I add comments to my code.
1) If I am using a third party library that is either a) complex, or b) doesn’t work as expected, I will add a comment explaining why the code is written the way it is.
2) If I am writing code that I just can’t seem to find a good way to refactor into self-explanatory code, I will add comment explaining what the code does (I really try to avoid explaining what), and why it is written this way.
3) If I am writing any type of library code that others will be using rather blindly, then I believe good comments (Javadoc) are essential to allow the user to understand how to use the code.
4) If there is a piece of code that has to be written in a not so obvious manner because of reasons not readily apparent in the class, I will comment why the code is written as is.

// Commenting out code

Don’t even get me started on commented out lines of code.  If I see them, I delete them…no questions asked.  Source control will allow you to get them back if you need them.

// Your Comments?

What is your stance on comments in code?  Are there other scenarios that you feel deserve comments?  Have you never seen code with well named methods and variables so you didn’t need to read the comments to figure out what it was doing?