Code Complete

(A detailed book review)

Book Information

Code Complete Book

Code Complete

A Practical Handbook of Software Construction

By Steve McConnell

Microsoft Press, 1993, 857 pages

ISBN 1556154844

Summary

Code Complete is programming classic. It is 900 pages of intelligent and fascinating discussion about coding software.

Introduction

This book is not about how to program in a particular language, how to use SSADM or other methodologies. This book is about improving the way that you work throughout the development cycle.

The author describes the development process as being everything from the technical, detailed design stage, right through to the integrated testing. This is the jurisdiction, or domain, of the programmer.

With an immense bibliography, the author has combined theories, common practices and hard data to make his points. Sometimes, however, he completely contradicts the commonplace practices. Here is a man who supports established practices, but backs his own convictions where they differ. Subjectivity surfaces on occasion with statements such as "If you come across one of these clowns, ask him the following". On the whole, there is the distinct impression that the author was motivated to write this book in order to help programmers, and related IT staff.

References to personal experience punctuate bibliographic references in order to put the point across. Clearly this man knows his stuff, and is not simply trying to pedal his own particular point of view that has never been proven. The author has developed his techniques over time, and has then decided to write a book on the subject. Where the purpose of his methodologies is nebulous, he backs them up with hard data.

Summary of Points

Here is a summary of the points that I believe are particularly of note.

1.       Software Accretion Method. The author recommends an accretion approach to software construction. This means the method of initially building the most basic working system possible, and then adding on layers piece by piece.

2.       Prerequisites. It seems obvious, but it is important to have all of the requirements in place before time is spent on detailed design or construction. Ensure that all the system prerequisites are outlined. The author also describes the "Myth of Stable Requirements". The important thing is to manage changes properly.

3.       Use of PDL. This is a section that I found particularly fascinating, in the section dealing with designing Routine. PDL stands for Programming Definition Language. PDL is a language similar in purpose to pseudo code, but is more abstract, using statements that resemble spoken English. The method here is to design a routine in PDL and then use the statements to form the basis of the routine. The PDL statements become the comment lines in the routine, and the functionality is filled in between the comments. This method allows the design of the routine to remain a constant, and to be clearly visible when viewing the code.

4.       Routines and Modules. The author spends a lot of time describing quality. This is particularly apparent with coding modules and routines. The author lists good and bad reasons for writing routines, and how to write quality routines and modules.

5.       Abstraction and Naming. One of the most recurring themes throughout the book is abstraction. This theme is prominent when the author discusses naming standards. For routines, modules, variables, constants and literals, abstract naming standards are extremely useful. They allow code reading to be made easier, and help to describe the program in the problem domain.

6.       Layout and Style. After mentioning quality in routine design and use, the author outlines the correct layout and styles of coding to use. Good and bad examples are shown, and the reasons for the choice of layout are mentioned. Also mentioned is how much of a sensitive area layout and programming styles are, including the hundred years war that is the GOTO debate.

7.       Management. The book is not only focused on the programmer. There is a section that is for the attention of the Programming Manager. This deals with everything from planning and scheduling right through to managing the people. When discussing planning, the importance of measurement is also mentioned. Apart from progress, quality also needs to be measured. Several methods for measuring are suggested, including formal and informal reviews.

8.       Testing. There are more opinions and suggestions for testing than just about anything else in software development. This book is no exception, however, the author describes testing in sections of Unit testing, Functional Testing, Integration Testing and Live Testing. Methodologies for all of these areas are outlined.

9.       Optimization. There may be times when a program needs to become more streamlined. The author discusses the use of code tuning techniques, and the most important issue of when to optimize and when to leave it alone.

Table of Contents

1.      Understanding Software Construction. 8

1.1.    Metaphors. 8

1.2.    Writing Code. 8

1.3.    Summary. 9

1.4.    Forwarding Actions. 9

2.      Prerequisites to Construction. 9

2.1.    Importance. 9

2.2.    Problem Definition. 10

2.3.    Requirements. 10

2.4.    Architecture. 11

2.5.    Language. 11

2.6.    Programming Conventions. 11

2.7.    Time to spend on Pre-Requisites. 11

2.8.    Adapting Pre-Requisites. 11

2.9.    Summary. 12

2.10.     Forwarding Actions. 12

3.      Building a Routine. 12

3.1.    Summary of Steps. 12

3.2.    PDL for Pros. 12

3.3.    Design the Routine. 12

3.4.    Code the Routine. 13

3.5.    Formal Checking. 13

3.6.    Summary. 13

3.7.    Forwarding Actions. 13

4.      High Quality Routines. 13

4.1.    Valid Reasons to Create a Routine. 13

4.2.    Good Routine Names. 14

4.3.    Strong Cohesion. 14

4.4.    Loose Coupling. 14

4.5.    How Long Can a Routine be?. 14

4.6.    Defensive Programming. 15

4.7.    Use of Routine Parameters. 15

4.8.    Consider the use of Functions. 15

4.9.    Summary. 15

4.10.     Forwarding Actions. 15

5.      Modules. 16

5.1.    Modularity: Cohesion and Coupling. 16

5.1.1.    Cohesion. 16

5.1.2.    Coupling. 16

5.2.    Information Hiding. 16

5.2.1.    Secrets and the Right to Privacy. 16

5.2.2.    Common Secrets. 16

5.2.3.    Barriers to Information Hiding. 17

5.3.    Good Reasons to Create a Module. 17

5.4.    Summary. 17

5.5.    Forwarding Actions. 17

6.      High Level Design. 17

6.1.    Introduction to Software Design. 17

6.2.    Structured Design. 18

6.2.1.    Choosing Components to Modularize. 18

6.3.    Object-Oriented Design. 18

6.3.1.    Key Ideas.18

6.3.2.    Design Steps. 18

6.3.3.    Typical Components. 19

6.4.    Comments on Popular Methodologies. 19

6.4.1.    When to use Structured Design. 19

6.4.2.    When to use Information Hiding. 19

6.4.3.    When to use Object Oriented Design. 19

6.5.    Round Trip Design. 19

6.6.    Design is a Heuristic. 19

6.7.    How to solve it. 19

6.8.    Summary. 20

6.9.    Forwarding Actions. 20

7.      Creating Data. 20

7.1.    Reasons to create your own Data Types. 20

7.2.    Guidelines for creating Data Types. 20

7.3.    Making Variable Declarations Easy. 20

7.4.    Guidelines for Initializing Data. 20

7.5.    Summary. 20

7.6.    Forwarding Actions. 21

8.      The Power of Data Names. 21

8.1.    Considerations in choosing good names. 21

8.1.1.    The Effect of Scope on Variable names. 21

8.1.2.    Computed-Value Qualifiers in Variable Names. 21

8.2.    Naming Specific Types of Data. 21

8.3.    The Power of Naming Conventions. 21

8.4.    Informal Naming Conventions. 21

8.5.    Hungarian Notation. 22

8.6.    Short Names. 22

8.7.    Kinds of Names to avoid. 22

8.8.    Summary. 22

8.9.    Forwarding Actions. 22

9.      General Issues in Using Variables. 22

9.1.    Scope. 22

9.2.    Persistence. 23

9.3.    Binding Time. 23

9.3.1.    Code Time Binding. 23

9.3.2.    Compiler Time Binding. 23

9.3.3.    Run Time Binding. 23

9.4.    Relationship between Data Structures and Control Structures. 23

9.5.    Use each Variable for one purpose only. 23

9.6.    Global Variables. 23

9.6.1.    Common Problems. 23

9.6.2.    Reasons to use Global Data. 23

9.6.3.    How to Reduce the Risks of Using Global Data. 23

9.6.4.    Use Access Routines instead of Global Data. 24

9.7.    Summary. 24

9.8.    Forwarding Actions. 24

10.    Fundamental Data Types. 24

10.1.     General Numbers. 24

10.2.     Integers. 24

10.3.     Floating Point Numbers. 24

10.4.     Characters and Strings. 24

10.5.     Booleans. 25

10.6.     Enumerations. 25

10.7.     Named Constants. 25

10.8.     Arrays. 25

10.9.     Summary. 25

10.10.    Forwarding Actions. 25

11.    Organizing Straight Line Code.25

11.1.     Statements that must be in a specific order. 25

11.2.     Statements who's order does not matter. 25

12.    Using Conditions. 26

12.1.     IF statements. 26

12.2.     IF chains. 26

12.3.     CASE statements. 26

12.4.     Tips. 26

13. Controlling Loops.26

13.1.     Select the kind of Loop to use.26

13.2.     Controlling the Loop.26

13.3.     Creating Loops form the inside out.27

13.4.     Correspondence between loops and arrays. 27

14.    Unusual Control Structures. 27

14.1.     GOTO. 27

14.2.     RETURN/EXIT. 27

14.3.     Recursion. 27

15.    General Control Issues. 28

15.1.     Boolean Expressions. 28

15.2.     Compound Statements. 28

15.3.     NULL Statements. 28

15.4.     Taming Dangerously Deep Nesting. 28

15.5.     The Power of Structured Programming. 28

15.6.     Control Structures and Complexity. 28

16.    Layout and Style. 29

16.1.     Fundamentals. 29

16.2.     Layout Techniques. 29

16.2.1. White Space. 29

16.2.2.   Parentheses. 29

16.3.     Layout Styles. 29

16.3.1. Pure Blocks. 29

16.3.2. End-line Layout30

16.3.3. BEGIN-END Block Boundaries. 30

16.4.     Laying Out Control Structures. 30

16.4.1.   Fine Points of Formatting Control Structures. 30

16.4.2.   Other Considerations.30

16.5.     Laying Out Individual Statements. 30

16.5.1.   Statement Length. 30

16.5.2. Using spaces for clarity. 31

16.5.3.   Aligning Related Statements. 31

16.5.4.   Format Continuation Lines. 31

16.5.5. Use Only One Statement Per Line. 31

16.5.6.   Laying Out Data Declarations. 31

16.6.     Laying Out Comments.31

16.7.     Laying Out Routines.31

16.8.     Laying Out File, Modules and Programs.31

16.9.     Summary.31

16.10.    Forwarding Actions. 32

17.    Self-Documenting Code.32

17.1.     External Documentation.32

17.2.     Programming Styles as Documentation.32

17.3.     Commenting.32

17.3.1.   Types of Comments. 32

17.3.2.   Commenting Efficiency. 32

17.4.     Commenting Techniques.32

17.4.1.   Individual Lines.32

17.4.2.   Commenting Paragraphs. 32

17.4.3.   Commenting Data Declarations. 33

17.4.4.   Commenting Control Structures. 33

17.4.5. Commenting Routines. 33

17.4.6.   Commenting Files, Modules and Programs. 33

17.4.7.   Using the "Book" Paradigm for commenting. 33

17.5.     Summary. 33

17.6.     Forwarding Actions. 34

18.    Programming Tools. 34

18.1.     Design Tools. 34

18.2.     Source Code Tools. 34

18.2.1.   Editing. 34

18.2.2.   Browsing. 34

18.2.3.   Analyzing Code Quality. 34

18.2.4.   Restructuring Source Code. 35

18.2.5.   Version Control35

18.2.6.   Data Dictionaries. 35

18.3.     Executable Code Tools. 35

18.3.1.   Code Creation.35

18.3.2.   Debugging.35

18.3.3.   Testing.35

18.3.4.   Code Tuning.35

18.4.     Tool-Orientated environments.35

18.5.     Building your own tools.36

18.6.     Summary. 36

18.7.     Forwarding Actions. 36

19.    How Program size Affects Construction. 36

19.1.     Effect of Project Size on Development Activities. 36

19.2.     Effect of Project Size on Errors. 36

19.3.     Effect of Project Size on Productivity. 36

20.    Managing Construction. 36

20.1.     Encouraging Good Coding.36

20.1.1.   Considering in Setting Standards.36

20.1.2.   Techniques.37

20.2.     Configuration Management. 37

20.2.1.   What is configuration Management?. 37

20.2.2.   Software Design Changes. 37

20.2.3.   Software Code changes. 37

20.3.     Estimating a Construction Schedule. 37

20.3.1.   Approaches. 37

20.3.2.   Establish Objectives. 37

20.3.3.   Influences on Schedule. 37

20.3.4.   Estimation vs. Control38

20.3.5.   What to do if you are behind. 38

21.    Software Metrics.38

21.1.     Treating Programmers as people. 38

21.2.     Variations in performance and quality. 38

21.3.     Religious Issues. 38

21.4.     Physical Environment. 39

21.5.     Summary. 39

22.    The Software Quality Landscape. 39

22.1.     Characteristics of Software Quality. 39

22.2.     Techniques for improving Software Quality. 39

22.3.     Relative Effectiveness of techniques. 39

22.3.1.   Percentage of Errors found. 39

22.3.2.   Cost of finding defects. 40

22.3.3.   Cost of fixing defects. 40

22.4.     When to do a QA. 40

22.5.     General Principle of Software Quality. 40

22.6.     Summary. 40

22.7.     Forwarding Actions. 40

23.    Reviews. 40

23.1.     The role of reviews. 40

23.1.1.   Reviews complement other QA techniques. 40

23.1.2.   Reviews remove corporate structure.40

23.1.3.   Reviews assess Quality and Progress.40

23.1.4.   Reviews also apply before construction.41

23.2.     Inspections.41

23.2.1.   Roles During Inspections. 41

23.2.2.   Procedure for Inspections. 41

23.3.     Other kinds of reviews. 41

23.3.1.   Walkthroughs.41

23.3.2.   Code Reading.41

23.3.3.   "Dog and Pony shows"42

24.    Unit Testing. 42

24.1.     The Role of Unit Testing. 42

24.2.     Testing During Construction. 42

24.3.     The Testing Bag of Tricks. 42

24.3.1.   Incomplete Testing. 42

24.3.2.   Structured Basis Testing. 42

24.3.3.   Data Flow Testing. 42

24.3.4.   Equivalence Partitioning. 42

24.3.5.   Error Guessing. 42

24.3.6.   Boundary Analysis. 42

24.3.7.   Classes of Bad Data. 43

24.3.8.   Classes of Good Data. 43

24.3.9.   Use test cases that allow easy manual checks.43

24.4.     Typical Errors. 43

24.4.1.   Which routines contain the most errors?. 43

24.4.2. Errors by Classification. 43

24.4.3.   Proportion of Errors Resulting from faulty construction. 43

24.4.4.   How many errors should you expect to find. 43

24.4.5.   Testing itself43

24.5.     Test Support Tools. 44

24.5.1.   Scaffolding. 44

24.5.2.   Results Comparators. 44

24.5.3.   Test Data Generators. 44

24.5.4. Coverage Monitors. 44

24.5.5. Symbolic Debuggers. 44

24.5.6.   System Perturbers. 44

24.5.7.   Error Databases.44

24.6.     Improving Testing. 44

24.7.     Planning to test. 44

24