Practical
Embedded Java

Document Your Code!


A practical engineering approach to using embedded Java in real-world applications.


...



Undocumented code is difficult (or impossible) to understand, unusable, and unmaintainable. Yet programmers (who should know better) continue to write such code. Stop, already! There's more than enough awful code in the world. Don't add to it.

Some CE4710 students recently asked "but isn't the most important thing that the code works? Would you rather have code that works well, or code that is well documented?" They are astonished when I reply "I'd rather have well documented code -- then at least I can get a good programmer to fix it, if necessary. If it's not documented, even a good programmer will throw up his hands in disgust and would rather start over".


Why document?

Download code from SourceForge or other open source repositories and you will be lucky if it includes pre-made or easily recreated javadocs. In fact, the amount of code I see which is completely lacking meaningful comments is astonishing. As Cicero said: "It is doubtful whether a man ever brings his faculties to bear with their full force on a subject until he writes upon it." So if you want your code to be half-baked, buggy, and generally unusable, by all means, don't waste your time thinking about it too much.On the other hand, if you are proud of what you are writing, and want your code to be robust, usable, and maintainable, then ponder these reasons why and how you should document what you write:

  1. The act of writing documentation forces you to think about what you are programming. This should be a good thing, right?
  2. Write the documentation first, then write the code to implement it. Lay out your class structures, fields and methods with empty stubs, and descriptive comments. Generate javadocs and see if it makes sense before you spend hours writing what later turns out to be less-than-optimal code. It's far better to encounter logical problems early on than in a painful debug-and-rewrite session later.
  3. If you don't have time to write the documentation, you don't have time to write the code. Really. Come back later when you have time to do it right. Put another way, "if you don't have time to do it right, do you have time to do it over"? The answer to this, 99% of the time, is "no". Quick and dirty is forever [kendall].
  4. I've never seen well-documented, crappy code, ever. I've seen code which works well and is undocumented, but never code which is well documented and works poorly. Perhaps Cicero was right.
  5. It just doesn't work to go back and write the documentation later. You won't remember all the reasons you wrote things the way you did, and once the code is working you won't be highly motivated to revisit it. Attempting to write documentation later is much less efficient, too. You have to get your head around all the intricacies again, and, unless you are writing or debugging at the time, this is very difficult. For these reasons, too, if you discover what appear to be problems during a post-documentation episode, you will be reluctant to make changes. You'll be afraid that you don't understand all the side-effects of changes, and -- guess what -- there aren't good documents in your code to help! Catch-22. Besides, the code may already be frozen, released, or tossed over the fence to another group, so it may be too late.
  6. Documentation must be living and it must be kept in sync with the code. Incorrect or misleading documentation is actually worse than no documentation since it actively interferes with your attempt to understand the code and can lead you down the wrong thought or maintenance path. This is why you must write the documentation at the same time as the code, and you must update it every time you change the code. No exceptions! The penalty in wasted time (yours and others) is just too high to ignore this advice. Waste half a day or a weekend banging your head against this and you will become a believer (or a masochist).
  7. How about self-defense? Do you really want 10/100/1000 users of your code asking you the same questions via email or phone, when you could have spent a fraction of that support time pre-emptively answering such questions in the documentation?
  8. Your own sanity is at stake. Would you rather leave yourself a "trail of breadcrumbs" now, while the code is fresh in your mind, or would you rather rack your brains six or twelve months from now when you are asked to add another feature or (heaven forbid) fix some subtle bug? I don't know about you, but after a year I don't even recognize code I've written, much less remember what I was thinking at the time.
  9. How many times have you been attempting to use someone else's code and found yourself thinking a) "I wish they hadn't told me so much about how this works", or b) "I wish they hadn't given me so many useful examples of how to use their code"? Never? Me neither.
  10. Do you want people to swear by your code or swear at it? Seriously, do you want people to see your name as the author and wish they could strangle you with their mouse cord, or send you a heartfelt email of thanks for documenting it so well? It's a matter of personal pride at some level, isn't it? Are you proud of your work and happy to sign your name to it? Does your documentation show that you are an above-average coder who thought about their project and can write reasonably well, or that you are a slipshod hacker? Would you be comfortable with your code being shown on a giant screen in front of 1000 of your customers/peers with you there at the podium to answer questions?
  11. Do you believe in craftsmanship? Well-crafted code can be a thing of beauty, just as much as a vintage car or a piece of handcrafted furniture. (If you don't feel this way, please -- find another career.)

What is "documentation"?

OK, so you believe documentation is a good thing. What is it, exactly? What should be contained in a documentation package?

In order for documentation to be meaningful your code should exhibit consistent style and use accepted naming conventions. In other words, use coding standards.

Every project has its own special requirements, of course. Some of our projects have specific contractual documentation requirements, particularly if there are security or intellectual property issues. These are meant to be some general guidelines and are what CE4710 students are expected to supply with their senior project submissions.They are also what we use, at a minimum, at Systronix for our internal code development projects.

  1. A functional partition, state diagram, outline, and/or flow chart of the major code modules. It's not so important what method of thought you apply to your project, but that you apply any. If this is a document created a a text editor, diagram tool, etc, then output it to some standard format (HTML, PDF, JPG, etc) and include it in your project documentation tree. Don't wind up with a bunch of documentation source files scattered across team member's PCs and various company network folders. Keep the source files (Pagemaker or Word originals) in a single project folder on your network, and part of your company's periodic backup tree.
  2. Licensing issues need to be considered, although we will not discuss them in detail here (licensing is already the topic of many authoritative publications). Who is claiming ownership of this code? Are you giving users the right to use, sell, re-distribute, and/or modify your work, and if so, under what conditions or using what standard license template? Does your code incorporate the licensed work of others and if so, what are the ramifications or requirements due to such inclusions?
  3. Examples of how to use it. These must be non-trivial examples to be useful (unless your code itself is trivial). These can be embedded in the package or class javadocs. Look at the Sun Java Thread class javadocs for examples of how this can be done. Example code snippets should be included in the package or class javadocs. You should also make available a public example or test class which gives a detailed example of using the most common aspects of your public API. You'll need to write such a class for your own use, so why not make it good enough to release as an example?
  4. A usable and consistent Public API. This is the only documentation which users can and should see. They don't need to know how classes are implemented, just how to utilize them. If you don't ship source code with your product, this Public API must be self-sufficient. Even if you do ship source, you should never force users to pick though your source in an attempt to divine how they should use your code. Forcing users to read your source code to use it breaks the encapsulation of your code and may prevent it from being maintainable. Users will invariably come to rely on private or undocumented features -- and then you can't change the inner implementation details of your classes without breaking your users' code. The public API should consist of at least:
    1. A package overview and summary. See package overview for how to generate this with javadoc.
    2. A class overview. What does this class include? On what other classes does it depend? If it is an interface or abstract, why is it so, and what do we need to know about subclassing (extending or implementing) it? Be sure your class structure is logical and consistent. For example, when we were writing the I/O drivers for JCX, we encapsulated the SPI hardware API in one set of classes rather than sprinkling bits of it in every sensor or motor class which wanted to access the hardware. If you must have inconsistencies, document them and provide cross-references to them (use the appropriate javadoc tags). For example, some Java Thread control methods (sleep, yield, start, join) are in the Thread class while others (notify, wait) are in the Object class.
    3. Method descriptions.
    4. Field descriptions.
    5. Constant descriptions. Constants are immutable fields which are intended to encapsulate and standardize fixed data such as I/O addresses, min and max values, and so forth.
  5. Detailed Private comments sufficient to enable you or others not familiar with the code to understand and maintain it.
  6. A Public JAR or other distribution and archive of your code which is meant for end-user access and consumption.
  7. A Private JAR which is intended for your internal archiving and use, or for distribution to customers who will be granted access to the source code.

Use javadoc's package.html capability

If your package has more than two classes, create package documentation using a "package.html" file - this is placed in the source root folder and is automatically included by javadoc. This should be an overview of all your package classes, explaining who does what.
Ref: http://java.sun.com/j2se/javadoc/writingdoccomments/#packagecomments

Here's a reference to such topics:
" How to Write Doc Comments for the Javadoc Tool"
http://java.sun.com/j2se/javadoc/writingdoccomments/

This is also installed with the JDK on your local disk, the location may vary depending on your JDK version. You might have to install the separate "doc install" from sun to get all the local doc files.

Copying right out of the above reference, with my bold and underlined emphasis added:

Contents of package.html source file

The package doc comment should provide (directly or via links) everything necessary to allow programmers to use the package. It is a very important piece of documentation: for many facilities (those that reside in a single package but not in a single class) it is the first place where programmers will go for documentation. It should contain a short, readable description of the facilities provided by the package (in the introduction, below) followed by pointers to detailed documentation, or the detailed documentation itself, whichever is appropriate. Which is appropriate will depend on the package: a pointer is appropriate if it's part of a larger system (such as, one of the 37 packages in Corba), or if a Framemaker document already exists for the package; the detailed documentation should be contained in the package doc comment file itself if the package is self-contained and doesn't require extensive documentation (such as java.math).

To sum up, the primary purpose of the package doc comment is to describe the purpose of the package, the conceptual framework necessary to understand and to use it, and the relationships among the classes that comprise it. For large, complex packages (and those that are part of large, complex APIs) a pointer to an external architecture document is warranted.


Some documentation examples
diskette Sonar JAR (100 KBytes) Includes javadocs. You can expand this with WinZip and see the javadocs.There's still room for improvement, and this project doesn't use the latest code templates.

How to create and maintain the code and documentation

Use a source code version control program such as CVS, and develop a team and company policy about using and managing it. CVS does very well at managing ascii files but a lot less well at binary files or files which cannot be easily merged, especially large binary files.

Use an Ant build.xml file to create the javadocs, including a multi- package overview if applicable (using the javadoc -overview parameter). Javadoc will also automatically look for a "package.html" file located in the same location as your package's .java source files.

 


 
Systronix® 939 Edison St, Salt Lake City, Utah, USA 84111
Tel +1-801-534-1017, Fax +1-801-534-1019
contact us     Time Zone: MDT (UTC-6)
 

Java and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
Systronix is independent of Sun Microsystems, Inc.
TStik, JStik, JCX, JStamp, JSimm, JDroid, and JRealTime are trademarks of Systronix, Inc.
1-Wire, iButton and TINI are trademarks of Dallas Semiconductor
Simmstick is a trademark of Dontronics
LEGO® is a trademark of Lego A/S, Denmark