31.3. Layout Styles

 < Free Open Study > 

Most layout issues have to do with laying out blocks, the groups of statements below control statements. A block is enclosed between braces or keywords: { and } in C++ and Java, if-then-endif in Visual Basic, and other similar structures in other languages. For simplicity, much of this discussion uses begin and end generically, assuming that you can figure out how the discussion applies to braces in C++ and Java or other blocking mechanisms in other languages. The following sections describe four general styles of layout:

  • Pure blocks

  • Emulating pure blocks

  • Using begin-end pairs (braces) to designate block boundaries

  • Endline layout

Pure Blocks

Much of the layout controversy stems from the inherent awkwardness of the more popular programming languages. A well-designed language has clear block structures that lend themselves to a natural indentation style. In Visual Basic, for example, each control construct has its own terminator and you can't use a control construct without using the terminator. Code is blocked naturally. Some examples in Visual Basic are shown in Listing 31-6, Listing 31-7, and Listing 31-8:

Listing 31-6. Visual Basic example of a pure if block
 If pixelColor = Color_Red Then    statement1    statement2    ... End If

Listing 31-7. Visual Basic example of a pure while block
While pixelColor = Color_Red    statement1    statement2    ... Wend

Listing 31-8. Visual Basic example of a pure case block
Select Case pixelColor    Case Color_Red       statement1       statement2       ...    Case Color_Green       statement1       statement2       ...    Case Else       statement1       statement2       ... End Select

A control construct in Visual Basic always has a beginning statement If-Then, While, and Select-Case in the examples and it always has a corresponding End statement. Indenting the inside of the structure isn't a controversial practice, and the options for aligning the other keywords are somewhat limited. Listing 31-9 is an abstract representation of how this kind of formatting works:

Listing 31-9. Abstract example of the pure-block layout style


In this example, statement A begins the control construct and statement D ends the control construct. The alignment between the two provides solid visual closure.

The controversy about formatting control structures arises in part from the fact that some languages don't require block structures. You can have an if-then followed by a single statement and not have a formal block. You have to add a begin-end pair or opening and closing braces to create a block rather than getting one automatically with each control construct. Uncoupling begin and end from the control structure as languages like C++ and Java do with { and } leads to questions about where to put the begin and end. Consequently, many indentation problems are problems only because you have to compensate for poorly designed language structures. Various ways to compensate are described in the following sections.

Emulating Pure Blocks

A good approach in languages that don't have pure blocks is to view the begin and end keywords (or { and } tokens) as extensions of the control construct they're used with. Then it's sensible to try to emulate the Visual Basic formatting in your language. Listing 31-10 is an abstract view of the visual structure you're trying to emulate:

Listing 31-10. Abstract example of the pure-block layout style


In this style, the control structure opens the block in statement A and finishes the block in statement D. This implies that the begin should be at the end of statement A and the end should be statement D. In the abstract, to emulate pure blocks, you'd have to do something like Listing 31-11:

Listing 31-11. Abstract example of emulating the pure-block style


Some examples of how the style looks in C++ are shown in Listing 31-12, Listing 31-13, and Listing 31-14:

Listing 31-12. C++ example of emulating a pure if block
if ( pixelColor == Color_Red ) {    statement1;    statement2;    ... }

Listing 31-13. C++ example of emulating a pure while block
while ( pixelColor == Color_Red ) {    statement1;    statement2;    ... }

Listing 31-14. C++ example of emulating a pure switch/case block
switch ( pixelColor ) {    case Color_Red:       statement1;       statement2;       ...    break;    case Color_Green:       statement1;       statement2;       ...    break;    default:       statement1;       statement2;       ...    break; }

This style of alignment works pretty well. It looks good, you can apply it consistently, and it's maintainable. It supports the Fundamental Theorem of Formatting in that it helps to show the logical structure of the code. It's a reasonable style choice. This style is standard in Java and common in C++.

Using begin-end Pairs (Braces) to Designate Block Boundaries

A substitute for a pure-block structure is to view begin-end pairs as block boundaries. (The following discussion uses begin-end to refer generically to begin-end pairs, braces, and other equivalent language structures.) If you take that approach, you view the begin and the end as statements that follow the control construct rather than as fragments that are part of it. Graphically, this is the ideal, just as it was with the pure-block emulation shown again in Listing 31-15:

Listing 31-15. Abstract example of the pure-block layout style


But in this style, to treat the begin and the end as parts of the block structure rather than the control statement, you have to put the begin at the beginning of the block (rather than at the end of the control statement) and the end at the end of the block (rather than terminating the control statement). In the abstract, you'll have to do something like what's done in Listing 31-16:

Listing 31-16. Abstract example of using begin and end as block boundaries


Some examples of how using begin and end as block boundaries looks in C++ are shown in Listing 31-17, Listing 31-18, and Listing 31-19:

Listing 31-17. C++ example of using begin and end as block boundaries in an if block
if ( pixelColor == Color_Red )    {    statement1;    statement2;    ...    }

Listing 31-18. C++ example of using begin and end as block boundaries in a while block
while ( pixelColor == Color_Red )    {    statement1;    statement2;    ...    }

Listing 31-19. C++ example of using begin and end as block boundaries in a switch/case block
 switch ( pixelColor )    {    case Color_Red:       statement1;       statement2;       ...       break;    case Color_Green:       statement1;       statement2;       ...       break;    default:       statement1;       statement2;       ...       break;    }

This alignment style works well; it supports the Fundamental Theorem of Formatting (once again, by exposing the code's underlying logical structure). Its only limitation is that it can't be applied literally in switch/case statements in C++ and Java, as shown by Listing 31-19. (The break keyword is a substitute for the closing brace, but there is no equivalent to the opening brace.)

Endline Layout

Another layout strategy is "endline layout," which refers to a large group of layout strategies in which the code is indented to the middle or end of the line. The endline indentation is used to align a block with the keyword that began it, to make a routine's subsequent parameters line up under its first parameter, to line up cases in a case statement, and for other similar purposes. Listing 31-20 is an abstract example:

Listing 31-20. Abstract example of the endline layout style


In this example, statement A begins the control construct and statement D ends it. Statements B, C, and D are aligned under the keyword that began the block in statement A.

The uniform indentation of B, C, and D shows that they're grouped together. Listing 31-21 is a less abstract example of code formatted using this strategy:

Listing 31-21. Visual Basic example of endline layout of a while block
While ( pixelColor = Color_Red )         statement1;         statement2;         ...         Wend

In the example, the begin is placed at the end of the line rather than under the corresponding keyword. Some people prefer to put begin under the keyword, but choosing between those two fine points is the least of this style's problems.

The endline layout style works acceptably in a few cases. Listing 31-22 is an example in which it works:

Listing 31-22. A rare Visual Basic example in which endline layout seems appealing
 If ( soldCount > 1000 ) Then                              markdown = 0.10                              profit = 0.05                         Else       <-- 1                              markdown = 0.05                         End If

(1)The else keyword is aligned with the then keyword above it.

In this case, the Then, Else, and End If keywords are aligned and the code following them is also aligned. The visual effect is a clear logical structure.

If you look critically at the earlier case-statement example, you can probably predict the unraveling of this style. As the conditional expression becomes more complicated, the style will give useless or misleading clues about the logical structure. Listing 31-23 is an example of how the style breaks down when it's used with a more complicated conditional:

A more typical Visual Basic example, in which endline layout breaks down

Listing 31-23.
If ( soldCount > 10 And prevMonthSales > 10 ) Then    If ( soldCount > 100 And prevMonthSales > 10 ) Then       If ( soldCount > 1000 ) Then                                  markdown = 0.1                                  profit = 0.05                               Else                                  markdown = 0.05                               End If                                                   Else                                                      markdown = 0.025                                                   End If                                                Else                                                   markdown = 0.0                                                End If


What's the reason for the bizarre formatting of the Else clauses at the end of the example? They're consistently indented under the corresponding keywords, but it's hard to argue that their indentations clarify the logical structure. And if the code were modified so that the length of the first line changed, the endline style would require that the indentation of corresponding statements be changed. This poses a maintenance problem that pure block, pure-block emulation, and using begin-end to designate block boundaries do not.

You might think that these examples are contrived just to make a point, but this style has been persistent despite its drawbacks. Numerous textbooks and programming references have recommended this style. The earliest book I saw that recommended this style was published in the mid-1970s, and the most recent was published in 2003.

Overall, endline layout is inaccurate, hard to apply consistently, and hard to maintain. You'll see other problems with endline layout throughout the chapter.

Which Style Is Best?

If you're working in Visual Basic, use pure-block indentation. (The Visual Basic IDE makes it hard not to use this style anyway.)

In Java, standard practice is to use pure-block indentation.

In C++, you might simply choose the style you like or the one that is preferred by the majority of people on your team. Either pure-block emulation or begin-end block boundaries work equally well. The only study that has compared the two styles found no statistically significant difference between the two as far as understandability is concerned (Hansen and Yim 1987).

Neither of the styles is foolproof, and each requires an occasional "reasonable and obvious" compromise. You might prefer one or the other for aesthetic reasons. This book uses pure-block style in its code examples, so you can see many more illustrations of how that style works just by skimming through its examples. Once you've chosen a style, you reap the most benefit from good layout when you apply it consistently.

 < Free Open Study > 


Code Complete
Code Complete: A Practical Handbook of Software Construction, Second Edition
ISBN: 0735619670
EAN: 2147483647
Year: 2003
Pages: 334

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net