《代码整洁之道 程序员的职业素养》读书笔记

第1章 专业主义

程序员的”希波克拉底誓言”

1.1 清楚你要什么

你是想做坚守“专业主义”的专业人士,还是一个混子

1.2 担当责任

你要为你的专业担当责任

1.3 不行损害之事

1.4 坚守职业道德

第2章 说”不”

能就是能,不能就是不能,不要说试试看。
专业人士敢于说明真相而不屈从于权势。专业人士有勇气对他们的经理说不。

第3章 说“是”

在工作中做出真正的承诺。你对自己将做的某件事做了清晰的事实陈述,而且还明确说明了完成期限。
做一名“严谨负责的开发人员”

之所以没成功,是因为我寄希望于别人去做这件事。
之所以没成功,是因为我不太确信是否真能完成得了。
之所以没成功,是因为有些时候我真的无能为力。

“代码必须经过测试,代码必须要有对应的测试代码。要确保代码清晰整洁,而且必须确保没有影响到系统的其他部分”
作为专业开发人员就应该遵守和捍卫这些标准。如果是专业的开发人员,就不会放弃底线。
专业人士不需要对所有请求都回答“是”。不过他们应该努力寻找创新的方法,尽可能做到有求必应。
当专业人士给出肯定回答时,他们会使用正式的承诺,以确保各方能明白无误地理解承诺的内容。

第4章 编码

要精熟掌握每项技艺,关键都是要具备”信心”和“出错感知”能力。
“不要在凌晨3点写代码”。疲劳的时候,千万不要写代码。奉献精神和职业素养,更多意义上指要遵循纪律原则,
而非成为长时间的工作狂。要确保自己已经将睡眠,健康和生活方式调整到最佳状态,这样才能做到在每天的8小时工作时间内全力以赴。

“不要在焦虑状态下写代码”

根据目标定期衡量进度,使用三个考虑到多种因素的期限:乐观预估,标称预估,悲观预估。
并且要坚决维持你的估算!不要经受不住诱惑盲目冲刺。

接受他人的帮助
如果帮助唾手可得却让自己一个人堵在那里,是很不专业的表现。

大家知道,程序员大多自负,固执,内向。

第5章 测试驱动开发

TDD三项法则
1:除非是为了使一个失败的unit test通过,否则不允许编写任何产品代码。
2:只要有一个单元测试失败了,就不要再写测试代码(无法通过编译也是失败情况)
3:只允许编写刚好能够使一个失败的unit test通过的产品代码。

第6章 练习

专业人士都需要通过专门训练提升自己的技能,无一例外。

现在我们有了更好的工具,更好的语言。可是,语句的本质并没有随着时间而改变。20世纪60年代的程序员
完全可以看懂2012年的代码。我们真正打交道的东西,40年来没有多少改变。

卡塔联系网站
http://codingdojo.org
http://katas.softwarecraftsmanshi.org
http://codekata.pragprog.com

职业程序员通常会受到一种限制,即解决问题的种类比较单一。老板通常只强调一种语言、一个平台,以及程序员的专门领域。经验不够丰富的程序员,履历和思维中都存在某种贻害无穷的盲区。经常可以看到这样的情景:程序员发现,面对行业的周期性变化造成的新局面,自己并没有做好准备。

保持不落伍的一种方法就是为开源项目贡献代码,就像律师和医生参加公益活动一样。程序员用自己的时间来练习,老板的职责不包括避免你的技术落伍,也不包括为你打造一份好看的履历。

第7章 验收测试

开发方和业务方之间需求的沟通,应该避免 过早精细化以及过晚的模糊性。
验收测试的目的在于确定需求已经完成。

相比于手动验收测试,自动化验收测试的成本更低
自动化的验收测试工具有:FitNesse,Cucumber,cuke4duke,robot framework,Selenium

验收测试应该是QA身份的人的任务,QA指Quality Assurances,也就是质量保证。
不仅仅要保证程序按预期方式运行,而且还要考虑误用例,和滥用例(misuse,abuse)

验收测试 vs 单元测试
单元测试是深入系统内部进行,调用特定类的方法;
验收测试则是在系统外部,通常是在API/UI级别进行。

几十年来,设计专家一直在教导我们,要把GUI和业务逻辑分开。
所以对产品验收测试也应该 专门针对GUI的测试 以及 真的GUI背后的API进行。

第8章 测试策略

开发小组要把“QA应该找不到任务错误”作为努力的目标。

自动化测试金字塔

测试模式 测试主体 负责人 测试目的 覆盖率
人工探索式测试 滥用例,误用例测试 项目负责人,测试人员:尽可能多的,各类人参与测试 在验证预期行为之后,探索系统预期之外的行为 5%
系统测试 GUI 系统架构师/技术负责人,测试目的:测试系统是否正确组装完毕,且系统间的交互是否符合预期 不是要确保正确的系统行为,而是要确保正确的系统构造。一般使用和UI集成测试使用同样的语言和环境 10%
集成测试 API 系统架构师/主设计师,测试目的:实际是装配测试,确认组件之间是否正确连接,彼此间通信是否畅通 使用适当的模拟/测试辅助技术与其他组件解耦,此阶段可以进行性能测试和吞吐率测试 20%
组件测试 API QA/业务人员,测试目的:因为系统的组建封装了业务规则,所以对组件的测试就是对业务规则的验收测试 组件间可能存在耦合关系,测试单一组件时,可能需要模拟/测试辅助技术,解开与系统其他组件间的耦合 50%
单元测试 XUnit 开发人员,测试目的:在最低层次上定义系统。 单元测试将作为持续集成的一部分来运行,用以确保程序员的代码意图没有遭到破坏 100%

(开发人员应该遵从TDD模式,先编写测试,再编写产品代码)

第9章 时间管理

关于会议,有两条真理

1:会议是必需的,

2:会议浪费了大量的时间。

参加的会议太多,其实只能证明你不够专业。你应该理智的使用时间,对会议必须谨慎的选择。

领导的最重要责任之一,就是帮你从某些会议脱身。好的领导一定会主动维护你拒绝出席的决定,因为他和你一样关心你的时间。

这些年来,我学到了一条简单的规则:“如果会议让人厌烦,就果断离席”

每个会议都应该关注 议程,会议时间和目标,如果会议偏离议程/议题,则应该指出。

站立会应该回答以下3个问题
1:我昨天干了什么
2:我今天打算干什么
3:我遇到了什么问题
每个问题的回答时间不应当超过20秒,每个人的发言不超过1分钟。

敏捷开发 迭代计划会议 和 迭代回顾及DEMO展示技巧参看P106-P107

Kent Beck曾告诉我一个深刻的道理:“凡是不能在5分钟内解决的争论,都不能靠辩论解决。”
争论之所以要花这么多时间,是因为各方都拿不出足够有力的证据。所以这类争论依据的不是事实,而是信念。

注意力点数
如果自己察觉自己的注意力点数耗尽,就像游戏里的魔耗尽,要根据自己的恢复方式回魔,而后再投入到工作中,特别是编码工作

所有的软件开发者都要遇到死胡同。比如选择了走不通的技术道路。
作为一个专业开发人员,就应该有足够的勇气走回头路,承认决策失误。
这就是所谓的坑法则(The Rule of Holes):如果你掉进了坑里,别挖。

专业的开发人员相比于死胡同,应该更关注/恐惧泥潭。
因为在泥潭中,你仍然可以看到前进的道路,而且看起来总是比走回头路更短(虽然实际不是这样)。

第10章 预估

预估的实质:预估不是个定数,预估的结果是一种概率分布。
比如预估任务需要多久完成,结果可能是这样
第2天能完成的概率是10%
第3天能完成的概率是50%
第4天能完成的概率是20%
第5天能完成的概率是10%
第6天能完成的概率是5%
所以说6天内能完成的概率是95%
cleancode_predict

预估任务的 乐观预估,标称预估,悲观预估时间可采用德尔菲法
比如 亮手指,规划扑克,关联预估,三元预估等

大数定律
把大任务分成许多小任务,分开预估再加总,结果会比单独预估大任务要准确。

第11章 压力

专业开发人员应该避免对没有把握能够达到的最后期限做出承诺。
如果是业务人员对客户做出了不切实际的承诺,专业开发人员应该尽力主动帮助业务方找到方法来兑现这些承诺,但是一定不能接受这些承诺。要明白,如果承诺无法兑现,责任应该由承诺的人承担。

快速前进确保最后期限的方法,便是保持整洁。专业人士不会为了快点前进而乱来。他们明白“快而脏”是自相矛盾的说法,脏乱只会导致缓慢。
让系统,代码和设计尽可能整洁,就可以避免压力。这并非是说我们要花无穷无尽的时间去清理代码,而只是说不要容忍混乱。
混乱会降低速度,导致工期延误,承诺失信。因此,要尽力保持输出成果整洁干净。

危机中的纪律
观察自己在危机时刻中的反应,就可以了解自己的信念。如果在危机中依然遵循着你守持的纪律,就说明你确实相信那些纪律。反之,则说明你没认可那些纪律。
比如TDD,保持代码设计整洁,结对工作等纪律,要刻在骨子里,变成原则,而不是压力情况下,这些原则全抛弃了。

依靠你的纪律原则
在危机/压力时刻,不要惊慌失措地茫然四顾另寻依靠,而要从容不迫,专心致志地依靠你自己的纪律原则,这将帮你更快地走出困境。
如果你遵循TDD,那么这时写的测试甚至要比平时多。
如果你笃行无情的重构,这时就要更多的进行重构。
如果你相信要保持函数尽量小,这时就要让函数变得更小。
战胜压力煎熬的唯一方法,便是依靠那些你以及知道切实有效的东西,也就是你平时遵守的纪律。

第12章 协作

我们并非是因为喜欢和其他人在一起工作才选择做程序员的。我们都认为人际关系难以应付而且毫无规律。编程用的机器则整洁,行为也可预见。
如果可以一个人待在房间里数个小时沉浸在一些真正有趣的问题上,那将会是最开心的时光。
虽然这么说有点以偏概全,但是整个群体的平均状况还是朝我所描述的方法发展。

专业开发人员应该结对工作,因为结对工作是分享知识最好途径,是复查代码最好的方式。

团队之前代码不应该筑起高墙,应该打破各种代码隔断,由整个团队共同拥有全部代码。

第13章 团队与项目

有凝聚力的团队确实有些神奇之处。他们能够一起创造奇迹。
有凝聚力的团队通常有大约12名成员。由12个人组成的理想团队,人员配备情况是这样的:7名程序员、2名测试人员、2名分析师和1名项目经理。

形成团队需要时间。团队成员需要首先建立关系。他们需要学习如何互相协作,需要了解彼此的癖好、强项、弱项,最终,才能凝聚成团队。

团队和项目,何者为先?
试图围绕项目来构建团队是一种愚蠢的做法。按照这种做法,团队永远都不可能形成凝聚力。
专业的开发组织会把项目分配给已形成凝聚力的团队,而不会围绕着项目来组建团队。一个有凝聚力的团队能够同时承接多个项目,根据成员各自的意愿、技能和能力来分配工作,会顺利完成项目。

团队比项目更难构建。因此,组建稳健的团队,让团队在一个又一个项目中整体移动共同工作是较好的做法。并且,团队也可以同时承接多个项目。在组建团队时,要给予团队充足的时间,让他们形成凝聚力,一直共同工作,成为不断交付项目的强大引擎。

每个团队都有自己的速度。团队的速度是指在一定时间内团队内完成的任务量。
有些团队用每周点数来衡量自己的速度,点数是一个抽象的概念,细粒度的度量单位
比如每个团队每周的速度为 40点,如果一个任务总点数是120点,那么如果把此任务分配给这个团队,就可以预估要花三周时间才能完成。

第14章 辅导,学徒期与记忆

程序员应该和医生一样,毕业后到独当一面,应该有一个过渡时期
比如医生从 毕业生 到 实习医生 到 住院实习期
程序员也应该是从 毕业生 到 学徒/实习生 到 熟练工 到 大师
熟练工应该作为学徒的导师,向学徒传授TDD,重构,估算等各类必备技艺
学徒期至少应持续一年。期满之时,如果熟练工愿意接受学徒上升到他们这个层次,就把学徒推荐给大师们。
大师们则通过面谈和水平检测,对学徒们进行考核校验。如果能够取得大师们的认可,那么学徒便可晋升为熟练工。

现实情况是大多数时候,学徒在公司都没有得到技术层面的督导。程序员的水平能否提升以及职位能不能晋升,全在于自己的表现。
实际上这时不对的,在学徒的培养阶段,专业主义价值观和技术敏锐度需要进行不断的传授,培育,滋养和文火慢炖,直至其完全渗入文化当中。
在一个技术导向公司,应该把上述 学徒的培养 融入到企业文化当中,而不是依赖于个别领导或核心人员的推动。

技艺是工匠所持有的精神状态,技艺的模因(meme)中包含价值观,原则,技术,态度和正见。
应该让技艺的模因像传染病/传销一样,让这种精神病毒感染到所有观察到的人,落地生根。
所谓近朱者赤近墨者黑,任何人应该能识别出哪些病毒是良性的,哪些是恶性的,应该主动去接近拥有良性病毒的大师/匠人,远离那些拥有恶性病毒的人。

学校能够传授的是计算机编程理论。但是学校并不会也无法传授作为一名编程匠者所需掌握的原则,实践和技能。这些东西只有经由师徒个体间多年的细心督导和辅导才能获得。
软件行业中像我们这样的一批人必须要面对这一事实,即指引下一代软件开发人员成熟起来的重任无法寄希望于大学教育,现在这个重任已经落到了我们肩上。
建立一种包含学徒期,实习期和长期指引的机制已是迫在眉睫。

Table of Contents