《The Clean Coder》读书笔记

340 阅读30分钟

第1章专业主义

希望我们都可以成为专业的软件工程师。

1.1 清楚你要什么

“专业主义象征着荣誉与骄傲,也象征着责任与义务。”专业主义的精髓在于将公司利益视同个人利益,意味着担当责任。

1.2 担当责任

一个小故事:需要对例行程序进行测试后才能交付,另外,客户和雇主高于自己的脸面。

1.3 首先,不行损害之事

不应破坏软件的功能与架构

1.3.1 不要破坏软件功能

做的专业,不应该有bug。专业人士就是能对自己犯下的错误负责的人,要练习道歉,要增加经验,不犯重复的错误,让失误率无限接近于0。

几个点:

  1. 让QA找不出任何问题;
  2. 要确信代码正常运行(单测、自动化测试);
  3. 自动化QA。

1.3.2 不要破坏结构

原则:软件应该易于修改。童子军训练守则:对每个模块,每检入一次代码,就要让它比上次检出时变得更为简洁。每次读代码都别忘了进行点滴的改善。

1.4 职业道德

要持续学习,学习是自己的事情。

每周额外花20小时的时间提升自己,充满乐趣。

几个点:

1.4.1 了解你的领域

对各种专业的观点、实践、技术、工具与术语应该了解。一些总结:

  • 设计模式
  • 设计原则:SOLID原则(单一功能、开闭原则、里氏替换、接口隔离以及依赖反转)
  • 方法:精益、看板、瀑布、结构化分析及结构化设计等
  • 实践:测试驱动开发、面向对象设计、结构化编程、持续集成和结对编程。
  • 工件:UML图、DFD图、结构图、状态迁移图表、流程图和决策表等。

1.4.2 坚持学习

读书、看相关文章、关注博客和微博、参与技术大会、访问用户群,多参与读书和学习小组,学一学新技术。

1.4.3 练习

在工作之余专门练习技能,以期自我提升。

1.4.4 合作

学会与他人合作,一起编程、练习、设计、计划等,从彼此身上学习到东西。

1.4.5 辅导

传道授业,其实就是费曼学习法。

1.4.6 了解业务领域

应当了解自己开发的解决方案对应的业务领域,读该领域相关的书,了解该领域的基础架构与基本知识。

1.4.7 与雇主/客户保持一致

雇主的问题就是自己的问题,应当弄明白,站在雇主的角度来思考,确保开发功能真正能满足雇主的需要。

1.4.8 谦逊

写代码会出错,要保持谦逊。

第2章 说“不”

“能就是能,不能就是不能,不要说‘试试看’。”

这里讲了一个故事,其实意思就是,作为软件工程师,不应该迫于压力承诺做不到的事情,导致事故发生。

2.1 对抗角色

不可能的就是不可能,即使有冲突和不愉快,也要提出来,最终达成一致意见。

同时,告诉客户或者要负责的人“为什么”。

2.2 高风险时刻

越是高风险时刻,如果确定不能完成,越要坚持说“不”,才不至于酿成大错。

2.3 要有团队精神

恪尽职守,当其他队员遭遇困境时要援手相助,频繁与大家交流,会关心队友,竭力做到尽职尽责。

根据自己的能力,明确哪些做得到、哪些做不到,不要自行其是。

2.3.1 试试看

在很多时候不能说试试看,尤其是不确定的时候,因为这就代表了承诺可以。

2.3.2 消极对抗

知道不可能做到的事时一定要努力制止和讲出来,否则因为队友的举动出错,影响的是最终的结果。

2.4 说“是”的成本

健康的团队都会努力寻求给他人以肯定的答复。运作良好的团队经理和开发人员,会相互协商,直至达成共同认可的方案。但是有时获取正确决策的唯一途径是坚定地说“不”。

这里讲了一个故事,几个点:做不到的不要承诺、提出问题的人不一定非常重视这个问题、不要急于求成、不应该预估事情太简单、不该一再推后项目截止日期。

2.5 如何写出好代码

保持专业习惯,坚守专业精神,学会说“不”。

第3章 说“是”

几个承诺相关的事情。

3.1 承诺用语

做出承诺的三个步骤:

  1. 口头上说自己将会去做;
  2. 心里认真对待作出的承诺;
  3. 真正付诸行动。

一方面要看自己是否是这样, 另一方面也要根据此判断其他人对自己的承诺。

3.1.1 识别“缺乏承诺”的征兆

几个需要注意的词和短语:

  • 需要/应当
  • 希望/但愿
  • 让我们

3.1.2 真正的承诺听起来是怎样的

承诺:对自己将会做某件事做了清晰的事实陈述,而且还明确说明了完成期限。

没能做到的几个原因

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

要避免这些,只承诺自己能掌控的事、全力以赴,以及及时调整承诺对象的预期,更改承诺。

3.2 学习如何说“是”

3.2.1 “试试”的另一面

如果确实不确定能否做到,那就要表达出来,并确定都有哪些可能性。

3.2.2 坚守原则

口头承诺是容易的,但要花精力高质量地完成工作却会困难很多。

专业人员应该对自己的能力和极限了如指掌。

第4章 编码

一些作者本人编码的准则与原则。

4.1 做好准备

几个要求:

  1. 首先,代码必须能正常工作;
  2. 代码必须能够帮你解决客户提出的问题;
  3. 代码必须要能和现有系统结合得天衣无缝;
  4. 其他程序员必须能读懂代码。

疲劳和心烦意乱时不要编码,否则强行写是要返工的。

4.1.1 凌晨3点写出的代码

奉献精神和职业素养,更多意义上指要遵循纪律原则而非成为长时间工作的工作狂,要确保自己已经将睡眠、健康、生活方式调整到了最佳,这样才能在工作时间全力以赴。

4.1.2 焦虑时写下的代码

不应该在焦虑期写代码,应当先解决焦虑问题。因为焦虑会削弱工作效率,甚至会导致出错。

4.2 流态区

高效率状态-“流态”:一种意识高度专注单思维视野却会收拢到狭窄的状态。正常情况下要避免进入流态区,顾及全局。但如果正希望进入流态区时,尝试练习。

4.2.1 音乐

写代码的时候也许不应该听音乐,虽然对有些人来说更容易进入流态区,但也会影响到编码效率。

4.2.2 中断

避免进入流态区,否则被人拉出来时会很痛苦。同时可以结对编程,同事帮助回答问题。或者采用TDD,失败的测试可以帮助维护编程进度的上下文,因为从中断回去时会清楚下一步是让失败的测试通过。

4.3 阻塞

睡眠不足、焦虑、恐惧、沮丧时,会进入不好的状态,同时难以写出好的代码。一个方法是找一个搭档结对编程,和别人一起工作时会减少这种状态。如果还是不行,就一个人待一会。

创造性输入:平时的广泛阅读,例如软件、政治、生物、航天、物理、化学、数学等方面的知识,甚至音乐、电视、ppt都有可能增加自己的创造性灵感,避免陷入阻塞状态。

4.4 调试

讲了一个队列同步问题导致的卡车司机工会终端系统的bug。

另外,努力将调试时间降到最低,例如使用TDD等,可以减少bug,也可以更快定义出错误。

4.5 保持节奏

软件开发是一场马拉松,所以要保存体力和维持稳定节奏,需要保存好自己的精力和创造力。

4.5.1 知道何时应该离开一会

感到疲劳时应该离开一会,让富有创造力的潜意识接管问题。并做好精力分配。

4.5.2 开车回家路上

开车会占用大量与创造性无关的脑力资源,要学会从问题中暂时脱离出来。

4.5.3 洗澡

可以思考解决方案和总结,

4.6 进度延迟

延迟总是无法避免的,但是管理延迟的诀窍就是早期检测和保持透明。

严守三个期限:乐观预估、标称预估、悲观预估,这三个时间点全部呈现给团队和利益相关者,并及时修正这些数字,暴露风险点。

4.6.1 期望

做不到的不要抱有幻想,也不要让其他人对此抱有期望,否则容易出问题。

4.6.2 盲目冲刺

坚持自己的估算,不要经受不住诱惑盲目冲刺。无法更快写完代码和解决问题,应当让团队知道。

4.6.3 加班加点

不轻易接受加班,因为加班风险会高一些。

除非满足三个条件:

  1. 个人能挤出这些时间;
  2. 短期加班,比如加班两周;
  3. 老板有后备预案,以防万一加班措施失败了。

最后一条至关重要。

4.6.4 交付失误

千万不能没有完成任务却宣称已经完成,会导致其它人也这么做,同时会压低“完成”的标准等等。

4.6.5 定义“完成”

通过一个确切定义的“完成”标准来避免交付失误。最好的方法是让业务分析师和测试人员创建一个自动化的验收测试,只有完全通过这些验收测试,开发任务才能算已完成。

4.7 帮助

和其它人互相交流,从其它人的思考和想法中获益。

4.7.1 帮助他人

互相帮助是职责所在,同时帮助别人时也可以让自己有所收获。

4.7.2 接受他人的帮助

学会请求帮助,尤其是在自己阻塞很严重时,不应该护住自己的地盘而拒绝其它人的帮助。

同时团队应该通过纪律原则来驱动大家良好协作。

4.7.3 辅导

辅导缺乏经验的程序员是经验丰富的程序员的职责。同样,向自身导师寻求辅导也是年轻程序员的专业职责。

第5章 测试驱动开发

TDD:先写单元测试,再写代码,然后运行验证,周而复始。这样可以使得自己的代码都是正确的,而且省去许多调试的时间。

5.1 此事已有定论

TDD绝不仅仅是一种用于缩短编码周期的简单技巧。

作者先声明的几句话:此事已有定论;争论已经结束;GOTO有害;TDD确实可行。

5.2 TDD的三项法则

三个法则:

  1. 在编好失败单元测试之前,不要编写任何产品代码;
  2. 只要有一个单元测试失败了,就不要再写测试代码:无法通过编译也是一种失败情况;
  3. 产品代码恰好能够让当前失败的单元测试成功通过即可,不要多写。

遵守这三项法则,大概30秒就要运行一次代码。以上三个法则循环往复。

5.3 TDD的优势

5.3.1 确定性

通过单测是否通过来验证代码是否可行,可以确信修改的代码是否可以交付。

5.3.2 缺陷注入率

TDD能显著降低缺陷。

5.3.3 勇气

有了一套值得信赖的测试,看到糟糕的代码就不怕整理,因为知道整理完可以通过测试的就没问题。

5.3.4 文档

遵循TDD三项法则的话,每个单元测试都是一个示例,用代码描述系统的用法。单测可以描述对象的各种创建方法,也可以描述函数的各种调用方式以及用法。

单测即是文档,描述了系统设计的最底层设计细节。

5.3.5 设计

遵循三大法则可以让自己写出一个松耦合的代码。

5.3.6 专业人士的选择

TDD可以提升代码确定性、给程序员鼓励、降低代码缺陷率、优化文档和设计的原则。

5.4 TDD的局限

写出好的测试代码是前提,同时在一些不适合的场景下不应该强行使用。

第6章 练习

本章主要讲程序员如何提升专业技能。

6.1 引子

可以用各种语言来实现同样功能练习。

6.1.1 10的22次方

作者这里用了MBP和之前的PDP做了比较,性价比高了6.4✖️10的22次方,但语言的本质并没有随着时间而改变,逻辑没有变化,20世纪60年代的程序员也完全可以看懂2012年的代码。

6.1.2 转变

但工作方式已经不一样,编译不需要程序员等待。几秒钟就可以知道本次重构是否成功。

编程的速度来源于练习,多写。

6.2 编程柔道场

还是讲测试驱动开发的故事。

6.2.1 卡塔

有点玄乎,大概意思就是编程卡塔是一整套键盘和鼠标的动作,用来模拟编程问题的解决过程。练习者不是在解决真正的问题,因为已经知道了解决方案。相反,是在练习解决这个问题所需要的动作和决策。要学习热键和导航操作,以及测试驱动开发、持续集成之类的方法。

6.2.2 瓦萨

大意就是一个人写单元测试,另一个人写程序,然后交换角色。

6.2.3 自由练习

多人瓦萨。

6.3 自身经验的拓展

要做好准备面对行业的周期性变化。

6.3.1 开源

为开源项目贡献代码。

6.3.2 关于练习的职业道德

老板的职责不包括避免你的技术落伍,也不包括为你打造一份好看的简历。所以要用自己的时间练习,并且不必限制在老板规定的语言和平台。

6.4 结论

无论如何,专业人士都需要练习,保持自己技能不落伍是自己的责任。并且,要关心自己能做到的最好结果。

第7章 验收测试

专业开发人员既要做好开发,也要做好沟通。

7.1 需求的沟通

开发方和业务方之间最常见的沟通是关于需求的。业务方描述他们认为自己需要的东西。

业务方对功能的设想通常跟电脑前的不同。

7.1.1 过早精细化

过早精细化是一个陷阱:业务方还没有启动项目,就要精确知道最后能得到什么;业务方还没有评估整个项目,就希望精确知道要交付什么。

不确定原则

东西画在纸上和真正做出来是不一样的。

观察者效应(不确定原则):每次向业务方展示一项功能,他们就获得了比之前更多的信息,这些信息反过来又会影响他们对整个系统的看法。

预估焦虑

无法实现早期的精确性,需求一定会变化的。

7.1.2 迟来的模糊性

相比解决分歧,更好的办法是换一种各方都统一的关于需求的表述。所以要想办法解决

7.2 验收测试

验收测试:业务方与开发方合作编写的测试,目的在于确定需求已经完成。

7.2.1 “完成”的定义

完成意味着所有的代码都写完了,所有的测试都通过了,QA和需求方已经认可。

不影响速度的方法:编写整套自动化测试,对功能的验收测试全都通过就意味着满足了所有的要求。

7.2.2 沟通

验收测试的目的是沟通、澄清、精确化。开发方、业务方、测试方对验收测试达成共识。

7.2.3 自动化

验收测试不应该手工完成,要考虑成本,同时有一些开源工具。

7.2.4 额外工作

测试不是额外工作

7.2.5 验收测试什么时候来写,谁来写

应当确保写测试的程序员与开发所测试功能的程序员不是同一个人。通常业务分析员测试“正确路径”,以证明功能的业务价值;QA则测试“错误路径”、边界条件、异常、例外情况。

7.2.6 开发人员的角色

实现某项功能的代码,应该在对应的验收测试完成后开始。开发人员运行这些验收测试,观察失败的原因,将验收测试与系统联系起来,然后实现需要的功能,让测试通过。

7.2.7 测试的协商与被动推进

发现测试的问题也要及时更正。

7.2.8 验收测试和单元测试

验收测试不是单元测试。

单元测试是程序员写给程序员的,是正式的设计文档,描述底层结构及代码的行为。关心单元测试的应该是程序员。

验收测试是业务方写给业务方的,是正式的需求文档,描述了业务方认为系统应该如何运行,关心验收测试结果的是业务方和程序员。

单元测试和验收测试首先是文档,然后才是测试。主要目的是如实描述系统的设计、结构、行为,也可以验证设计、结构、行为是否达到了具体指标。真正价值主要在于是否达到了具体指标。

7.2.9 图形界面及其他复杂因素

“单一责任原则”及恰当的GUI测试,应该减少GUI测试。

7.2.10 持续集成

确保在持续集成系统中,单元测试和验收测试每天都能运行好几次。整套持续集成系统应该由源代码管理系统来出发,只要有人提交了代码,持续集成系统就会开始构建,并运行所有的测试,测试结果会发送给团队所有人。

如果持续集成失败了,应该停下来手中的活看如何让测试通过。

7.3 结论

解决开发方和业务方沟通问题,唯一有效的办法就是编写自动化的验收测试,应该足够正式并且结果有权威性。这些测试就是无可挑剔的需求文档。

第8章 测试策略

专业团队要有好的测试策略。

8.1 QA应该找不到任何错误

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

8.1.1 QA也是团队的一部分

QA要扮演的角色是规约定义者(specifier)和特性描述者(characterizer)。

8.1.2 需求规约定义者

QA的任务是和业务人员一起创建自动化验收测试,作为系统真正的需求规约文档。业务人员针对正常路径的测试,QA编写针对极端情况、边界状态和异常路径的测试。

8.1.3 特性描述者

QA的另一项任务是遵循探索式测试的原则,描述系统运行的真实情况,将之反馈给开发人员和业务人员。

8.2 自动化测试金字塔

拥有一套单元测试和验收测试的同事,还需要有更高层次的测试,这样QA才找不出任何错误。

8.2.1 单元测试

金字塔底部是单元测试,从最低层次上来定义系统。先编写测试,再编写产品代码。

8.2.2 组件测试

是验收测试的一种,通常是针对系统的各个组件而编写的。系统组件封装了业务规则,对这些组件的测试是对其中业务规则的验收测试。

在组件测试中,需要使用合适的模拟(mocking)或测试辅助(test-doubling)技术,解开与系统的其他组件的耦合。

组件测试差不多可以覆盖系统的一半,更主要测试的是成功路径的情况,以及一些明显的极端情况、边界状态和可选路径。

8.2.3 集成测试

只对组件很多的较大型系统有意义。

集成测试将组件装配成组,测试它们彼此之间是否能正常通信。照例要使用合适的模拟对象和测试辅助,与系统的其他组件解耦。

集成测试是编排性测试,不会测试业务规则,而是主要测试组件装配在一起时是否协调。是装配测试。

8.2.4 系统测试

系统测试是针对整个集成完毕的系统来运行的自动化测试,是最终的集成测试。不直接测业务规则,而是测系统是否已经组装完毕,以及各个组件之间是否正确交互。同时应该包含吞吐率测试和性能测试。

由系统架构师和技术负责人来编写,主要确保正确的系统构造。

8.2.5 人工探索式测试

需要人工介入、敲击键盘、盯牢屏幕的测试。这些测试的意图是要在验证预期行为的时候,探索系统预期之外的行为。

主要确保系统在人工测试操作下表现良好,同时找出尽可能多的不合理之处。

8.3 结论

要开发团队和QA一起创建由单元测试、组件测试、集成测试、系统测试和探索式测试构成的测试体系,同时尽可能频繁地运行这些测试,提供尽可能多的反馈,确保系统始终整洁。

第9章 时间管理

专业开发人员应当高效工作,取得尽可能多的成果。

9.1 会议

会议是必须的,同时会议浪费了大量的时间。

9.1.1 拒绝

邀请你参加会议的人并不负责管理你的时间,为时间负责的只有你自己。要权衡利弊,是否比自己的工作计划更重要。

9.1.2 离席

会议并不总是按计划进行,如果正在参加某个会议,发现无用且让人厌烦,就应该离席。

9.1.3 确定议程与目标

如果收到会议邀请,务必弄清楚指定的议题是什么。要花多长时间,取得什么成果。

9.1.4 立会

站会,每个到场的人主要回答三个问题:

  1. 我昨天干了什么?
  2. 我今天打算干什么?
  3. 我遇到了什么问题?

9.1.5 迭代计划会议

迭代计划会议用来选择在下一轮迭代中实现的开发任务。

会议召开前必须完成两项任务:评估可选择任务的开发时间,确定这些任务的业务价值。

会议结构应该快,简明扼要讨论各个候选任务,然后决定是选择还是放弃。

建议每轮迭代中,这类会议所花时间不超过5%。

9.1.6 迭代回顾和DEMO展示

回顾什么做得对,什么做得不对

9.1.7 争论反对

5分钟内不能解决的争论,都不能靠辩论解决。

那靠什么呢?做实验、模仿、建模,甚至抛硬币。不要发泄情绪。

9.2 注意力点数

编程是需要持续投入精力和注意力的智力活动。忧虑和分心都会消耗注意力点数。控制注意力很重要。

9.2.1 睡眠

至少要睡够7小时吧。

9.2.2 咖啡因

咖啡因过多也会让人沉迷到奇怪状态,所以要适量。

9.2.3 恢复

不集中注意力时反而会恢复。所以散步、聊天、看看窗外,都有利于恢复注意力点数。有人选择沉思、反省、小睡一会或者听播客、翻翻杂志等。

注意力点数耗尽之后不要继续写代码,否则可能需要第二天重写。

9.2.4 肌肉注意力

运动需要肌肉注意力,而编程需要心智注意力。但肌肉注意力有助于改善心智注意力。

定期训练肌肉注意力,可以提升心智注意力的上限。

9.2.5 输入与输出

平衡输入与输出。编程是一项创造性活动,如果接触到其他人的创造性思维,自己的创造力也会旺盛。比如可以看科幻小说等。

9.3 时间拆分和番茄工作法

番茄工作法:沉浸式25分钟,之后处理这25分钟内需要处理的其他事,然后休息5分钟。循环这个过程。

9.4 要避免的行为

无论什么原因,我们都有办法逃避真正的工作。潜意识会说服自己有些工作更紧急,所以转去处理,这种行为叫优先级错乱--提高某个任务的优先级,之后就有借口推迟真正急迫的任务。专业人员应该会评估每个任务的优先级,排除个人喜好,按照真实的紧急程度来执行任务。

9.5 死胡同

所有开发都有可能走到死胡同,专业人员靠慎重的态度和积累的经验可以避免,但无法避免所有。所以当走到死胡同了要迅速意识到,并有足够的勇气走回头路。

坑法则:如果你掉进了坑里,别挖。

9.6 泥潭

泥潭跟死胡同不同的一点是,泥潭里可以看到前进的路,而且看起来总是比走回头路要短。

要及时注意,走回头路,修正,重构。

9.7 结论

专业人员会用心管理自己的时间和注意力,抵制优先级错乱。及时注意避免死胡同和陷入泥潭。

第10章 预估

要对做的事情有合理预估。

10.1 什么是预估

业务方会觉得预估是承诺,开发方认为预估是猜测。

10.1.1 承诺

承诺是必须达到的,如果有承诺,即使每天工作12小时,放弃周末的休假也必须兑现。

10.1.2 预估

预估是一种猜测,不需要做任何约定。另外,预估要考虑好极端情况。

10.1.3 暗示性承诺

不能说试试看。专业开发人员能够清楚区分预估和承诺。只有在确切知道可以完成的前提下,才会给出承诺。

10.2 PERT

Program Evaluation and Review Technique / 计划评审技术:指当活动的估算无法确定时,使用其乐观估算、悲观估算和最可能估算的加权平均值作为估算结果的一种技术。

10.3 预估任务

德尔菲法:一群人集合起来讨论某项任务,预估完成时间,然后重复讨论-预估过程,直到意见统一。

亮手指:大家一起在桌下伸手指投票,然后数1-2-3举起来。

规划扑克:区间改变一些的亮手指,同样是各自做好预估然后一起表示出来。

关联预估、三元预估,都是德尔菲法的一种。

10.4 大数定律

控制预估错误的办法之一就是使用大数定律:把大任务分成许多小任务,分开预估再加总,结果会比单独评估大任务要准确很多。

第11章 压力

背景故事,大意压力高强度的生活方式和压力让自己痛苦不堪。

11.1 避免压力

压力下保持冷静的最好方式,就是规避会导致压力的处境。

11.1.1 承诺

控制好承诺,只承诺能承诺的事。

11.1.2 保持整洁

指系统、代码、设计尽可能整洁,这样会避免压力。

11.1.3 危机中的纪律

选择那些在危机时刻依然会遵循的纪律原则,并且在所有工作中都遵守这些纪律。遵守这些纪律原则是避免陷入危机的最好途径。

11.2 应对压力

面对压力时应该怎么做

11.2.1 不要惊慌失措

烦躁不安也于事无补,反而容易鲁莽仓促。所以要避免孤注一掷的想法,放松下来,对问题深思熟虑。努力寻找可以带来最好结果的路径,沿着路径以合理稳定的节奏前进。

11.2.2 沟通

告诉团队和主管自己面临的困境,告诉他们自己制定的走出困境的最佳计划,请求支援和指引。

避免产生惊恐,惊恐会令人愤怒和失去理性,让压力增加更多。

11.2.3 依靠你的组织纪律

事情十分困难时也要坚信组织纪律。

11.2.4 寻求帮助

结对编程,效率更高。

11.3 结论

压力能回避就回避,无法回避的就勇于直面。

可以通过慎重承诺、遵循自己的纪律原则、保持整洁等来回避压力。

直面压力时则应该保持冷静,与别人多多沟通,坚持自己的纪律原则,并寻求它人帮助。

第12章 协作

讲了个和自己伙伴共同开发的事情。

12.1 程序员与人

程序员很多更享受面无表情的沉思。

12.1.1 程序员与雇主

专业程序员的首要职责是满足雇主的需求,意味着要深刻理解业务目标,理解在写的代码的业务价值是什么,了解雇你的企业如何从你的工作中获得回报。

专业程序员会花时间去理解业务,会和用户、销售人员、市场人员、经理们沟通,明确团队的短期目标和长期目标。

讲了个例子,作者对公司的DDL不放在心上被解雇了。

12.1.2 程序员与程序员

代码个体所有:不让其他程序员看到自己的代码,这样会引发灾难。

协作性的代码共有权:应当采用整个团队共同拥有全部代码的做法。

结对:结对编程有利于分享知识,互相结对来学习系统的不同部分和业务。同时结对也有利于复查代码。

第13章 团队与项目

小项目如何实施?如何给程序员分派?大项目又该如何实施?

13.1 只是简单混合吗

作者批评了小项目按照半个人或者1/4个人计算时间的做法。称其为混合物。

13.1.1 有凝聚力的团队

作者给出了一个有凝聚力的团队较好的人数和比例:12人,7个程序员、2个测试人员、2个分析师、1个项目经理。

分析师关注业务价值,测试人员关注正确性。都编写自动化验收测试。

成员需要克服个体差异性,默契配合,彼此信任,形成真正有凝聚力的团队。并且不应该围绕项目来构建团队,而是把项目分配给已经形成凝聚力的团队。

13.1.2 如何管理有凝聚力的团队

可以使用点数来控制自己的速度,记录每周能完成多少个点,定下目标。这样既可以检查团队的能力,又可以做好优先级分配。

13.2 结论

团队比项目更难构建。组建文件的团队,让团队在一个又一个项目中整体移动共同工作是较好的做法。团队也可以同时承接多个项目。要让团队有时间磨合,形成凝聚力。

第14章 辅导、学徒期与技艺

大学一直没有教授真正的编程之道。

14.1 失败的学位教育

计算机学科教学计划里,很多时候只教授原理,而不教如何写代码。

14.2 辅导

这里主要讲了作者自己学习编程的经历。其实就是在自学时抱有乐趣,工作有师傅带着,多看别人的代码。另外,要有职业精神。

14.3 学徒期

大学毕业生在成为软件开发人员之前有一段合理的督导实训期其实很重要。

14.3.1 软件学徒期

几种水平分类。

大师:已经领到过多个重要软件项目的程序员。通常来说拥有10年以上从业经验,懂得如何领导和协调多个团队,是熟练的设计师和架构师,能够游刃有余地编程。同时会通过阅读、研究、练习、实践和教学来维持自身的技术水平。

熟练工:尚缺乏经验,不过已经能胜任工作且精力充沛。平均水平在5年左右。

学徒/实习生:毕业生通常在这一等级,他们需要在熟练工的督导下工作,一开始不会单独承接任务,而是作为助手为熟练工打下手。熟练工会担任他们的导师,确保学徒们能了解设计原则、设计模式、各种纪律和固定的操作环节。熟练工会向他们传授TDD、重构、估算等各种技艺,会为学徒安排阅读、练习和实践任务,并且检查学徒们的任务进展情况。

学徒大概一年的时间,经过大师的考验,就可以成为熟练工了。

14.3.2 现实情况

资深人士辅导信任向其传授技艺的环节是较为重要的。专业主义价值观和技术敏锐度需要进行不断的传授、培育、滋养和文火慢炖,直至完全渗入文化当中。

14.4 技艺

工匠:应在人们心中唤起“经验丰富”和“堪当重任”这样的印象。成熟工匠手脚麻利、从容淡定,他们能够做出合情合理的估算并遵守承诺。

技艺是工匠所持的精神状态,包含着价值观、原则、技术、态度和正见。

口口相传和手手相承其实是最好的学习方式,现实中,我们可以通过观察其他人的工作,让年轻学徒学会资深人士的模因。

14.5 结论

软件开发人员成熟起来不能考大学,应该在社会、公司中,建立一种包含学徒期、实习期和长期引导的机制。

其实这一点公司已经做得很好了。

读完整本书,感觉这本书更多是在价值观和作为程序员所要具备的软素质上描述。

有所收获,继续看其他几本。