Re: Managing a project as it scales
- From: BobF <rNfOrSePeAzMe@xxxxxxxxxxx>
- Date: Sat, 17 Dec 2005 07:20:02 -0600
Joe - great post. I'm glad to see I'm not the only that uses the brace
style you demonstrated here ... :-)
There is a great OS documentation tool called Doxygen. I like it because
the source for the documentation goes into the code, so it's not an
*external* documentation tool. It's similar to javadoc.
It takes a minor amount of effort to add MS macro support (I'll post what I
have for anybody interested), but once done it performs magic, producing
html docs from the embedded comments in the code.
I have used it several times to help sort out existing code. It does
amazing things with source code that doesn't have any specific
documentation embedded.
Again, it takes a little getting used to, and a little effort to tailor for
MS macros. But once done, it is like having the best of both worlds.
I add a post-build step to my VS projects to update the docs on each build.
It's also in my tools menu for "demand" docs generation.
On Fri, 16 Dec 2005 22:05:32 -0500, Joseph M. Newcomer wrote:
> Every function I write has a standard header. It is a comment my editor adds as part of
> the act of creating the empty function body, and it looks like this:
>
> /**************************************************************************************
> * CMyClass::DoSomething
> * Inputs:
> *
> * Result:
> *
> * Effect:
> *
> **************************************************************************************/
>
> I will then document the parameters, the result and its meaning, and the effect, e.g.,
>
> * Inputs:
> * const CString & filename: The name of the file to be opened for output
> * UINT count: The number of elements to write to this file
> * Result: BOOL
> * TRUE if successful
> * FALSE if error (caller uses ::GetLastError)
> * Effect:
> * Opens the file and writes out 'count' elements. This includes writing out
> * the file header. If the file already exists, it is replaced.
> * Notes:
> * File format
> * +------------------------------+
> * | int FileVersion | 0
> * +------------------------------+
> * | count | 4
> * /+------------------------------+
> * | | COLORREF color | 8 + recno * sizeof(record)
> * < +------------------------------+
> * | | BOOL active | 12 + recno * sizeof(record)
> * \ +------------------------------+
> * | |
> * : :
> ****************************************************************************************/
>
> The Notes: section is often the longest section, sometimes longer than the code. Not all
> functions need Notes: sections, which is why I don't have it automatically added in the
> prototype.
>
> Note that I can't control the font, so depending on what font you are using, you may or
> may not see what should be a sequence of rectangular boxes.
>
> I left drawings like this in the program I described in an earlier post. I also will put
> in decision tables, e.g.
>
> * Notes:
> * case ref count
> * -----------------------------------------------
> * A. NULL == 0 Nothing initialized, nothing to do
> * B. NULL > 0 Create new ref table to hold elements
> * C. ~NULL == 0 Nothing to add, nothing to do, should not happen
> * D. ~NULL > 0 Append elements to table
>
> if(ref == NULL && count == 0)
> { /* A. */
> // nothing to do
> } /* A. */
> else
> if(ref == NULL && count > 0)
> { /* B. */
> ref = new Table;
> append(ref, count);
> } /* B. */
> else
> if(ref != NULL && count == 0)
> { /* C. */
> ASSERT(FALSE); // actually, this should never happen
> } /* C. */
> else
> { /* D. */
> append(ref, count);
> } /* D. */
>
> While the code is simplistic, it follows the documentation and is easier to understand and
> debug. When confronted with complex decision tables, write out the comments first, and
> only then implement the code.
>
> Note also that my editor forces every { } block to have a block comment, and when I type
> the matching }, it grabs the correct comment from the open brace.
>
> If you have ever once printed out a listing so you could circle the braces to figure out
> who matched what, you should instantly recognize that any style of braces that does not
> make this trivially obvious is a poor programming style. Typically, you want to minimize
> nesting depth anyway, but braces should follow a methodology that is easy to read. As
> human beings, we are not very good at counting blank spaces, or dealing with nested
> contexts (any good introductory book on cognitive psychology will explain this). So it is
> important to never, ever adopt styles that work directly against us. As far as I can
> tell, nearly every brace convention mechanism is designed to exacerbate what we do poorly.
> I once worked with a compiler, in the early 1970s,that actually took block comments and
> forced matching (begin "name" and end "name" were the block delimiters), and that taught
> me...35 years ago...that no methodology that did not provide for trivially-decodable
> nesting is a flawed methodology.
>
> Rarely is it valuable to maintain external documentation, although I've done it. I once
> wrote an 80-page manual on how to support one product I did. It was clear that certain
> features were potentially open-ended, so I made them table driven. I described in detail
> how to add new entries to the dispatch table, how to write handler methods, how they
> interacted with the app, what the most useful methods were to call, etc. How to add new
> files to the build (this was pre-VS). How to handle per-file customization (we used the
> Microsoft C 3.0 command-line compiler). How to add new overlays. How to read and
> interpret the instrumentation for performance optimization. I got a call from the client
> about once every three months for the next several years, each time starting out, "The
> documentation is wonderful, but we aren't sure how to..." which usually required a new
> paragraph or in the worst case new chapter in the documentation, until we converged on
> something they could hand to unskilled labor and say "Add a Gloop feature to the Mumble
> component" and the person could have in running in a few days.
>
> Remember: unskilled labor is usually the new hire, or yourself six months later. The only
> thing that saved me from disaster when I got that project back after five years was the
> detailed documentation I put in.
>
> Even the message handlers get procedure header blocks. No system I deliver fails to have
> complete headers for each and every function.
>
> Note that Window messages are by definition functions. A user-defined message always has
> (I'll eliminate the long **** lines)
> /****...****
> * UWM_LOG_MESSAGE
> * Inputs:
> * WPARAM: (WPARAM)(CString *) pointer to the string to be displayed. This
> * *must* be heap-allocated!
> * LPARAM: unused, should be 0
> * Result: LRESULT
> * Logically void, 0, always
> * Effect:
> * Logs the string to the message log
> * Notes:
> * It is the responsibility of the recipient of the message to delete the WPARAM
> * value when it is no longer needed
> *****...****/
> #define UWM_LOG_MESSAGE_MSG _T("UWM_LOG_MESSAGE-<guid here>")
>
> A window message is an interface, and all interfaces are completely documented.
>
> This particular message will be a registered window message, e.g.,
>
> static UINT UWM_LOG_MESSAGE = ::RegisterWindowMessage(UWM_LOG_MESSAGE_MSG)
>
> or I use the DECLARE_MESSAGE macro I write:
>
> #define DECLARE_MESSAGE(x) static UINT x = ::RegisterWindowMessage(x##_MSG);
>
> so to get the message, I'll write
>
> DECLARE_MESSAGE(UWM_LOG_MESSAGE)
>
> by such techniques, I reduce the complexity of my code, and thoroughly document it.
> joe
>
> Joseph M. Newcomer [MVP]
> email: newcomer@xxxxxxxxxxxx
> Web: http://www.flounder.com
> MVP Tips: http://www.flounder.com/mvp_tips.htm
.
- Follow-Ups:
- Re: Managing a project as it scales
- From: Alexander
- Re: Managing a project as it scales
- References:
- Managing a project as it scales
- From: Alexander
- Re: Managing a project as it scales
- From: BobF
- Re: Managing a project as it scales
- From: Joseph M . Newcomer
- Managing a project as it scales
- Prev by Date: Re: Managing a project as it scales
- Next by Date: Windows Media Player ActiveX
- Previous by thread: Re: Managing a project as it scales
- Next by thread: Re: Managing a project as it scales
- Index(es):
Relevant Pages
|
Loading