guidelines.h

Go to the documentation of this file.
00001 /*
00002  * guidelines.h
00003  *
00004  * Not a real header!  This is just here for Doxygen.  Don't use this header.
00005  */
00006 
00007 /// \ingroup princip_guide
00008 /*@{*/
00009 
00010 /// \defgroup guidelines Wavepacket Coding Guidelines
00011 /// General Style and Design Guidelines
00012 ///
00013 /// \n
00014 /// <b>Formatting Style:</b>
00015 /// - Generally follows the FreeBSD kernel style.
00016 ///    See "man style" on a FreeBSD host, or search the web.
00017 /// - Example link: http://www.freebsd.org/cgi/man.cgi?query=style&sektion=9
00018 /// - FreeBSD style means 8-character tabs.
00019 /// - Optimized for easy merges and diffs (cvs diff etc.)
00020 ///     (this means function definitions and other lists are often
00021 ///      split into a single line per argument or entry, etc).
00022 ///
00023 /// \n
00024 /// <b>Header Files:</b>
00025 /// - Header files are there for the user of a class or API, <b>not</b> the
00026 ///     developer of the class or API.
00027 /// - As such, header files must be terse (or silent!) on implementation.
00028 /// - Header files must be easy to
00029 ///     read and understand from the user's point of view.  That is, they
00030 ///     must be formatted and commented so that someone perusing the
00031 ///     header can quickly understand everything.  You should not rely on
00032 ///     tools or generated documentation for users to understand the
00033 ///     objects and methods declared in the header.
00034 /// - Header files must explain clearly what the class/API is for
00035 ///     and how it should be used.  That is, the design and logical concepts
00036 ///     as well as the technical details.
00037 /// - Header files form a strict wall between the complexity of
00038 ///     implementation (.cpp file) and what should be the simple intended
00039 ///     purpose (exposed API).  A messy header file indicates that complexity
00040 ///     can leak out into other code, which is nonmaintainable.
00041 ///
00042 /// \n
00043 /// <b>General Implementation Notes:</b>
00044 /// - Aggressively check inputs.  Assert or throw as necessary.
00045 /// - Throw if you think there may be legitimate reasons for an error
00046 ///      condition to occur (out of disk space, bad user input, etc.).
00047 ///      Only assert if the error appears to be a coding issue.  Imagine
00048 ///      that the code will be linked into a long-running server daemon
00049 ///      that is never supposed to fail.  Throwing is safest if you
00050 ///      aren't sure.
00051 /// - Any errors <b>must</b> be accompanied with a rich error message.  Imagine
00052 ///      that someone is trying to code against your API using only the
00053 ///      error messages to guide them.  It should be possible for them to
00054 ///      do that.  (Asserting on a null pointer is okay.  But more intricate
00055 ///      checks must have clear descriptions for both callers and the
00056 ///      developers who come into the code later).
00057 /// - Code for long-term maintainability by multiple strangers.  This means
00058 ///      code and comments must be clear and readable.
00059 /// - Within a .cpp file, I usually put static helper methods at the
00060 ///      top of the file, and the public API at the bottom.  This is to
00061 ///      avoid needing separate function declarations and definitions.
00062 ///      Usually, the only function declarations are in header files, and
00063 ///      functions private to a file (static) are defined before any
00064 ///      references to them occur, so no separate declaration is needed.
00065 /// 
00066 /// \n
00067 /// <b>A note on Class implementation:</b>
00068 /// - If a class is meant to be used on the stack, then of course
00069 ///     the header file must include all of the private data etc.
00070 /// - If a class is meant to be allocated on the heap, then
00071 ///     private data should <b>not</b> be in the header.  Typically this
00072 ///     means that the header contains only an interface declaration,
00073 ///     and the .cpp file contains a class that implements the
00074 ///     interface.  You'll have to provide a factory method on the
00075 ///     interface, since the implementation class is hidden.
00076 ///     Why do this?
00077 ///       - Header file stays clean (interface only, so a user of the
00078 ///            class isn't distracted by implementation details).
00079 ///       - Code that uses the class doesn't have to recompile every
00080 ///            time the implementation changes.
00081 /// - If for some reason you have a class allocated on the heap
00082 ///     but you can't pay the cost of virtual function calls, then
00083 ///     of course you can put the private data in the header.  But
00084 ///     that is probably an indication that something isn't factored
00085 ///     correctly.
00086 /// - If your class interface is so big that you can't reasonably put
00087 ///     all of the class implementation in a single .cpp file, that
00088 ///     is also an indication that your class is too complex and needs
00089 ///     to be refactored.
00090 /// - Even within a .cpp file, the class declaration must be terse,
00091 ///     so a developer can get a feel for the class in only 1-2
00092 ///     screens.  A large implementation class is probably a sign that
00093 ///     additional functionality could be broken out into separately
00094 ///     reusable components.
00095 /// - Within a class declaration, keep things grouped.  For instance,
00096 ///     all public methods should be declared in one place, all private
00097 ///     data in one place, etc.  Don't mix data and functions or
00098 ///     public + private.  If you start needing a lot of sections with
00099 ///     coupled code + data, that's a sign you need to break up the
00100 ///     class.
00101 /// - Don't mix data with behaviors.  If a class is mostly about its
00102 ///     data, then keep any operations fairly terse, and rich
00103 ///     behaviors on the data can be contained in separate visitor
00104 ///     objects.
00105 /// - Don't couple concepts.  For instance, a rich data object should
00106 ///     not know how to render itself--that should be done by a
00107 ///     separate object.  So the rich data object is not dependent on
00108 ///     an arbitrary rendering library.