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.