Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1530767
  • 博文数量: 465
  • 博客积分: 8915
  • 博客等级: 中将
  • 技术积分: 6365
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-30 15:05
文章分类

全部博文(465)

文章存档

2017年(33)

2016年(2)

2015年(4)

2014年(29)

2013年(71)

2012年(148)

2011年(178)

分类: Delphi

2012-11-16 15:33:13

传世经典书丛

Clean Code(评注版)

[]Robert C. Martin(罗伯特.马丁) 

韩磊 评注

ISBN 978-7-121-15505-5

20122月出版

定价:79.00

16

496

软件质量,不但依赖架构及项目管理,而且与代码质量紧密相关。这一点,无论是敏捷开发流派还是传统开发流派,都不得不承认。本书提出一种观念:代码质量与其整洁度成正比。干净的代码,既在质量上较为可靠,也为后期维护、升级奠定了良好的基础。本书作者给出了一系列行之有效的整洁代码操作实践。这些实践在本书中体现为一条条规则(或称启示),并辅以来自现实项目的正、反两方面的范例。只要遵循这些规则,就能写出干净的代码,从而有效提升代码的质量

本书适合致力于改善代码质量的程序员及技术经理阅读。本书介绍的规则均来自作者多年的实践经验,涵盖从命名到重构的多个方面,虽为一之言,然诚有借鉴意义。

本书是Clean Code一书的评注版,力邀国内资深专家执笔,在英文原著的基础上增加了中文点评和注释,旨在融合二者之长,既保留经典的原创文字与味道,又以先行者的学研心得与实践感悟,对读者的阅读和学习加以点拨,指明捷径。

作者简介

Robert C. Martin

软件工程领域的大师级人物,设计模式和敏捷开发运动的主要倡导者之一,曾经担任C++ Report杂志主编多年。他的Agile Software Development: Principles, Patterns, and Practices一书曾荣获Jolt大奖。

评注者简介

韩磊

技术管理者和作译者,互联网专家。2001年创办CoDelphi.com中文开发在线网站;2003年加入CSDN,历任网络总监、副总经理、CSDN网站和《程序员》杂志总编辑等职;2010年加入21世纪传媒,现任21世纪新媒体副总经理、CTO。拥有美国Borland公司“Delphi产品专家微软最有价值专家称号。译有《C#编程风格》(Elements of C# Style)、《梦断代码》(Dreaming in Code)、《代码整洁之道》(Clean Code),合著有《网络媒体教程》,合译有《Beginning C# Objects:对象到代码》。

评注者序

代码猴子与童子军军规

3月,我在SD West 2007技术大会上聆听了Robert C. Martin(鲍勃大叔)的主题演讲Craftsmanship and the Problem of Productivity: Secrets for Going Fast without Making a Mess。一身休闲打扮的鲍勃大叔,以一曲嘲笑低水平编码者的Code Monkey(代码猴子)开场。

是的,我们就是一群代码猴子,上蹿下跳,自以为领略了编程的真谛。可惜,当我们抓着几个酸桃子,得意洋洋坐到树枝上时,却对自己造成的混乱熟视无睹。那堆可以运行的乱麻程序,就在我们的眼皮底下慢慢腐坏。

从听到那场以TDD为主题的演讲之后,我就一直关注鲍勃大叔,还有他在TDD和整洁代码方面的言论。

这本书名为Clean Code,乃Object Mentor(鲍勃大叔开办的技术咨询和培训公司)一干大牛在编程方面的经验累积。按鲍勃大叔的话来说,就是“Object Mentor整洁代码派的说明。

正如Coplien在序中所言,宏大建筑中最细小的部分,如关不紧的门、有点儿没铺平的地板,甚至是凌乱的桌面,都会将整个大局的魅力毁灭殆尽这就是整洁代码之所系。Coplien列举了许多谚语以证明整洁的价值,中国也有修身、齐家、治国、平天下之语。整洁代码的重要性毋庸置疑,问题是如何写出真正整洁的代码。

本书既是整洁代码的定义,亦是如何写出整洁代码的指南。鲍勃大叔认为,写整洁的代码,需要遵循大量的小技巧,贯彻刻苦习得的整洁感。这种代码感就是关键所在……它不仅让我们看到代码的优劣,还予我们以借戒规之力化劣为优的攻略。作者阐述了在命名、函数、注释、代码格式、对象和数据结构、错误处理、边界问题、单元测试、类、系统、并发编程等方面如何做到整洁的经验与最佳实践。长期遵照这些经验编写代码,所谓代码感也就自然而然滋生出来。更有价值的部分是鲍勃大叔本人对3Java项目的剖析与改进过程的实操记录。通过多达3章的重构记录,鲍勃大叔充分地证明了童子军军规在编程领域同样适用:离开时要比发现时更整洁。为了向读者呈现代码的原始状态,我对这部分代码及本书其他部分的绝大多数代码注释都不做评注。如果读者有任何疑问,可通过邮件与我沟通(cleancode.cn@gmail. com)。

接触开发技术10多年以来,特别是从事IT技术媒体工作6年以来,我见过许多对于代码整洁性缺乏足够重视的开发者。不过分地说,这是职业素养与基本功的双重缺陷。为本书做评注,实在也是因为希望在这方面看到开发者的重视度和实际应用能力的提升。

在本书的结束语中,鲍勃大叔提到别人给他的一条腕带,上面的字样是“Test Obsessed”(沉迷测试)。鲍勃大叔发现自己无法取下腕带。不仅是因为腕带很紧,而且那也是条精神上的紧箍咒……它一直提醒我,我做了写出整洁代码的承诺。有了这条腕带,代码猴子成了模范童子军。我想,每位开发者都需要这样一条腕带吧!

韩磊

 

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

阅读(1431) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~