Search

Top Ten List

Of all my ramblings, people seem to find the following the most interesting:
  1. Pimp My Fields
  2. Using the WebBrowser control to view attachments inline
  3. Purty charts in Domino
  4. My approach to DbLookup and DbColumn in Javascript
  5. Mind Map of Database Design
  6. Design Catalog - version control for Domino
  7. Workaround for LotusScript event binding
  8. Clickable URL's in Notes view columns
  9. Every time you use window.open, God kills a kitten
  10. Create, edit, and delete without agents via AJAX

« SnTT: Mersenne Primes | Main| SnTT: Programmatically Modify Designer Tools Menu »

Maintainability

Category musings
Earlier tonight I was watching Nicholas Zakas' lecture on "Maintainable JavaScript" in the YUI Theater. I wasn't impressed with his speaking style, but he brought up a few good points. One guideline he presented was appropriate uses for comments... which is a sore point for me, both because I'm occasionally aware that I need better habits in this area, and because of my pet peeve regarding the uselessness of most code comments I encounter. Zakas recommends using comments for the following:
  • Each method - what it's for, where it's used, what data it's expecting
  • Large sections of code - explain each portion to avoid confusion
  • Difficult-to-understand algorithms - if you suspect the approach will not be intuitive to everyone, help others understand
  • Hacks - if this was not your ideal approach, flag it... not only to warn others what would break if the "standard" approach were used, but also because at some point the hack may no longer be necessary. All hacks should be revisited periodically to ensure they're still the best approach available.
A former mentor's attitude toward comments - which seems to have shaped my own - is that they are only useful if they answer the question, "why?"; if you find yourself elaborating on "what" or "how", it's likely the code needs refactoring. Here's where I differ from the first two of the above recommendations.

If your methods (and their parameters) are well named, you've already indicated what it's for and what data it's expecting, and where it's used is almost as obvious: a function named "getQueryStringParameter", for example, will (or should) be used in any code whose behavior is dependent upon the value of a parameter in the URL query string. I often see code that seems to have been written by someone who tried to save time by using terse variable and function names, but spent more time explaining in comments what those variables and functions are used for than they would have by simply using names that answer those questions already.

Comments explaining each block in a large section of code seem also to indicate that refactoring might be useful: if you're inserting an explanation for what's taking place in the next 20 lines, those lines should be a separate function. Why? For code to be maintainable, each function should do one thing, and do it well. If you're using OpenLog to trap your errors, but you've got 900 lines of code in the Initialize Sub of a LotusScript agent, when a log document tells you there was a type mismatch in line 752 of Initialize, it's going to take longer to determine the root cause than if it reported the same error in line 8 of sendApprovalNotice. Perhaps more importantly, if each function is only responsible for a small, easy to understand task, it simplifies the process of identifying common functionality across portions of an application, and across multiple applications. These common functions can then be pulled into script libraries and leveraged wherever needed, and whenever any of them is further optimized, any code calling the newly optimized function automatically benefits, without you having to revisit it. Taken to an extreme, any Initialize Sub will read almost like English (or whatever your primary language might be). For example, the following might be the entire Initialize of an "Approve" button:

Call submitCurrentApproverDecision("Approved")
If (isAdditionalApprovalRequired()) Then
    Call sendToNextApprover()
Else
    Call markDocumentApproved()
    Call sendApprovalNotice()
End If
Call updateModificationHistory()
Call closeCurrentDocument()


This is so much more maintainable than having all the code of each step in Initialize, because anyone who needs to modify it later can tell immediately exactly what it does and in what order. They won't know right away precisely how it does it, but assuming they're in the code to fix a bug or add a feature, it tells them exactly where they'll need to go; a "table of contents", so to speak. If each of those functions is structured similarly, they may have to drill down a couple layers to find the exact code to update, but it's unlikely they'll be confused about what the code is doing - and how - even if there isn't a single comment in the code. Again, the only reason for a comment would be to explain why one approach was used instead of an alternative one, whether that be motivated by technical or business considerations.

I think the last two categories, however, are quite valid uses for comments... these are definitely "why" opportunities: the first, because you're indicating why the code works (especially if it would appear to most people as though it shouldn't work), and the second, because you're indicating why the way you would have preferred to approach it wouldn't work. In the former case, it may alert others to a solution for a problem somewhere else that they've heretofore been unable to resolve; in the latter, it makes it less tempting for others to "clean up" your code and, in so doing, break that particular functionality... or, conversely, draws their attention to something that required an awkward solution at the time (for example, string replacement in pre-6 versions of Notes) but can now be made more elegant.

Comments

Gravatar Image1 - Good points Tim. If you haven't already I would get your hands on Rocky Oliver's "Writing Readable Code" presentation { Link } . Some similar points but also some additional ones worth checking out. I'm hoping to get a "sample" database from him at some point which embodies all his various points. I had also brought up the idea of adapting his style to tie-in with the Lotusscript.doc tool { Link } . Haven't looked that closely at it yet so I'm not sure how big a deal that would be.

Ultimately I'd like to inject as many of these little best practice style tips into SuperNTF as I can (or get someone else to help )

Gravatar Image2 - LotusScript.doc rocks. It's the only example I've seen where verbose comments serve a truly useful purpose. It's actually still useful without any comments at all, in the sense that it will still give you a Javadoc-style output of your code... just with no explanation. Again, if everything's well-named, the output is relatively self-explanatory.

I keep meaning to download SuperNTF and take a gander... and then my mind wanders off onto some other tangent. I have almost no attention span... I'd love to blame it on adult-onset A.D.D. or something, but I suspect it's nothing of the sort.

Post A Comment

:-D:-o:-p:-x:-(:-):-\:angry::cool::cry::emb::grin::huh::laugh::lips::rolleyes:;-)

Contact Me

Hire Me

Elsewhere

What the Quote?

"Hold me closer, Tony Danza."

Robert Rockey

"You can't polish a turd."

Michael Nurre

"We thought we'd be brilliant and just copy your code, and your code said, 'Yeah, you're funny'."

Monica Ferrante

"You'll be just below the Bible Belt. So, anatomically speaking..."

Greg Rotz

"Real developers don't eat quiche, they eat liquid crystal."

Nathan Freeman

Apparel

Lotus Rocks

I write the code that makes the young girls cry

Current Terror Alert Level

Assorted Linkage

ClustrMap