Sunday, August 24, 2008

XML Documentation

OK, that last post ended up as being a bit of a tease, so I'll jump right into things today. I write most of my comments using XML. Before the days of XML, I used to write "header comments" for all my major code blocks. Each of these header sections would contain a number of pre-defined elements. With the advent of XML and the inclusion of support for XML-style comments in Visual Studio, it became easy to create consistent, thorough documentation for each primary element of my code (by "primary element" I mean classes, properties, methods, and events).

Using XML comments in .NET code has several advantages.

  • XML's well-defined tags and the assistance of auto-complete make it easy to create consistent comment blocks.
  • Starting with Visual Studio 2005, XML Documentation Comments can be extracted from VB, C#, and C++ source code files. When you compile with the /doc parameter, the compiler will extract all XML tags from your source code and create an XML documentation file. You can instruct the compiler to extract these comments into an XML file. These comments can be used by NDoc and SandCastle to create HTML and chm help files.
  • Finally, these XML files can also be used to add IntelliSense in VisualStudio to your own classes.

  • I try to comment every class, method, property, and event. In order for the compiler to extract documentation, the code comments need to meet the following two conditions:

  • The comment must begin with ''' in VB files and /// in C# or C++ files.
  • The documentation to be extracted must be encased within XML tags.

  • While the compiler will accept any valid XML tags, I generally use a specific set of tags for each element that I'm commenting. In the remainder of this post I'll describe how I comment classes and properties. I'll finish my discussion of XML comments in the next post where I describe how I comment methods and events.

    Classes
    At the very minimum, I use the <summary> tag to provide a short summary of the class. This summary describes what the class is and its use. A more detailed description goes in the <remarks> tag. Other tags I may use in a class comments block are <example> (usually used with the <code> tag), and <seealso> to add a See Also section to the documentation containing links to related classes. Finally, I add the non-standard tag <author> to all my class comment blocks.

    Here's an example:

    ''' <summary>
    ''' A simple class that represents a US mailing address.
    ''' </summary>
    ''' Keven Lehmann
    ''' <remarks>
    ''' <para>
    ''' This class contains properties for all of the elements in a common US
    ''' mailing address. It provides basic validation for state abbreviations
    ''' and ZIP code formats (basic and ZIP+4) but does not verify that the
    ''' address represents an actual US mailing address.
    ''' </para>
    ''' <para>
    ''' The following example demonstrates a typical use for this class:
    ''' </para>
    ''' <example>
    ''' <code>
    ''' Public Function GetSampleAddress() as String
    ''' Dim addr as USAddress = new USAddress()
    ''' addr.Recipient = "Keven Lehmann"
    ''' addr.Street = "101 Main St"
    ''' addr.City = "Somewhere"
    ''' addr.State = "MD"
    ''' addr.ZIP = "21212-1212"
    ''' Return addr.ToUspsString()
    ''' End Function
    ''' </code>
    ''' </example>
    ''' </remarks>
    Public Class USAddress
    ...
    End Class


    Properties
    For properties, I always include the <summary> and <value> tags, although <value> often turns out to be a rehashing of the <summary>. If I feel there is anything about the property that needs extra clarification, I'll include that in a <remarks> tag. Other common tags I may use with a property are <example> for examples of use and <see> to refer to related functions from within the body of the documentation.

    Here is an example:

    ''' <summary>
    ''' Gets the <see cref="Person"></see>'s full name.
    ''' </summary>
    ''' <value>
    ''' The full name of the <b>Person</b>, comprising their
    ''' <see cref="FirstName"></see> and <see cref="LastName"></see>,
    ''' separated by a space.
    ''' </value>
    Public ReadOnly Property FullName() As String
    ...
    End Property


    That's it for right now. Next time I'll finish up XML comments by covering Method and Event comments.

    Sunday, August 17, 2008

    Documentation is the Key

    Documentation is one of the most important, yet overlooked, aspects of programming. No one programs in a vacuum. At some point, someone else will look at your code and have to understand it. For that matter, at some point in the future you may have to look at your code and understand it! When the code is fresh in your mind, understanding it is easy. But how easy is it to follow six months from now? One year? Two years? By that time, several projects have come and gone and that code is stale and musty in your mind. Do you really want to laboriously read through it line-by-line just to understand how it works again? Wouldn't it be easier if you could skim through your code and quickly home in on the piece you need to fix or change?

    Clearly-written code can certainly help you achieve that objective, but I feel that clearly-documented code can make the task even easier. With well-documented code you can read through the documentation rather than the code itself to understand what each piece of code is supposed to do. And well-written documentation in plain English (or French or German or whatever your native language is) is always much easier to understand than the actual code itself (and if it isn't, then you really need to work on your writing skills).

    If you're tasked with making changes to a project that you've never been involved with before and the previous developers didn't properly document their work, you may quickly feel the urge to track down those programmers and do bodily harm (if so, hopefully they were consultants who were long gone and not your co-workers). No documentation means having to slog through thousands of lines of code (or more) to track down the code you need. Sometimes you have to wade through all of the code just to get a basic understanding of the application before you can even dream of modifying it. Don't be one of those programmers that other programmers will one day want to kill!

    On the other hand, good documentation means having external documents that help you see the overall structure of the application -- the big picture. From that, you can see which pieces of the code (layers, namespaces, or classes) are important to your current task. More detailed documentation about those code sections (both external documents as well as class-level comments) can help you drill-down to even smaller pieces of the code. Finally, documentation on the class properties and methods as well as inline comments can help you pinpoint the exact sections of your code that you need.

    Good documentation involves several things. The main aspects of well-documented code are internal documentation, self-documenting code, and external documentation.

    Internal Documentation
    Actively documenting the body of your code is perhaps the biggest topic of the three types of documentation I mentioned. Thus, I'll start with that and spend most of my time talking about it. Internal documentation itself can be broken down into several topics: class-level comments; method-, property-, and event-level comments; and inline (or code block) comments. In addition, there are a couple side-topics I'd like to discuss: XML documentation and code regions.

    It is vitally important to rigorously comment your code. Unfortunately, writing comments tends to be boring compared to the challenge of coding and is often neglected. It can also be time-consuming and thus easy to skip when you're working under a tight deadline. I know I'm still far from perfect when it comes to properly documenting my code, but I'm aware of its importance and since I constantly strive to improve the quality of my code, I also constantly strive to improve the quality of my code comments (which I feel has a net effect of improving the quality of the code itself).

    The next few sections delve into each aspect of internal documentation in more detail. At the end, I'll provide a few tips and tricks I've discovered that help make it easier to include and maintain good documentation. Some of them even make you a more efficient programmer, so you have even less excuses for not including good comments in your code!

    OK, I'm long-winded, I'll admit it. so without further adieu, let's start commenting about comments... next time. ;-)

    full window
    full window
    full window
    full window

    Thursday, August 7, 2008

    Apologies, life, and software deadlines

    Yes, it's been a long time since my last blog post. I've been pulling a lot of extra work trying to hit a milestone for an application I've been developing. As a result, in my free time I've mainly wanted to just unwind so other commitments have suffered a bit. You should see the state of my yard!

    Anyway, the deadline has come and gone, and now I'm scrambling to hit the NEXT milestone! It just never ends in the life of a software engineer, does it? Our life is a series of deadlines stretching off (way off) into the distance. In my case, I'm writing an application that's much more complex than anything I've attempted before and there's only one other developer working with me on this project so we're in for a marathon, not a sprint (sorry all you Scrum adherents!).

    As the project lead, I've found this a very interesting challenge. I've actually been working on this project for some time now and am approximately 2/3 through the whole thing. The whole process has led to a number of things I hope to write about here.

    To give you a quick teaser until then, this project is an application to assist our staff with the document creation process. Sounds like all we need to do is purchase Microsoft Word, right? However, these documents are built on over 100 templates (all of which may need to be highly customized), have several input fields, pull information from our databases, and have to integrate with our document imaging and workflow systems.

    Actually, we already have such a system. I wrote it several years ago when the previous system was made obsolete during a mainframe upgrade. And it was built on Microsoft Word. However, now we also need to capture information from these documents for statistical analysis (we currently do capture statistics from these documents, but it's manually entered into our statistics database by another department after the documents have been committed to our document imaging system).

    Sounds like a fairly straightforward addition, right? It's definitely a good idea and one I fully support, but a basic analysis of the actual system quickly quickly reveals a number of twists in an otherwise simple-sounding task. First, the users need to play pretty fast and loose with the templates. Depending on the need, some of the statistics that need to be captured are currently added to the text of the document, not existing fields. Some could come from fields that are inserted dynamically into the text through a variety of predefined text blocks. Also, some statistical elements may occur a variable number of times in a document. Some documents don't contain new statistics, but modify existing statistics. Finally, one of the "templates" is a totally blank document for free-form entry (that one's probably going to be a goner if I have anything to say about it).

    Put it all together, and our existing VB6 application bundled on top of Microsoft Word templates and VBA code just wasn't quite up to the task. So the decision was made to dump Word from the system (we found a fairly good word processor control that we can embed in the new application) and rewrite the application in .NET.

    All this is a long-winded way of saying that I'm sorry for the long delay since my last post and (hopefully) software deadlines will no longer distract me from my blog. I plan to post my next article about coding conventions soon and you can expect to hear more about the past, present, and future of this project as well.