< Free Open Study > |
This section presents guidelines for laying out code in classes. The first subsection describes how to lay out the class interface. The second subsection describes how to lay out the class implementations. The final subsection discusses laying out files and programs. Laying Out Class InterfacesIn laying out class interfaces, the convention is to present the class members in the following order: Cross-Reference For details on documenting classes, see "Commenting Classes, Files, and Programs" in Section 32.5. For a discussion of the differences between good and bad classes, see Chapter 6, "Working Classes."
Laying Out Class ImplementationsClass implementations are generally laid out in this order:
If you have more than one class in a file, identify each class clearly Routines that are related should be grouped together into classes. A reader scanning your code should be able to tell easily which class is which. Identify each class clearly by using several blank lines between it and the classes next to it. A class is like a chapter in a book. In a book, you start each chapter on a new page and use big print for the chapter title. Emphasize the start of each class similarly. An example of separating classes is shown in Listing 31-66: Listing 31-66. C++ example of formatting the separation between classes// create a string identical to sourceString except that the <-- 1 // blanks are replaced with underscores. | void EditString::ConvertBlanks( | char *sourceString, | char *targetString | ) { | Assert( strlen( sourceString ) <= MAX_STRING_LENGTH ); | Assert( sourceString != NULL ); | Assert( targetString != NULL ); | int charIndex = 0; | do { | if ( sourceString[ charIndex ] == " " ) { | targetString[ charIndex ] = '_'; | } | else { | targetString[ charIndex ] = sourceString[ charIndex ]; | } | charIndex++; | } while sourceString[ charIndex ] != '\0'; | } <-- 1 //---------------------------------------------------------------------- <-- 2 // MATHEMATICAL FUNCTIONS | // | // This class contains the program's mathematical functions. | //---------------------------------------------------------------------- <-- 2 // find the arithmetic maximum of arg1 and arg2 <-- 3 int Math::Max( int arg1, int arg2 ) { | if ( arg1 > arg2 ) { | return arg1; | } | else { | return arg2; | } | } <-- 3 // find the arithmetic minimum of arg1 and arg2 <-- 4 int Math::Min( int arg1, int arg2 ) { | if ( arg1 < arg2 ) { | return arg1; | } | else { | return arg2; | } | } <-- 4
Avoid overemphasizing comments within classes. If you mark every routine and comment with a row of asterisks instead of blank lines, you'll have a hard time coming up with a device that effectively emphasizes the start of a new class. An example is shown in Listing 31-67: Listing 31-67. C++ example of overformatting a class//********************************************************************** //********************************************************************** // MATHEMATICAL FUNCTIONS // // This class contains the program's mathematical functions. //********************************************************************** //********************************************************************** //********************************************************************** // find the arithmetic maximum of arg1 and arg2 //********************************************************************** int Math::Max( int arg1, int arg2 ) { //********************************************************************** if ( arg1 > arg2 ) { return arg1; } else { return arg2; } } //********************************************************************** // find the arithmetic maximum of arg1 and arg2 //********************************************************************** int Math::Min( int arg1, int arg2 ) { //********************************************************************** if ( arg1 < arg2 ) { return arg1; } else { return arg2; } } In this example, so many things are highlighted with asterisks that nothing is really emphasized. The program becomes a dense forest of asterisks. Although it's more an aesthetic than a technical judgment, in formatting, less is more. If you must separate parts of a program with long lines of special characters, develop a hierarchy of characters (from densest to lightest) instead of relying exclusively on asterisks. For example, use asterisks for class divisions, dashes for routine divisions, and blank lines for important comments. Refrain from putting two rows of asterisks or dashes together. An example is shown in Listing 31-68: Listing 31-68. C++ example of good formatting with restraint //********************************************************************** // MATHEMATICAL FUNCTIONS // // This class contains the program's mathematical functions. //********************************************************************** //---------------------------------------------------------------------- <-- 1 // find the arithmetic maximum of arg1 and arg2 //---------------------------------------------------------------------- int Math::Max( int arg1, int arg2 ) { if ( arg1 > arg2 ) { return arg1; } else { return arg2; } } //---------------------------------------------------------------------- // find the arithmetic minimum of arg1 and arg2 //---------------------------------------------------------------------- int Math::Min( int arg1, int arg2 ) { if ( arg1 < arg2 ) { return arg1; } else { return arg2; } }
This advice about how to identify multiple classes within a single file applies only when your language restricts the number of files you can use in a program. If you're using C++, Java, Visual Basic, or other languages that support multiple source files, put only one class in each file unless you have a compelling reason to do otherwise (such as including a few small classes that make up a single pattern). Within a single class, however, you might still have subgroups of routines, and you can group them using techniques such as the ones shown here. Laying Out Files and ProgramsBeyond the formatting techniques for classes is a larger formatting issue: how do you organize classes and routines within a file, and how do you decide which classes to put in a file in the first place? Cross-Reference For documentation details, see "Commenting Classes, Files, and Programs" in Section 32.5. Put one class in one file A file isn't just a bucket that holds some code. If your language allows it, a file should hold a collection of routines that supports one and only one purpose. A file reinforces the idea that a collection of routines are in the same class. All the routines within a file make up the class. The class might be one that the program really recognizes as such, or it might be just a logical entity that you've created as part of your design. Cross-Reference For details on the differences between classes and routines and how to make a collection of routines into a class, see Chapter 6, "Working Classes." Classes are a semantic language concept. Files are a physical operating-system concept. The correspondence between classes and files is coincidental and continues to weaken over time as more environments support putting code into databases or otherwise obscuring the relationship between routines, classes, and files. Give the file a name related to the class name Most projects have a one-to-one correspondence between class names and file names. A class named CustomerAccount would have files named CustomerAccount.cpp and CustomerAccount.h, for example. Separate routines within a file clearly Separate each routine from other routines with at least two blank lines. The blank lines are as effective as big rows of asterisks or dashes, and they're a lot easier to type and maintain. Use two or three to produce a visual difference between blank lines that are part of a routine and blank lines that separate routines. An example is shown in Listing 31-69: Listing 31-69. Visual Basic example of using blank lines between routines'find the arithmetic maximum of arg1 and arg2 Function Max( arg1 As Integer, arg2 As Integer ) As Integer If ( arg1 > arg2 ) Then Max = arg1 Else Max = arg2 End If End Function <-- 1 | | <-- 1 'find the arithmetic minimum of arg1 and arg2 Function Min( arg1 As Integer, arg2 As Integer ) As Integer If ( arg1 < arg2 ) Then Min = arg1 Else Min = arg2 End If end Function
Blank lines are easier to type than any other kind of separator and look at least as good. Three blank lines are used in this example so that the separation between routines is more noticeable than the blank lines within each routine. Sequence routines alphabetically An alternative to grouping related routines in a file is to put them in alphabetical order. If you can't break a program up into classes or if your editor doesn't allow you to find functions easily, the alphabetical approach can save search time. In C++, order the source file carefully Here's a typical order of source-file contents in C++:
cc2e.com/3194
|
< Free Open Study > |