![]() Psychedelic Panorama of FooÁ¦ À̸§ÀÌ Inigo Montoya ÀÔ´Ï´Ù. ´ç½ÅÀÌ ³» ¾Æ¹öÁö¸¦ Á׿´¾î. Á×À» ÁغñÇØ.Åä¿äÀÏ, 3¿ù 15, 2008Comments in OO Java Software¾Æ³çÇϼ¼¿ä. I qualified OO in the title of the blog because there are some weirdos that have it in their mind to use Java for Functional, Declarative, or even Logic Programming. There are a lot of differing opinions on how to handle comments in Java. I am writing this to outline my experience of best practices in this area. Not that my experience is better than anyone else's, but I think it's at least worth putting out there for others to respond to and perhaps even be enlightened by. In "The Elements of Java Style," there are 3 basic types of comments for Java. These are documentation comments, C-style comments, and one-line/in-line comments. There are several camps that developers fall into regarding the one-line/in-line comments. I happen to belong to the camp that declares, "If there are comments, then the code needs to be refactored so they are not needed." Many disagree with that. Two major camps that disagree with this are the ones that declare, "Domain-specific intrinsics of the code should be commented for those unfamiliar with the domain." and "Anything that isn't obvious about the code, should be commented." The 3 camps seem to make sense to some degree. I will stick to my guns though. I'll address each of the other camps. If there are some "domain-specific" intrinsics in code, then there still shouldn't be a comment. I follow many best practices of Martin Fowler's Refactoring. Suppose we have a section of code:
public void paint(Canvas canvas) {
. . .
. . .
// Always clear whiteboard canvases before painting because we know the canvas is reused.
if (canvas instanceof WhiteBoardCanvas) {
canvas.clear();
}
canvas.paint();
. . .
. . .
}
A very useful comment. No one would know why the clear() method is being called without that comment unless they were familiar with the domain. How do we refactor this code, so it still works, but we don't lose the documentation?
public void paint(Canvas canvas) {
. . .
. . .
prepare(canvas);
canvas.paint();
. . .
. . .
}
/**
* Handle the preparation of the <code>{#link Canvas}</code> for painting. <br/>
* <br/>
* If the <code>{#link Canvas}</code> is a <code>{#link WhiteBoardCanvas}</code> instance, clear it before painting because
* we know the canvas is reused.
*
* @param canvas to prepare and work on.
*/
public void prepare(Canvas canvas) {
if (canvas instanceof WhiteBoardCanvas) {
canvas.clear();
}
}
Notice that the domain-specific comments are all well documented within the context of what they are doing. We took care of two-refactorings in one this way. One piece of functionality that should have been extracted into its own method was, and it was properly explained and documented for the applicable domain. This is usually the case in situations where one is tempted to leave a one-line comment for the domain. I think the developer would usually find that if that piece of functionality were properly extracted into its own method, then it could be handled properly with a documentation comment rather than a one-line comment.
public void someMethod() {
. . .
. . .
// Building log message with StringBuffer because '+' is inefficient
StringBuffer buffer = new StringBuffer().append("Log Message: ").append(" trace data - ").append(this.toString());
log(buffer.toString());
. . .
. . .
}
Again, a very useful comment. Who knew that '+' was inefficient?
public void someMethod() {
. . .
. . .
log(logMessage(" trace - data ", this.toString()));
. . .
. . .
}
/**
* Creates a log message with a prefix. '+' is an inefficient way to append strings. A StringBuffer is created along with each string. Then the append() method is called to do the appending.
* Rather than creating a lot of objects that are just going to get thrown away, this method creates a single StringBuffer instance and appends strings from the method parameters.
*
* @param params varargs String parameters for the log message.
*/
public String logMessage(String ... params) {
StringBuffer buffer = new StringBuffer("Log Message: ");
for (String param : params) {
retval.append(param);
}
return buffer.toString();
}
Same as before. Two refactorings in one! Not only did we do that, but it turns out the documentation comment was even more useful than the one-liner. Again, if there is a one-line comment, it's a bad smell without question. There's already the possibility of two refactorings. All you have to do is imagine that one-line or C-style comment as a documentation comment. Also, imagine that section of code you want to devote a comment to as its very own method. If you run into a case where the section of code already is its own method, then you already know you don't need a one-line comment, but a documentation comment. To top it off, I will outline the advantages of documentation comments vs. one-line comments.
·¹À̺í: java, programming, software |
