I often agree with Jeff Atwood and what he writes in his Coding Horror blog, but I thought I was going to disagree strongly with him when I saw one of his posts titled The Problem with Code Folding. After reading it, it turns out that we don't disagree as much as we each have a different focus on code folding. He warns against using it for many things related to actual executable code (which I agree with), but I have found code folding to be highly useful in cases on non-executable code that I don't need to be burdened with when reviewing and maintaining code.
I agree that we all need to give and take a little in our software development teams. However, there are situations when the team is split roughly 50/50 on what is the best approach. Rather than irritate half the team every time they look at the code just because one approach is arbitrarily chosen, code folding can often help everyone be happier. In this blog entry, I will attempt to outline some of these cases and use NetBeans 6.1 code folding to illustrate. I'm going to try to not state which side of these issues I prefer and instead focus on how code folding allows both sides to be happier. This does not mean I don't have a preference.
One area of disagreement that can be easily handled with code folding is the specification of Java classes and interfaces to be imported. One school of thought holds that all imported classes and interfaces should be individually and explicitly imported while the other school of thought maintains that the entire package should be imported using the asterisk. The Java Tutorials section Using Package Members suggests that explicit imports are okay if only a small number of classes and/or interfaces in a given package are needed, but that the asterisk should be used to include the entire package if several members of that package are needed.
NetBeans provides automatic code folding for import statements. The advantage of automatic IDE-provided code folding is that the code is not touched in anyway and the code has nothing in it specific to code folding. The following three screen snapshots (taken from my recent EasyMBean blog example) demonstrate NetBeans 6.1's automatic import statement code folding in action. The first image shows an example piece of code with the import statements expanded as one would normally see them in any text editor. The second image shows these same import statements collapsed (by clicking on the minus sign to the left of the first import) and the third image shows them still collapsed, but shows the preview that is shown if the mouse cursor is moved over the collapsed marking (. . . ).
Import Statements Shown Normally (or Expanded)
Import Statements Collapsed
Import Statements Collapsed with Preview of Collapsed Content
The above code folding of import statements is obtained in NetBeans without any additional effort from the developer and can allow the team to have explicit and individually specified classes and interfaces without irritating those who see those as extraneous or cumbersome for their normal daily needs. Because it is automatic in NetBeans, there is no trace of any special treatment of important statements in the source code. Anyone looking at the source code in an alternate editor that doesn't itself fold import statements will just see the lines of code like shown next:
package dustin.jmx.modelmbeans;
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import org.jmanage.easymbean.EasyMBean;
Another area of controversy among experienced and highly skilled software developers is the appropriate level of commenting. In truth, this is almost as much art (and personal opinion) as science, but I think most of us can agree that the more readable the code is, the less commenting is often needed. As is often cited, comments are sometimes used as the deodorant for smelly code. Note also that there are different types of comments. For example, Javadoc comments are often very different animals from inline comments within methods.
NetBeans offers automatic code folding for Javadoc comments similar to what it provides for import statements. I will again use the example code from my EasyMBean blog example to illustrate NetBeans's code folding of Javadoc comments. The next two screen snapshots show a class-level Javadoc comment and a method-level Javadoc comment expanded (normal/default) in the first image and collapsed in the second image. Note that control of the Javadoc comments is separate; I just happened to have both open for one snapshot and both closed for the other.
Javadoc Comments Expanded
Javadoc Comments Collapsed
I did not show a preview screen snapshot with collapsed Javadoc comments. This works just as I showed it working for import statements. Without expanding the collapsed Javadoc comments, I can move my mouse cursor over the collapsed Javadoc comments section in NetBeans and see a preview of what is being collapsed.
You may have noticed that even in the screen snapshot in which the Javadoc comments were closed, there was a minus sign icon for collapsing (code folding) the method itself. Use of code folding to hide a method as can be done with that icon is definitely not something I'd choose to do often. This is where I agree with many of Jeff Atwood's assertions in The Problem with Code Folding. I don't mind it as provided by NetBeans automatically because it doesn't change the code at all (NetBeans implements these code folding sections without any special demarcation in the code) and the code is expanded by default. I might occasionally find it helpful to collapse a method to better focus on what's going on, but I generally favor having executable code viewable by default. Because of this opinion, I won't be demonstrating method collapsing. However, it works similarly to the collapsing already shown of import statement sections and Javadoc comment sections.
So far, the NetBeans code folding examples have demonstrated the type of code folding that I prefer and that is my first choice when available and sufficient. This automatic and implicit code folding does not require any effort by the developer and do not in any way adulterate the source code.
The next example of NetBeans code folding that I will demonstrate is the NetBeans wizard-generated servlet code folding. This code folding is automatically added by NetBeans, but the servlet code folding differs from the previous code folding examples because it does rely on explicit code folding comments in the source code. The next screen snapshot shows what the servlet looks like immediately after being generated with NetBeans's servlet wizard.
If the developer clicks on the + icon to expand the collapsed servlet code, he or she sees something like this:
// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
/**
* Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Returns a short description of the servlet.
*/
public String getServletInfo() {
return "Short description";
}// </editor-fold>
The code that was collapsed by default after the servlet wizard was run are the three standard methods expected of servlets. The
doGet
and doPost
methods are not all that interesting because all they do is turn around and call the processRequest
method. The collapsed getServletInfo
method is slightly more interesting, but would also not be too interesting once a useful string was set to be returned from the method.The servlet wizard example provides a taste of another class of NetBeans code folding where NetBeans automatically generates the code folding, but it requires explicit comments to be placed in the code to perform the code folding. These commented-out lines will be ignored by other editors, but will be respected by NetBeans. Another example of this was present in my blog entry on Using Orson Charts to Extend JConsole, in which I used the NetBeans GUI editor to create code and that code was placed (by NetBeans) within code folding comments.
All of the previous code folding examples were automatically provided by NetBeans where code had to be changed or not to perform the code folding. The third class of NetBeans code folding is customized code folding where the developer marks sections of code that he or she wants to support NetBeans code folding. The last example of the servlet generation showed the syntax that developers can use to implement custom folding. As shown in the servlet example and as described in Custom Code Folding in NetBeans, one can add custom code folding in NetBeans simply be enclosing the code to be folded within
// <editor-fold>
and // </editor-fold>
comments.Custom code folding allows the developer to be more selective in which types of code are folder. This can be a nice advantage, but can also be a problem if used indiscriminately. The situation in which I think that custom code folding is most desirable is when things not directly related to the successful execution of the code is included within the code. The primary way this can happen is via comments and via annotations.
There are times when developers may choose to or be forced to include comments and/or annotations in their code that are not required to successfully execute the code. Examples of such situations include the decision to include requirements in the code, to include contact or other personnel information in the code, or to include architectural or other high-level software characteristics in the code. Often, a client or management wants this additional non-executing code included for various reasons that may not be at all related to the successful execution of the code itself. Code folding can be used to keep such metadata in the code, but remove the non-executing metadata from the developer's view when using NetBeans. In other words, code folding allows this non-executing code to be removed as a distraction without actually removing it from the code.
In the previous screen snapshot, I showed Javadoc commented out. However, there were regular (not Javadoc) comments within the method
processRequest
that were still visible. These are actually working servlet code lines generated by NetBeans servlet generation wizard, but they are commented out. It is easy to fold or collapse these lines by adding the comments before and after that indicate code folding as shown in the next code listing.
try {
//<editor-fold defaultstate="collapsed" desc="Generated code">
/* TODO output your page here
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet FakeServlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Servlet FakeServlet at " + request.getContextPath () + "</h1>");
out.println("</body>");
out.println("</html>");
*/
//</editor-fold>
} finally {
out.close();
}
The code now looks like this in NetBeans:
This shows that any types of comments could be easily folded out of the current NetBeans view. This might be useful for verbose comments providing background, history, requirement, or details that are often not desirable when editing code. The one major issue with this, however, is the increased tendency for comments to become obsolete or even outright wrong compared to the actual code. This is because it is difficult enough remembering to keep comments current with code changes even when they're right there in front of you and hiding them only makes that maintenance that much more difficult. This is one of the arguments for "less commenting is better," but that is not always a choice.
Annotations are sometimes used where they arguably should not be used, including being used as "processable comments" (not much more than comments except that a third-party piece of software can process them easily and mine them for comment information that would be more difficult to parse out of actual comments). In such cases, the annotations might have nothing to do with the execution of the code and so most developers will benefit from folding these out of their normal NetBeans view. For example if some custom annotations were used to associate methods with certain business requirements, the developer might enclose the requirements annotations within commented lines
//<editor-fold defaultstate="collapsed" desc="Requirements Annotations">
and </editor-fold>
. Code folding can lead to problems when applied indiscriminately. However, there are many advantages to be gained from carefully chosen, effective code folding. Code folding has the least downside when it is automatically generated on-the-fly by the IDE without any impact to the code. Code folding is arguably most dangerous when it is custom code folding, but this can also sometimes provides its greatest value when used carefully.
Developers are not always fortunate enough to work with code as clean as they'd like. Code folding can be used to hide away some of the most distracting non-executing code to make the executable code a little easier to read and maintain.
1 comment:
Good post on an unusual topic. I'd like to point out that the reason we would want code folding, is that of raising the abstraction level - not be burdened with unnecessary detail. The reason Java and C# editors have it is to fold away part of the AST context which is rarely interesting. When we have better (AST based rather than flat file based) editors, we won't need folding at all.
Also, note that many people in the C# world prefers to let the language handle this rather than the tool. In C#, with its partial classes, you can have auto-generated code (i.e. UI or web service stuff) in a separate file than where you would be adding logic. Unfortunately Java is not very flexible in this regard.
Post a Comment