Last week I was asked to answer a question about our code base and wound up with the wrong answer for what I think are interesting reasons. Thus, a few thoughts on the power of IDEs, the importance of coding standards, and a problem with the way Java handles accessor methods.
The application I work on queries an external datasource and then does stuff with the incoming data to provide a variety of results. I often get questions about how, exactly, we’re using that external data to make decisions. The incoming data is copied into Java classes which are persisted in the database using Hibernate.
My usual approach to answering these types of questions is to open Eclipse, find the appropriate accessor method for the value in question, and then use the fantastic “Find References” function to locate all the places in our code where we use that value. (It’s Command-Shift-G on your keyboard if you’re a Mac user.) If someone asked where a certain value originates, I start by pulling up all of the references to to the setter method. If someone asks how the value is being used, I find all of the references to the getter. Sometimes the sleuthing involves navigating through the code by finding a method that calls an accessor, then finding all the places that method is called, and so on.
For all of the hassle associated with building Java applications, the power of Java IDEs almost makes it worth it. I find it easy to be productive using TextMate to work on Ruby on Rails applications, but I always miss features like “Find References” and “Open Declaration” that are found in Eclipse. Eclipse, IntelliJ IDEA, and other Java IDEs build a semantic model of Java code that makes it very easy to manage your code that aren’t available when using other languages and editors. Any developer who’s avoided a bug because their IDE told them a local variable is never referenced anywhere knows exactly what I’m talking about.
Anyway, I had trouble figuring out how our code worked because I was investigating a feature written by another developer. The get method in question didn’t have any usages in our code base, and I assumed that while the value was being stored in the database, it was not incorporated into our business logic. I was asked to look again, and deeper inspection revealed that the member variable associated with the accessor I was searching for was accessed directly in other methods in its class.
When people talk about coding standards, this sort of thing is a bigger deal than bracket placement or tab size. My habit is to always use accessor methods if they’re available, whereas this other developer’s habit was to use the instance variables within the class. It’s probably better to do it one way or the other, or at least to have a clear understanding of why you might use one or the other in a given situation. The fact that we didn’t cost us a little wasted time, and could have been worse had I not reinvestigated and made sure that things were working as expected and not the way I thought they were.
This also underscores a drawback of the way Java handles accessor methods. Because accessors are regular methods, there are no easy ways to pull up all of the references to a particular variable that includes both references to the instance variable and to the accessors. It seems like Ruby accessors would lend themselves better to a more consistent approach. I’d also be curious to know whether the accessor implementation in C# leads to better tools.
February 1, 2011 at 4:13 pm
Rarely do searches go so easy for me. I’d start by finding references to the inst var, then fan out to find references to those things, which would include the setter method.
February 3, 2011 at 7:58 pm
I cannot tell you how many times I’ve done exactly what you describe, working backwards from a setter to figure out what a value is used for.
This is a HUGE and underappreciated advantage of Java relative to dynamic languages.
February 4, 2011 at 9:15 pm
C# auto-properties are not backed by a visible field, so it guarantees that they are only accessible via the getter. There is a “Find Usages” feature in Visual Studio, although it might be being provided by the Resharper plugin I’m using, I’m not clear on that.
Unfortunately auto-properties are not a complete replacement for field-backed properties, for instance, you can’t make a truly readonly (i.e. Java “final”) field with one, just one with a private setter.
In Java you can also get in trouble with “find usages” when interacting with JSPs that might contain expressions that reference properties by reflection.
I generally don’t bother with accessors until there is a reason for them, for codebases that are completely controlled (i.e. where you are not shipping code to 3rd parties). Binary compatibility is irrelevant. When you need the field encapsulated, do it and change every reference to it, boom, you’re done. There is no need to plan ahead if you control the whole codebase.
I like dynamic languages, but I don’t think I would start a large project in one now given the advantages in managing large codebases in strongly-typed languages in modern IDEs, especially reliable full-codebase search and refactoring tools.
On C# vs. Java, it would depend on the project – I would probably end up with Java given a free choice, partly because of useful it is to share code with GWT – but C# is very competitive.