Layout Styles

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 Example 31-6, Example 31-7, and Example 31-8:

Example 31-6. Visual Basic example of a pure if block

If pixelColor = Color_Red Then
   statement1
   statement2
   ...
End If

Example 31-7. Visual Basic example of a pure while block

While pixelColor = Color_Red
   statement1
   statement2
   ...
Wend

Example 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. Example 31-9 is an abstract representation of how this kind of formatting works:

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

image with no caption

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. Example 31-10 is an abstract view of the visual structure you're trying to emulate:

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

image with no caption

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 Example 31-11:

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

image with no caption

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

Example 31-12. C++ example of emulating a pure if block

if ( pixelColor == Color_Red ) {
   statement1;
   statement2;
   ...
}

Example 31-13. C++ example of emulating a pure while block

while ( pixelColor == Color_Red ) {
   statement1;
   statement2;
   ...
}

Example 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 Example 31-15:

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

image with no caption

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 Example 31-16:

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

image with no caption

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

Example 31-17. C++ example of using begin and end as block boundaries in an if block

if ( pixelColor == Color_Red )
   {
   statement1;
   statement2;
   ...
   }

Example 31-18. C++ example of using begin and end as block boundaries in a while block

while ( pixelColor == Color_Red )
   {
   statement1;
   statement2;
   ...
   }

Example 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 Example 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. Example 31-20 is an abstract example:

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

image with no caption

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. Example 31-21 is a less abstract example of code formatted using this strategy:

Example 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. Example 31-22 is an example in which it works:

Example 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. Example 31-23 is an example of how the style breaks down when it's used with a more complicated conditional:

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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.128.205.21