《Clean Code(评注版)》
Chapter 1: Clean Code(新增评注47条) 1
There Will Be Code 2
Bad Code 3
The Total Cost of Owning a Mess 5
The Grand Redesign in the Sky 6
Attitude 6
The Primal Conundrum 7
The Art of Clean Code? 8
What Is Clean Code? 9
Schools of Thought 15
We Are Authors 17
The Boy Scout Rule 18
Prequel and Principles 18
Conclusion 18
Bibliography 19
Chapter 2: Meaningful Names(新增评注19条) 21
Introduction 21
Use Intention-Revealing Names 22
Avoid Disinformation 24
Make Meaningful Distinctions 25
Use Pronounceable Names 26
Use Searchable Names 27
Avoid Encodings 28
Hungarian Notation 28
Member Prefixes 29
Interfaces and Implementations 29
Avoid Mental Mapping 30
Class Names 30
Method Names 30
Don’t Be Cute 31
Pick One Word per Concept 32
Don’t Pun 32
Use Solution Domain Names 33
Use Problem Domain Names 33
Add Meaningful Context 33
Don’t Add Gratuitous Context 35
Final Words 36
Chapter 3: Functions(新增评注25条) 39
Small! 42
Blocks and Indenting 43
Do One Thing 44
Sections within Functions 45
One Level of Abstraction per Function 45
Reading Code from Top to Bottom:The Stepdown Rule 46
Switch Statements 46
Use Descriptive Names 48
Function Arguments 49
Common Monadic Forms 50
Flag Arguments 50
Dyadic Functions 51
Triads 52
Argument Objects 52
Argument Lists 52
Verbs and Keywords 53
Have No Side Effects 53
Output Arguments 54
Command Query Separation 55
Prefer Exceptions to Returning Error Codes 56
Extract Try/Catch Blocks 57
Error Handling Is One Thing 57
The Error.java Dependency Magnet 57
Don’t Repeat Yourself 58
Structured Programming 59
How Do You Write Functions Like This? 59
Conclusion 60
SetupTeardownIncluder 60
Bibliography 62
Chapter 4: Comments(新增评注18条) 65
Comments Do Not Make Up for Bad Code 67
Explain Yourself in Code 68
Good Comments 68
Legal Comments 68
Informative Comments 69
Explanation of Intent 69
Clarification 70
Warning of Consequences 71
TODO Comments 71
Amplification 72
Javadocs in Public APIs 72
Bad Comments 72
Mumbling 73
Redundant Comments 73
Misleading Comments 76
Mandated Comments 76
Journal Comments 77
Noise Comments 78
Scary Noise 80
Don’t Use a Comment When You Can Use a Function or
a Variable 80
Position Markers 80
Closing Brace Comments 81
Attributions and Bylines 82
Commented-Out Code 82
HTML Comments 83
Nonlocal Information 83
Too Much Information 84
Inobvious Connection 84
Function Headers 84
Javadocs in Nonpublic Code 85
Example 85
Bibliography 88
Chapter 5: Formatting(新增评注13条) 89
The Purpose of Formatting 90
Vertical Formatting 90
The Newspaper Metaphor 91
Vertical Openness Between Concepts 92
Vertical Density 93
Vertical Distance 94
Vertical Ordering 99
Horizontal Formatting 99
Horizontal Openness and Density 100
Horizontal Alignment 101
Indentation 103
Dummy Scopes 104
Team Rules 105
Uncle Bob’s Formatting Rules 106
Chapter 6: Objects and Data Structures(新增评注12条) 109
Data Abstraction 110
Data/Object Anti-Symmetry 111
The Law of Demeter 114
Train Wrecks 115
Hybrids 116
Hiding Structure 116
Data Transfer Objects 117
Active Record 118
Conclusion 118
Bibliography 119
Chapter 7: Error Handling(新增评注7条) 121
Use Exceptions Rather Than Return Codes 122
Write Your Try-Catch-Finally Statement First 123
Use Unchecked Exceptions 125
Provide Context with Exceptions 126
Define Exception Classes in Terms of a Caller’s Needs 126
Define the Normal Flow 128
Don’t Return Null 129
Don’t Pass Null 130
Conclusion 131
Bibliography 131
Chapter 8: Boundaries(新增评注6条) 133
Using Third-Party Code 134
Exploring and Learning Boundaries 136
Learning log4j 137
Learning Tests Are Better Than Free 138
Using Code That Does Not Yet Exist 139
Clean Boundaries 140
Bibliography 141
Chapter 9: Unit Tests(新增评注13条) 143
The Three Laws of TDD 144
Keeping Tests Clean 145
Tests Enable the -ilities 146
Clean Tests 147
Domain-Specific Testing Language 150
A Dual Standard 150
One Assert per Test 153
Single Concept per Test 154
F.I.R.S.T. 155
Conclusion 156
Bibliography 156
Chapter 10: Classes(新增评注12条) 157
Class Organization 158
Encapsulation 158
Classes Should Be Small! 158
The Single Responsibility Principle 161
Cohesion 162
Maintaining Cohesion Results in Many Small Classes 163
Organizing for Change 169
Isolating from Change 172
Bibliography 174
Chapter 11: Systems(新增评注10条) 175
How Would You Build a City? 176
Separate Constructing a System from Using It 176
Separation of Main 178
Factories 178
Dependency Injection 179
Scaling Up 180
Cross-Cutting Concerns 183
Java Proxies 184
Pure Java AOP Frameworks 186
AspectJ Aspects 189
Test Drive the System Architecture 190
Optimize Decision Making 191
Use Standards Wisely, When They Add Demonstrable Value 191
Systems Need Domain-Specific Languages 191
Conclusion 192
Bibliography 192
Chapter 12: Emergence(新增评注5条) 195
Getting Clean via Emergent Design 195
Simple Design Rule 1: Runs All the Tests 196
Simple Design Rules 2–4: Refactoring 196
No Duplication 197
Expressive 199
Minimal Classes and Methods 200
Conclusion 201
Bibliography 201
Chapter 13: Concurrency(新增评注15条) 203
Why Concurrency? 204
Myths and Misconceptions 205
Challenges 206
Concurrency Defense Principles 207
Single Responsibility Principle 207
Corollary: Limit the Scope of Data 207
Corollary: Use Copies of Data 208
Corollary: Threads Should Be as Independent as Possible 208
Know Your Library 209
Thread-Safe Collections 209
Know Your Execution Models 210
Producer-Consumer 210
Readers-Writers 211
Dining Philosophers 211
Beware Dependencies Between Synchronized Methods 212
Keep Synchronized Sections Small 212
Writing Correct Shut-Down Code Is Hard 212
Testing Threaded Code 213
Treat Spurious Failures as Candidate Threading Issues 214
Get Your Nonthreaded Code Working First 214
Make Your Threaded Code Pluggable 214
Make Your Threaded Code Tunable 215
Run with More Threads Than Processors 215
Run on Different Platforms 215
Instrument Your Code to Try and Force Failures 215
Hand-Coded 216
Automated 217
Conclusion 218
Bibliography 219
Chapter 14: Successive Refinement(新增评注18条) 221
Args Implementation 223
How Did I Do This? 228
Args: The Rough Draft 229
So I Stopped 240
On Incrementalism 241
String Arguments 243
Conclusion 280
关于第15章、第16章和第17章 281
Chapter 15: JUnit Internals 283
The JUnit Framework 284
Conclusion 297
Chapter 16: Refactoring SerialDate 299
First, Make It Work 300
Then Make It Right 302
Conclusion 316
Bibliography 316
Chapter 17: Smells and Heuristics 317
Comments 318
C1: Inappropriate Information 318
C2: Obsolete Comment 318
C3: Redundant Comment 318
C4: Poorly Written Comment 319
C5: Commented-Out Code 319
Environment 319
E1: Build Requires More Than One Step 319
E2: Tests Require More Than One Step 319
Functions 320
F1: Too Many Arguments 320
F2: Output Arguments 320
F3: Flag Arguments 320
F4: Dead Function 320
General 320
G1: Multiple Languages in One Source File 320
G2: Obvious Behavior Is Unimplemented 320
G3: Incorrect Behavior at the Boundaries 321
G4: Overridden Safeties 321
G5: Duplication 321
G6: Code at Wrong Level of Abstraction 322
G7: Base Classes Depending on Their Derivatives 323
G8: Too Much Information 324
G9: Dead Code 324
G10: Vertical Separation 324
G11: Inconsistency 324
G12: Clutter 325
G13: Artificial Coupling 325
G14: Feature Envy 325
G15: Selector Arguments 326
G16: Obscured Intent 327
G17: Misplaced Responsibility 328
G18: Inappropriate Static 328
G19: Use Explanatory Variables 329
G20: Function Names Should Say What They Do 329
G21: Understand the Algorithm 330
G22: Make Logical Dependencies Physical 330
G23: Prefer Polymorphism to If/Else or Switch/Case 331
G24: Follow Standard Conventions 332
G25: Replace Magic Numbers with Named Constants 332
G26: Be Precise 333
G27: Structure over Convention 333
G28: Encapsulate Conditionals 334
G29: Avoid Negative Conditionals 334
G30: Functions Should Do One Thing 334
G31: Hidden Temporal Couplings 335
G32: Don’t Be Arbitrary 336
G33: Encapsulate Boundary Conditions 336
G34: Functions Should Descend Only One Level of Abstraction 337
G35: Keep Configurable Data at High Levels 338
G36: Avoid Transitive Navigation 339
Java 339
J1: Avoid Long Import Lists by Using Wildcards 339
J2: Don’t Inherit Constants 340
J3: Constants versus Enums 341
Names 342
N1: Choose Descriptive Names 342
N2: Choose Names at the Appropriate Level of Abstraction 343
N3: Use Standard Nomenclature Where Possible 344
N4: Unambiguous Names 344
N5: Use Long Names for Long Scopes 345
N6: Avoid Encodings 345
N7: Names Should Describe Side-Effects 345
Tests 346
T1: Insufficient Tests 346
T2: Use a Coverage Tool 346
T3: Don’t Skip Trivial Tests 346
T4: An Ignored Test Is a Question about an Ambiguity 346
T5: Test Boundary Conditions 346
T6: Exhaustively Test Near Bugs 346
T7: Patterns of Failure Are Revealing 347
T8: Test Coverage Patterns Can Be Revealing 347
T9: Tests Should Be Fast 347
Conclusion 347
Bibliography 347
Appendix A: Concurrency II 349
Client/Server Example 349
The Server 349
Adding Threading 351
Server Observations 351
Conclusion 353
Possible Paths of Execution 353
Number of Paths 354
Digging Deeper 355
Conclusion 358
Knowing Your Library 359
Executor Framework 359
Nonblocking Solutions 359
Nonthread-Safe Classes 361
Dependencies Between Methods Can Break Concurrent Code 362
Tolerate the Failure 363
Client-Based Locking 363
Server-Based Locking 365
Increasing Throughput 366
Single-Thread Calculation of Throughput 367
Multithread Calculation of Throughput 367
Deadlock 368
Mutual Exclusion 369
Lock & Wait 369
No Preemption 369
Circular Wait 370
Breaking Mutual Exclusion 370
Breaking Lock & Wait 370
Breaking Preemption 371
Breaking Circular Wait 371
Testing Multithreaded Code 372
Tool Support for Testing Thread-Based Code 374
Conclusion 375
Tutorial: Full Code Examples 375
Client/Server Nonthreaded 375
Client/Server Using Threads 379
Appendix B: org.jfree.date.SerialDate 381
Appendix C: Cross References of Heuristics 441
Epilogue 445
Index 447