Tải bản đầy đủ (.pdf) (617 trang)

code craft - the practice of writing excellent code (2006)

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (2.6 MB, 617 trang )

by Pete Goodliffe
San Francisco
®
CODE CRAFT. Copyright © 2007 by Pete Goodliffe.
All rights reserved. No part of this work may be reproduced or transmitted in any form or by any means, electronic or
mechanical, including photocopying, recording, or by any information storage or retrieval system, without the prior
written permission of the copyright owner and the publisher.
10 09 08 07 06 1 2 3 4 5 6 7 8 9
ISBN-10: 1-59327-119-0
ISBN-13: 978-1-59327-119-0
Publisher: William Pollock
Production Editor: Elizabeth Campbell
Cover Design: Octopod Studios
Text Illustrations: David Brookes
Technical Reviewer: Jon Jagger
Copyeditor: Megan Dunchak
Compositors: Megan Dunchak, Riley Hoffman, and Christina Samuell
Proofreader: Stephanie Provines
For information on book distributors or translations, please contact No Starch Press, Inc. directly:
No Starch Press, Inc.
555 De Haro Street, Suite 250, San Francisco, CA 94107
phone: 415.863.9900; fax: 415.863.9950; ; www.nostarch.com
Library of Congress Cataloging-in-Publication Data
Goodliffe, Pete.
Code craft: the practice of writing excellent code / Pete Goodliffe.
p. cm.
Includes bibliographical references and index.
ISBN-13: 978-1-59327-119-0
ISBN-10: 1-59327-119-0
1. Computer programming. 2. Programming languages (Electronic computers) 3. Computer software


Development. I. Title.
QA76.6.G656 2006
005.1 dc22
2006015575
No Starch Press and the No Starch Press logo are registered trademarks of No Starch Press, Inc. Other product and
company names mentioned herein may be the trademarks of their respective owners. Rather than use a trademark
symbol with every occurrence of a trademarked name, we are using the names only in an editorial fashion and to the
benefit of the trademark owner, with no intention of infringement of the trademark.
The information in this book is distributed on an “As Is” basis, without warranty. While every precaution has been
taken in the preparation of this work, neither the author nor No Starch Press, Inc. shall have any liability to any
person or entity with respect to any loss or damage caused or alleged to be caused directly or indirectly by the
information contained in it.
All text illustrations copyright © 2006 by David Brookes.
Printed on recycled paper in the United States of America
To Bryony, my wonderful wife.
To Alice, who drew balloons on this book.
To Millie, who tasted this book.
And to Jessica, who never got a chance to.
Psalm 150

BRIEF CONTENTS
Preface xxvii
Acknowledgments xxxv
About the Author xxxvii
PART I
AT THE CODEFACE 1
Chapter 1: On the Defensive
Defensive Programming Techniques for Robust Code 3
Chapter 2: The Best Laid Plans
The Layout and Presentation of Source Code 23

Chapter 3: What’s in a Name?
Giving Meaningful Things Meaningful Names 39
Chapter 4: The Write Stuff
Techniques for Writing “Self-Documenting” Code 57
Chapter 5: A Passing Comment
How to Write Code Comments 73
Chapter 6: To Err Is Human
Dealing with the Inevitable—Error Conditions in Code 89
PART II
THE SECRET LIFE OF CODE 109
Chapter 7: The Programmer’s Toolbox
Using Tools to Construct Software 111
Chapter 8: Testing Times
The Black Art of Testing Code 129
viii Brief Contents
Chapter 9: Finding Fault
Debugging: What to Do When Things Go Wrong 153
Chapter 10: The Code That Jack Built
Mechanisms to Turn Source Code into Executable Code 175
Chapter 11: The Need for Speed
Optimizing Programs and Writing Efficient Code 199
Chapter 12: An Insecurity Complex
Writing Secure Programs 223
PART III
THE SHAPE OF CODE 239
Chapter 13: Grand Designs
How to Produce Good Software Designs 241
Chapter 14: Software Architecture
Laying the Foundations of Software Design 261
Chapter 15: Software Evolution or Software Revolution?

How Does Code Grow? 279
PART IV
A HERD OF PROGRAMMERS? 293
Chapter 16: Code Monkeys
Fostering the Correct Attitude and Approach to Programming 295
Chapter 17: Together We Stand
Teamwork and the Individual Programmer 315
Chapter 18: Practicing Safe Source
Source Control and Self-Control 349
PART V
PART OF THE PROCESS 365
Chapter 19: Being Specific
Writing Software Specifications 367
Chapter 20: A Review to a Kill
Performing Code Reviews 385
Brief Contents ix
Chapter 21: How Long Is a Piece of String?
The Black Art of Software Timescale Estimation 401
PART VI
VIEW FROM THE TOP 417
Chapter 22: Recipe for a Program
Code Development Methodologies and Processes 419
Chapter 23: The Outer Limits
The Different Programming Disciplines 441
Chapter 24: Where Next?
All’s Well That Ends Well 459
Answers and Discussion 463
Bibliography 559
Index 565


CONTENTS IN DETAIL
PREFACE xxvii
What’s In It for Me? xxvii
Getting Better xxviii
Who Should Read This Book? xxix
What’s Covered? xxx
How This Book Is Organized xxx
The Chapters—A Closer Look xxxii
Part I: At The Codeface xxxii
Part II: The Secret Life of Code xxxii
Part III: The Shape of Code xxxii
Part IV: A Herd of Programmers xxxii
Part V: Part of the Process xxxii
Part VI: From the Top xxxii
How to Use This Book xxxiii
A Note to Mentors xxxiii
ACKNOWLEDGMENTS xxxv
ABOUT THE AUTHOR xxxvii
PART I
AT THE CODEFACE
1
ON THE DEFENSIVE
Defensive Programming Techniques for Robust Code 3
Toward Good Code 4
Assume the Worst 4
What Is Defensive Programming? 6
The Big, Bad World 8
Techniques for Defensive Programming 8
Employ a Good Coding Style and Sound Design 9
Don’t Code in a Hurry 9

Trust No One 10
Write Code for Clarity, Not Brevity 10
Don’t Let Anyone Tinker with Stuff They Shouldn’t 11
Compile with All Warnings Switched On 11
Use Static Analysis Tools 12
Use Safe Data Structures 12
Check Every Return Value 13
Handle Memory (and Other Precious Resources) Carefully 13
xii Contents in Detail
Initialize All Variables at Their Points of Declaration 14
Declare Variables as Late as Possible 14
Use Standard Language Facilities 14
Use a Good Diagnostic Logging Facility 15
Cast Carefully 15
The Fine Print 15
Constraints 16
What to Constrain 17
Removing Constraints 18
In a Nutshell 20
See Also 20
Get Thinking 21
Mull It Over 21
Getting Personal 22
2
THE BEST LAID PLANS
The Layout and Presentation of Source Code 23
What’s the Big Deal? 24
Know Your Audience 25
What Is Good Presentation? 26
Brace Yourself 26

K&R Brace Style 27
Exdented Brace Style 27
Indented Brace Style 29
Other Brace Styles 29
One Style to Rule Them All 30
House Styles (and Where to Stick Them) 31
Setting the Standard 33
Righteous Wars? 35
In a Nutshell 35
See Also 37
Get Thinking 37
Mull It Over 37
Getting Personal 38
3
WHAT’S IN A NAME?
Giving Meaningful Things Meaningful Names 39
Why Should We Name Well? 41
What Do We Name? 41
Name Games 42
Descriptive 42
Technically Correct 42
Idiomatic 43
Appropriate 43
The Nuts and Bolts 44
Naming Variables 44
Naming Functions 45
Contents in Detail xiii
Naming Types 46
Naming Namespaces 47
Naming Macros 48

Naming Files 48
A Rose by Any Other Name 49
Be Consistent 50
Exploit Context 51
Use Names to Your Advantage 51
In a Nutshell 52
See Also 53
Get Thinking 53
Mull It Over 53
Getting Personal 55
4
THE WRITE STUFF
Techniques for Writing “Self-Documenting” Code 57
Self-Documenting Code 59
Techniques for Self-Documenting Code 61
Write Simple Code with Good Presentation 61
Choose Meaningful Names 62
Decompose into Atomic Functions 62
Choose Descriptive Types 63
Name Constants 63
Emphasize Important Code 64
Group-Related Information 64
Provide a File Header 64
Handle Errors Appropriately 65
Write Meaningful Comments 65
Practical Self-Documentation Methodologies 66
Literate Programming 66
Documentation Tools 67
In a Nutshell 69
See Also 70

Get Thinking 71
Mull It Over 71
Getting Personal 72
5
A PASSING COMMENT
How to Write Code Comments 73
What Is a Code Comment? 74
What Do Comments Look Like? 75
How Many Comments? 75
What Goes Inside Our Comments? 76
Explain Why, Not How 76
Don’t Describe the Code 76
xiv Contents in Detail
Don’t Replace Code 76
Keep It Useful 77
Avoid Distractions 78
In Practice 79
A Comment on Aesthetics 80
Consistency 80
Clear Block Comments 80
Indenting Comments 81
End-of-Line Comments 81
Helping You to Read the Code 81
Choose a Low-Maintenance Style 82
Breakwaters 82
Flags 83
File Header Comments 83
Working with Comments 84
Helping You to Write Routines 84
Bug-Fix Notices 85

Comment Rot 85
Maintenance and the Inane Comment 86
In a Nutshell 86
See Also 87
Get Thinking 87
Mull It Over 87
Getting Personal 88
6
TO ERR IS HUMAN
Dealing with the Inevitable—Error Conditions in Code 89
From Whence It Came 90
Error-Reporting Mechanisms 91
No Reporting 91
Return Values 92
Error Status Variables 93
Exceptions 93
Signals 95
Detecting Errors 95
Handling Errors 96
When to Deal with Errors 97
Possible Reactions 98
Code Implications 100
Raising Hell 104
Managing Errors 105
In a Nutshell 106
See Also 107
Get Thinking 107
Mull It Over 107
Getting Personal 108
Contents in Detail xv

PART II
THE SECRET LIFE OF CODE
7
THE PROGRAMMER’S TOOLBOX
Using Tools to Construct Software 111
What Is a Software Tool? 112
Why Worry About Tools? 114
Power Tools 115
Understand What It Can Do 115
Learn How to Drive it 116
Know What Tasks It’s Good For 116
Check That It’s Working 116
Have a Clear Route to Find Out More 117
Find Out When New Versions Appear 117
Which Tools? 117
Source Editing Tools 118
Code Construction Tools 120
Debugging and Investigative Tools 123
Language Support Tools 124
Miscellaneous Tools 125
In a Nutshell 126
See Also 127
Get Thinking 128
Mull It Over 128
Getting Personal 128
8
TESTING TIMES
The Black Art of Testing Code 129
Reality Check 131
Who, What, When, and Why? 132

Why We Test 132
Who Tests 133
What Testing Involves 133
When We Test 134
Testing Isn’t Hard . . . 135
The Types of Test 138
Choosing Unit Test Cases 142
Design for Test 144
Look! No Hands! 144
The Face of Failure 145
Can You Manage It? 146
Fault-Tracking System 147
Bug Reviews 148
xvi Contents in Detail
In a Nutshell 149
See Also 150
Get Thinking 150
Mull It Over 150
Getting Personal 151
9
FINDING FAULT
Debugging: What to Do When Things Go Wrong 153
The Facts of Life 154
Nature of the Beast 155
The View from 1,000 Feet 155
The View from the Ground 156
The View from the Trenches 158
Pest Extermination 160
The Low Road 161
The High Road 161

Bug Hunting 162
Compile-Time Errors 162
Run-Time Errors 164
How to Fix Faults 167
Prevention 169
Wasp Spray, Slug Repellent, Fly Paper . . . 169
Debugger 169
Memory Access Validator 170
System Call Tracing 170
Core Dump 170
Logging 170
In a Nutshell 171
See Also 172
Get Thinking 173
Mull It Over 173
Getting Personal 173
10
THE CODE THAT JACK BUILT
Mechanisms to Turn Source Code into Executable Code 175
Language Barriers 176
Interpreted Languages 177
Compiled Languages 178
Byte-Compiled Languages 179
Making Mountains out of Molehills 179
Building Builds 181
What Makes a Good Build System? 184
Simplicity 184
Uniformity 184
Repeatable and Reliable 185
Contents in Detail xvii

Atomic 186
Coping with Errors 187
The Mechanics 187
Choice of Targets 187
Housekeeping 189
Dependencies 189
Automated Builds 190
Build Configuration 191
Recursive Make 192
Please Release Me 192
Jack-of-All-Trades, Buildmaster Of? 194
In a Nutshell 195
See Also 195
Get Thinking 196
Mull It Over 196
Getting Personal 196
11
THE NEED FOR SPEED
Optimizing Programs and Writing Efficient Code 199
What Is Optimization? 200
What Makes Code Suboptimal? 201
Why Not Optimize? 202
Alternatives 204
Why Optimize? 205
The Nuts and Bolts 206
Prove You Need to Optimize 206
Identify the Slowest Code 207
Testing the Code 208
Optimizing the Code 209
After Optimization 209

Optimization Techniques 210
Design Changes 210
Code Changes 213
Writing Efficient Code 217
In a Nutshell 219
See Also 219
Get Thinking 220
Mull It Over 220
Getting Personal 221
12
AN INSECURITY COMPLEX
Writing Secure Programs 223
The Risks 224
The Opposition 226
Excuses, Excuses 228
xviii Contents in Detail
Feeling Vulnerable 229
Insecure Design and Architecture 229
Buffer Overrun 229
Embedded Query Strings 230
Race Conditions 231
Integer Overflow 231
Protection Racket 232
System Installation Techniques 233
Software Design Techniques 234
Code Implementation Techniques 235
Procedural Techniques 236
In a Nutshell 236
See Also 237
Get Thinking 237

Mull It Over 237
Getting Personal 238
PART III
THE SHAPE OF CODE
13
GRAND DESIGNS
How to Produce Good Software Designs 241
Programming as Design 242
What Do We Design? 243
What’s All the Fuss About? 244
Good Software Design 245
Simplicity 246
Elegance 247
Modularity 247
Good Interfaces 248
Extensibility 251
Avoid Duplication 251
Portability 252
Idiomatic 252
Well-Documented 253
How to Design Code 253
Design Methods and Processes 254
Design Tools 255
In a Nutshell 257
See Also 258
Contents in Detail xix
Get Thinking 258
Mull It Over 258
Getting Personal 259
14

SOFTWARE ARCHITECTURE
Laying the Foundations of Software Design 261
What Is Software Architecture? 262
Software Blueprints 262
Points of View 263
Where and When Do You Do It? 264
What Is It Used For? 265
Of Components and Connections 266
What Is Good Architecture? 268
Architectural Styles 269
No Architecture 269
Layered Architecture 270
Pipe and Filter Architecture 271
Client/Server Architecture 271
Component-Based Architecture 273
Frameworks 274
In a Nutshell 275
See Also 276
Get Thinking 276
Mull It Over 276
Getting Personal 277
15
SOFTWARE EVOLUTION OR SOFTWARE REVOLUTION?
How Does Code Grow? 279
Software Rot 281
The Warning Signs 282
How Does Code Grow? 284
Believe the Impossible 286
What Can We Do About This? 287
Writing New Code 287

Maintenance of Existing Code 288
In a Nutshell 290
See Also 290
Get Thinking 291
Mull It Over 291
Getting Personal 292
xx Contents in Detail
PART IV
A HERD OF PROGRAMMERS?
16
CODE MONKEYS
Fostering the Correct Attitude and Approach to Programming 295
Monkey Business 296
The Eager Coder 297
The Code Monkey 298
The Guru 299
The Demiguru 300
The Arrogant Genius 300
The Cowboy 302
The Planner 302
The Old Timer 303
The Zealot 304
The Monocultured Programmer 305
The Slacker 306
The Reluctant Team Leader 306
You 307
The Ideal Programmer 308
So What? 308
The Stupidest of Men 309
In a Nutshell 310

See Also 310
Action Sheet 311
Get Thinking 312
Mull It Over 312
Getting Personal 312
17
TOGETHER WE STAND
Teamwork and the Individual Programmer 315
Our Teams—The Big Picture 316
Team Organization 318
Management Approach 318
Division of Responsibility 318
Organization and Code Structure 320
Teamwork Tools 320
Team Diseases 322
Tower of Babel 322
Dictatorship 324
Development Democracy 325
Satellite Station 327
Contents in Detail xxi
The Grand Canyon 329
Quicksand 330
Lemmings 332
Personal Skills and Characteristics for Good Teamwork 333
Communication 333
Humility 334
Dealing with Conflict 334
Learning and Adaptability 335
Know Your Limitations 336
Teamwork Principles 336

Collective Code Ownership 336
Respect Other People’s Code 337
Code Guidelines 337
Define Success 337
Define Responsibility 338
Avoid Burnout 338
The Team Life Cycle 339
Team Creation 339
Team Growth 341
Teamwork 342
Team Closure 343
In a Nutshell 345
See Also 346
Action Sheet 347
Get Thinking 348
Mull It Over 348
Getting Personal 348
18
PRACTICING SAFE SOURCE
Source Control and Self-Control 349
Our Responsibility 350
Source Control 351
Revision Control 352
Access Control 353
Working with the Repository 354
Leave Branching to the Trees 354
A Brief History of Source Control 356
Configuration Management 356
Backups 358
Releasing Source Code 359

Wherever I Lay My Source 360
In a Nutshell 361
See Also 362
Get Thinking 363
Mull It Over 363
Getting Personal 363
xxii Contents in Detail
PART V
PART OF THE PROCESS
19
BEING SPECIFIC
Writing Software Specifications 367
What Are They, Specifically? 368
The Types of Specification 369
Requirements Specification 371
Functional Specification 373
System Architecture Specification 373
User Interface Specification 374
Design Specification 374
Test Specification 375
What Should Specifications Contain? 376
The Specification-Writing Process 379
Why Don’t We Write Specifications? 381
In a Nutshell 383
See Also 383
Get Thinking 384
Mull It Over 384
Getting Personal 384
20
A REVIEW TO A KILL

Performing Code Reviews 385
What Is a Code Review? 386
When Do You Review? 387
Whether to Review 388
Which Code to Review 389
Performing Code Reviews 389
Code Review Meetings 390
Integration Reviews 392
Review Your Attitudes 393
The Author’s Attitude 393
The Reviewer’s Attitude 394
Code Perfection 395
Beyond the Code Review 396
In a Nutshell 397
See Also 397
Checklist 398
Get Thinking 399
Mull It Over 399
Getting Personal 399
Contents in Detail xxiii
21
HOW LONG IS A PIECE OF STRING?
The Black Art of Software Timescale Estimation 401
A Stab in the Dark 402
Why Is Estimation So Hard? 403
Under Pressure 405
Practical Ways to Estimate 406
The Planning Game 409
Keep Up! 412
In a Nutshell 415

See Also 415
Get Thinking 416
Mull It Over 416
Getting Personal 416
PART VI
VIEW FROM THE TOP
22
RECIPE FOR A PROGRAM
Code Development Methodologies and Processes 419
Programming Styles 420
Structured Programming 421
Object-Oriented Programming 422
Functional Programming 423
Logic Programming 424
Recipes: The How and the What 424
Development Processes 425
Ad Hoc 426
Waterfall Model 427
SSADM and PRINCE 429
V Model 430
Prototyping 430
Iterative and Incremental Development 432
Spiral Model 432
Agile Methodologies 433
Other Development Processes 434
Enough, Already! 435
Pick a Process 436
In a Nutshell 437
See Also 438
Get Thinking 438

Mull It Over 438
Getting Personal 439
xxiv Contents in Detail
23
THE OUTER LIMITS
The Different Programming Disciplines 441
Applications Programming 442
Shrink-Wrap Software 443
Custom Applications 444
Games Programming 445
Systems Programming 446
Embedded Programming 447
Distributed Programming 450
Web Application Programming 451
Enterprise Programming 453
Numerical Programming 454
So What? 455
In a Nutshell 456
See Also 456
Get Thinking 457
Mull It Over 457
Getting Personal 457
24
WHERE NEXT?
All’s Well That Ends Well 459
But What Now? 460
ANSWERS AND DISCUSSION 463
Chapter 1: On the Defensive 463
Mull It Over 463
Getting Personal 465

Chapter 2: The Best Laid Plans 466
Mull It Over 466
Getting Personal 471
Chapter 3: What’s in a Name? 474
Mull It Over 474
Getting Personal 478
Chapter 4: The Write Stuff 480
Mull It Over 480
Getting Personal 484
Chapter 5: A Passing Comment 485
Mull It Over 485
Getting Personal 486
Chapter 6: To Err Is Human 487
Mull It Over 487
Getting Personal 490
Chapter 7: The Programmer’s Toolbox 491
Mull It Over 491
Getting Personal 492
Contents in Detail xxv
Chapter 8: Testing Times 494
Mull It Over 494
Getting Personal 498
Chapter 9: Finding Fault 500
Mull It Over 500
Getting Personal 502
Chapter 10: The Code That Jack Built 502
Mull It Over 502
Getting Personal 508
Chapter 11: The Need for Speed 510
Mull It Over 510

Getting Personal 514
Chapter 12: An Insecurity Complex 515
Mull It Over 515
Getting Personal 518
Chapter 13: Grand Designs 519
Mull It Over 519
Getting Personal 521
Chapter 14: Software Architecture 522
Mull It Over 522
Getting Personal 525
Chapter 15: Software Evolution or Software Revolution? 527
Mull It Over 527
Getting Personal 530
Chapter 16: Code Monkeys 532
Mull It Over 532
Chapter 17: Together We Stand 533
Mull It Over 533
Getting Personal 538
Chapter 18: Practicing Safe Source 539
Mull It Over 539
Getting Personal 542
Chatper 19: Being Specific 544
Mull It Over 544
Getting Personal 546
Chapter 20: A Review to a Kill 547
Mull It Over 547
Getting Personal 549
Chapter 21: How Long Is a Piece of String? 550
Mull It Over 550
Getting Personal 552

Chapter 22: Recipe for a Program 553
Mull It Over 553
Getting Personal 556
Chapter 23: The Outer Limits 557
Mull It Over 557
Getting Personal 558
BIBLIOGRAPHY 559
INDEX 565

×