//********************************************************************* //* Pattern name: MassiveFunctionHeaders * //* Pattern type: Anti * //* Because: * //* All imposed structure is inherently good, and to make up for * //* deficient tools (lack of on-demand versioning reports), and * //* because our ancestors did it that way, * //* Therefore: * //* Require that every function have a massive and elaborate * //* header. Extra points awarded for enclosing the whole thing in * //* a box of ASCII characters so that it looks pretty. * //* However: * //* Due to the high cost of creating and filling out massive head- * //* ers, impels programmers to add functionality to existing func- * //* tions rather than to add new functions. This causes overly * //* large functions. Hard to maintain (edit this example and get * //* the *'s to line up). The inventor of the header tends to * //* kitchen-sink it, so that every function has many empty fields * //* that are not carrying their weight. Many programmers do not * //* fill in even the fields that apply, "insert method description * //* here." All modern versioning tools will give you a version * //* history for a file. It is incredibly stupid to have to write * //* a description for a method called "extractSourceAddressFromMes- * //* sage." * //* Author: WayneConrad * //* Creation date: 2000-02-18 * //* Version: 0.06 * //* Version history: * //* 2000-02-18 wconrad Initial check-in * //* 2002-05-16 tholenst Adjustment of header * //* 2002-06-13 cwillu Corrected above adjustment (missing '*') * //* 2002-06-16 gkalnins fixing version number and date format * //* 2003-09-07 kknechtel Adjustment of version history * //* 2003-10-13 kpanko bug fix change of unclear nature * //* 2010-09-11 bungalo justified and hyphenated with TeX * //*********************************************************************
Couldn't agree more that this is a disgusting practice, especially if you throw in documenting all callers/callees of the function. One thing that's interesting to note though is that sometimes people use formatting conventions which look cumbersome to the casual observer, but are, in fact, well supported in the author's editor of choice. Examples are aligning all the = signs in initialized variable declarations, aligning inline comments at a certain column, etc. -- LukeGorrie
I once worked on a project where you had to add this huge comment template to the front of every function. The net result was that people would pile more and more code into a single function. They were reluctant to start a new function.
I complained to my ProjectManager that this was leading to bad code. We came up with a compromise - the small function header - a lightweight template for small functions. Result: happier engineers and more code reuse. -- AlastairRae?
Another war story. One company I worked for required a function header for every function in the corporate coding standard. The result was the header template was dutifully copied and place in front of every function. The template was rarely filled in; a vast majority of the function headers were merely the empty template, but we could claim compliance.
JavaDoc comments suffer from redundant noise also. Have you ever seen nonsense like this?
/** Extract the address from the message. @param message The message @return The address */ String extractAddressFromMessage (Message message)Noise. Lots of noise. -- WayneConrad
I've always found that you need to play that game with javadoc, because your documentation output ends up looking ugly if you don't state the obvious. I'm guilty of writing horribly redundant stuff like that in classes that I expect to be very user-visible. -- LukeGorrie
As a C/C++ programmer, I've always wondered about JavaDoc. It seems to require a lot of work to recreate the header files that were so reviled in C. With modern IDEs that can pull function declarations directly from the source code, I do not see the continued value of either C header files nor of JavaDoc inline header commands.
See JavaDocBreaksOnceAndOnlyOnce.
As always, if you need a comment, the code isn't sufficiently simple enough. Corollary: If you don't understand it without a comment, I won't understand it at all. Function headers were/are mandated because the system spiraled out of control. People wanted to know callers and callees and side effects because they lost track of what was going on. So, they didn't understand the code that they themselves wrote. Their solution was to comment more. It doesn't help. A better solution would have been to simplify the code. -- SunirShah
Even though using MassiveFunctionHeaders is a bad idea, SmallFunctionHeaders may be necessary. Simplifying the code is a good idea for inline comments, but I have still not found any code that is simple enough to understand at high level without comments.
Why should code be not understandable without comments? I have found it to be quite true that comments, documenting workarounds due to bad APIs from third party software, are an indicator of code that needs improvement. Even SmallFunctionHeaders get in the way of creating small functions (a necessity in eliminating comments). -- WayneMack
I remove all code too, because it is often wrong and therefore I can't trust it. Much cleaner result.
But when the code is wrong, it will become evident through a bug or a failed unit test. You know what to fix. An incorrect comment is noise at best, and misleading at worst. I'd reserve comments expressly for when a piece of code does not do what it seems to (due to a bad API, or what have you). -- WilliamUnderwood
(see CommentingChallengeResponse)
As always, if you need a comment, the code isn't sufficiently simple enough.
When you write a function header to document your function, keeping in mind that the probable user is someone who never took part in the development, you should not explain why the code does, but how to use it. Then you never write extra stuff. Example:
If the class was found using the above steps, and the resolve flag is true, this method will then invoke the resolveClass(Class) method on the resulting Class object.The good point of this example is that the resolve flag is an argument of the method. The bad point is that it explains it in the Method's Javadoc, leaving the param tag to:
@param resolve If true then resolve the class-- TiagoSilveira
DocumentCodeBeforeYouWriteIt? SeparateCodeAndDocumentation? IsTheOriginalProgrammerResponsibleForMaintainableCode
See also SmallFunctionHeaders
CategoryAntiPattern CategoryCodingIssues CategoryDocumentation