作者:Robert C. Martin

一本“方法论”的书,还是可以借鉴很多东西的,做了摘录

讲了很多东西,涉及这个职业的方方面面

目标是,成为“专业人士”

每一节的标题还是有点作用的,摘录之


需要的不是“经历丰富的人”而是“有职业素养的人”

相比问题本身,解决问题的方式、步骤以及反思深度都体现出一个人的职业素养

职业素养: 它体现了能力和素质,又强调了持续的积累和养成

技术人员需要如何改变才能被视为专业人士呢?

前言

专业,要变得有影响力,有说服力

引言

尝试定义专业程序员,成为真正专业的程序员,需要什么样的态度、原则、行动 (本书主旨, note about that)

第一章 专业主义

1.1 清楚你要什么

"专业主义",不但象征着荣誉与骄傲,而且明确意味着责任与义务

"专业主义"就意味着担当责任

1.2 担当责任

尽职尽责

1.3 首先,不行损害之事

1.3.1 不要破坏软件的功能

要做得专业,就不能留下bug

要对自己的不完美负责

所谓专业人士,就是能对自己犯下的错误负责的人,哪怕那些错误实际上是在所难免的

你有责任让失误率无限接近0

1.让QA找不出任何问题(每次 QA 找出问题时, 更糟糕的是用户找出问题时, 你都该震惊羞愧, 并决心以此为戒)
2.要确信代码正常运行:
  如何确保-测试,一遍遍测试.自动化测试
  要求: 你写的每一行代码都要测试,完毕
3.自动化QA

1.3.2 不要破坏结构

聪明人不会为了发布新功能而破坏结构

所有软件项目的根本指导原则是,软件要易于修改

如果你希望自己的软件灵活可变,那就应该时常修改它: 要证明易于修改,唯一办法就是做些实际的修改

"无情重构",每次读、修改代码,就要比原来更简洁

不要害怕修改代码,(有一套完整测试,你就根本不会害怕)

1.4 职业道德

职业发展是你自己的事(雇主没有义务确保你在职场能够立于不败之地, 也没有义务培训你)

将自己的职业发展寄希望于雇主的软件开发人员将会很惨

"术业有专攻",需要投入时间去追求

1.4.1 了解你的领域

每个专业软件开发人员必须精通的事项(感觉有些可借鉴,并非全部)

1.设计模式
2.设计原则。必须了解SOLID原则,而且要深刻理解组件设计原则
3.方法。必须了解XP/Scrum/精益/看板/瀑布/结构化分析/结构化设计
4.实践。TDD、OOP、结构化编程、持续集成和结对编程
5.工件、UML/DFD/结构图/Petri网络图/状态迁移图表、流程图和决策表

1.4.2 坚持学习

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

不懂就学,不要畏难

1.4.2 练习

练习,指的是在日常工作之余专门练习技能,以期自我提升

解决一些简单的编程问题, 把它当做热身练习或静心过程

1.4.4 合作

学习的第二个最佳方法是与他人合作.

1.4.5 辅导

教学相长, 传道授业的同时, 导师也会从中受益

1.4.6 了解业务领域

对新领域有所了解, 未必需要成为该领域的专家, 但是仍然需要勤勉, 付出相当的努力来仍是业务领域.

1.4.7 与雇主/客户保持一致

必需弄明白雇主的真正问题, 站在其角度思考.

1.4.8 谦逊

专业人士都清楚自己的自负,不会故作谦逊

第二章 说不

专业人士敢于说明真相而不屈从于权势。专业人士有勇气对他们的经理说“不”

2.1 对抗角色

不靠谱的承诺是失职

说不,然后找到双方都能接受的解决方案

有时候需要提供必要细节, 解释说服, 但有时候提供太多细节会导致更多的微观管理

2.2 高风险时刻

最要说“不”的时那些高风险的关键时刻

2.3 要有团队精神

恪尽职守,关心队友,提供帮助,最大可能做到尽职尽责

有团队精神的人不会总是说“是”

2.3.1 试试看

没有“试试看”这回事

许诺“尝试”,就意味着你承认自己之前未尽全力,承认自己还有余力可施,意味着你只要再加把劲还是可以达成目标的

本质上,承诺“尝试”是一种不诚实的表现

2.3.2 消极对抗

直接交流沟通,而不是消极对抗

2.4 说“是”的成本

运作良好的团队的经理和开发人员, 会相互协商, 直至达成共同认可的行动方案.

有时候,获取正确决策的唯一途径,便是勇敢无畏的说出“不”字。

2.5 如何写出好代码

"客户所要的任何一项功能, 一旦写起来, 总是远比它开始时所说的药复杂许多...."

专业人士常常成为英雄,但这样的荣誉并非他们所刻意追求的

成为英雄与“解决问题”的诱惑诚然巨大,只是我们要明白,委屈专业原则以求全,并非问题的解决之道。舍弃这些原则,只会制造出更多的麻烦

坚守专业原则(问题: 哪些是专业原则?)

要学会说"不"

第三章 说“是”

3.1 承诺用语

做出承诺,包含三个步骤

口头上说自己将会去做
心里认真对待做出的承诺
真正付诸行动

当我们承诺某事时,必须认证对待承诺

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

一类词语

需要、应当
希望、但愿
让我们(不是让我)

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

你,你自己,始终能掌控某些事情,也就是说,总有些事是你可以承诺做到的

我将在....之前...

你对自己将会做某件事做了清晰的事实陈述,而且明确了完成期限

之所以没成功

1.是因为我寄希望于某某去做这件事
你只能承诺自己能完全掌控的事
最终目标依赖与他人,那么就应该采取些具体行动,接近最终目标

2.是因为我不大确信是否真能完成得了
即使目标无法完成,你仍能全力前进,离目标更近些3

3.是因为有些时候我真的无能为力
如果你无法兑现承诺,最重要的就是,尽早向你的承诺对象发出预警,越快越好,越早越好

3.2 学习如何说“是”

3.2.1 “试试”的另一面

试试尽力xxxx

3.2.2 坚守原则

如果是专业人员,就不会放弃底线。

写测试/重构/回归....打破这些纪律和原则, 必然会拖慢进度

专业人士对自己的能力极限了如指掌, 他们十分清楚自己还能保持效率加班多长时间, 也非常明白要付出的代价.

第四章 编码

具备"出错感知力", 说明你已经能够非常迅速地获得反馈, 能够更为快速地从错误中学习.

要精熟掌握每项技艺, 关键都是要具备"信心"和"出错感知"能力

4.1 做好准备

编码是一项智力活动

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

如果感到疲劳或者心烦意乱, 千万不要写代码. 要找到一种方法来消除干扰, 让心绪平静下来.

4.1.1 凌晨3点写出的代码

疲劳的时候,千万不要写代码

要确保自己已经将睡眠、健康和生活方式调整到最佳状况,这样才能在每天的8个小时里全力以赴

4.1.2 焦虑时写下的代码

专业开发人员善于合理分配个人时间,以确保工作时间段中尽可能富有成效。

在家中时,应该专门安排时间解决焦虑,这样就不会把焦虑情绪带到办公室里

4.2 流态区

意识高度专注,但思维视野收拢到狭窄的状态

避免进入流态区!并非真的极为高效,也绝非毫无错误

流态区写的代码可能会快些,但是后面你将不得不更多的回头重新审视这些代码

切换思维、结对编程等

ps: 为何我反而喜欢这种流态

4.2.1 音乐

对不同人,音乐帮助不一样,不一定有助于编码

4.2.2 中断

礼貌地回应中断

当然,要想办法减少中断

4.2.3 阻塞

不要干坐,找一些其他事情干

或者,结对编程

另一种方法:创造性输出依赖于创造性输入,增加自己知识体系的广度

4.4 调试

TDD?

衡量你是否是一个专业人士的重要方面,能否将调试时间尽量降到最低!

绝对的零调试时间是一个理想化的目标, 无法达到, 但要将之作为努力方向

4.5 保持节奏

软件开发是一场马拉松, 而不是短跑冲刺

4.5.1 知道何时应该离开一会

阻塞,疲倦等,让自己保持好节奏

当碰到困难而受阻时, 当你感到疲倦时, 就离开一会儿, 让富有创造力的潜意识接管问题.

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 辅导

第五章 测试驱动开发

TDD,测试驱动开发,先写测试的编程

5.1 此事已有定论

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

此事已有定论:TDD是确切可行,并且,每个开发者都要适应和掌握TDD

5.2 TDD的三项法则(似乎有些过了)

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

5.3 TDD的优势

5.3.1 确定性

代码有任何修改,都必须运行手头有的全部测试

确定状态

5.3.2 缺陷注入率

TDD能够显著降低缺陷

5.3.3 勇气

拥有一套值得信赖的测试,便可完全打消对修改代码的全部恐惧。

放手整理,代码变得更具有可塑性,可以安全地将之雕琢为简单而满意的结构

5.3.4 文档

单元测试即文档

5.3.5 设计

测试先行,会迫使你去考虑什么是好的设计

事后测试只是一种防守,而先行测试是一种进攻

5.3.6 专业人士的选择

TDD是专业人士的选择

它是一项能够提升代码确定性, 给程序员孤立, 降低代码缺陷率, 优化文档和设计的原则.

5.4 TDD的局限

TDD并非万能

某些场合显得不切实际或不合适

第六章 练习

专业人士都需要借助专门的训练提升自己的技能

6.1 引子

6.1.1 10的22次方

现在我们有更好的工具,更好的语言,但是,语句的本质并没有随时间而改变

6.1.2 转变

工作方式已经截然不同

任何事情,要做得快,都离不开练习

无论搏斗还是编程, 速度都来源于练习.

6.2 编程柔道场

需要找一些东西,来做实际的练习

6.3 自身经验的扩展

会受限,即所解决问题的种类比较单一

所以,要自己扩展

1.开源,提升技能的最好方式
2.自己规划,不要局限在公司的语言和平台

6.4 结论

无论如何,专业人士都需要练习

保持自己的技能不落伍是自己的责任, 而不是雇主的责任

联系的时候你是赚不到钱的, 但是联系之后, 你会获得回报, 而且是丰厚的回报.

第七章 验收测试

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

7.1 需求的沟通

7.1.1 过早精细化

陷阱:过早精细化

1.不确定原则
需求完成得越精细,就越容易被忽视, 系统因此也谈不上完工
观察者效应/不确定原则:每次你想业务方提供一个功能,他们获取比之前更多的信息,反过来影响他们对整个系统的看法
2.预估焦虑
所谓的预估,预估整个系统,对需求进行精确评估
其实:即便拥有全面准确的信息,评估通常也会存在很大的变数
     不确定原则,需求是一定会变化的,追求的那种精确是徒劳的

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测试

7.2.10 持续集成

保持持续集成系统的时刻运行

7.3 结论

要解决开发方和业务方沟通问题,有效的办法就是,编写自动化的验收测试

第八章 测试策略

每个专业的开发团队都需要一套好的测试策略

8.1 QA应该找不到任何错误

QA在团队中扮演需求规约定义者和特性描述者

8.2 自动化测试金字塔

5%   人工探索式测试
10%  系统测试
20%  集成测试
50%  组件测试
100% 单元测试

8.2.1 单元测试

在最低层次上定义系统

单元测试是可行的

单元测试可以做到90%以上的覆盖率

开发人员

8.2.2 组件测试

验收测试的一种,针对系统的各个组件编写的

QA和业务人员

8.2.3 集成测试

只能对那些组件很多的较大型系统才有意义

测试组件装配到一起是否协调,是装配测试

系统架构师或者主设计师

8.2.4 系统测试

针对真个击沉完毕的系统来运行的自动化测试,是最终的集成测试

测试系统是否正确组装完毕,以及系统各个组件之间是否能正常交互

系统架构师和技术负责人来编写.

8.2.5 人工探索性测试

人工,对系统进行深入研究和探索

8.3 结论

开发团队要和QA紧密配合,创建有单元测试,组件测试,集成测试,系统测试和探索式测试构成的测试体系

第九章 时间管理

9.1 会议

关于会议,有两条真理

1.会议是必须的
2.会议浪费了大量的时间

专业开发人员同样清楚会议额的高昂成本。所以,如果会议没有现实且显著的成效,他们会主动拒绝

9.1.1 拒绝

邀请你参加会议的人并不负责管理你的时间,为时间负责的人只有你

理智地使用时间,谨慎选择,应当参加哪些会议,礼貌拒绝哪些会议

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

9.1.2 离席

会议并不总按计划进行的

如果会议然人厌烦,就离席(想个办法礼貌地退出来)

9.1.3 确定议程与目标

会议应当有清晰的议程,确定每个议题所花的时间,以及明确的目标

9.1.4 立会

站立会议

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

每个人发言不超过1分钟

9.1.5 迭代计划会议

会议的节奏应该很快,简明扼要地讨论各个候选人物,然后决定是选择还是放弃

会议是每轮迭代时间的5%以内

9.1.6 迭代回顾和DEMO展示

在迭代的末尾召开

9.1.7 争论/反对

凡事不能再5分钟内解决的争论,都不能靠辩说解决

用数据说话

如果你同意了, 就必须拿出行动来.

9.2 注意力点数

编程是需要持续投入精力和注意力的智力活动

注意力点数会随时间流逝而减少.

9.2.1 睡眠

保证睡眠,好好睡上7小时

9.2.2 咖啡因

适度

9.2.3 恢复

在注意力不集中的时候,无法控制注意力,可以想办法花30到60分钟恢复

9.2.4 肌肉注意力

肌肉注意力有助于改善心智注意力

定期训练肌肉注意力

9.2.5 输入与输出

平衡输入与输出

9.3 时间拆分和番茄工作法

25分钟高效工作+5分钟休息,每4个番茄钟休息30分钟

25分钟内,可以拒绝任何干扰

9.4 要避免的行为

优先级错乱:提高某个任务优先级来借口推迟真正急迫的任务

专业开发人员会评估每个人物的优先级,排除个人喜好和需求,按照真实的紧急程度来执行任务

9.5 死胡同

慎重的态度和积累的经验可以帮你避免某些死胡同,但无法避免所有

在走入死胡同时,要迅速意识到,并有足够的勇气走回头路

坑法则,The Rule of Holes:如果你掉进坑里,别挖

9.6 泥潭

泥潭会减慢你的速度,但不会让你彻底停下来

泥潭不容易被发现

发现自己深处泥潭还要固执前进,是最严重的优先级错乱

9.7 结论

专业的开发人员会用心管理自己的时间和注意力

第十章 预估

预估是软件开发人员面对的最简单、也是最可怕的活动之一

10.1 什么是预估

问题在于,不同人不同看法,业务方认为是承诺,开发方认为是猜测. 两者相差迥异

10.1.1 承诺

承诺是必须做到的。

如果你承诺在某天做成某事, 就必须按时完成.

专业开发人员不随便承诺,除非他们确切知道可以完成

如果被要求承诺做自己不确定的事情, 那么就应当坚决拒绝.

10.1.2 预估

预估是一种猜测。它不包含任何承诺的色彩,他不需要做任何约定

大多数软件开发人员不擅长预估。

预估不是个定数,预估的结果是一种概率分布

10.1.3 暗示性承诺

专业开发人员能够清楚区分预估和承诺,只有在确切知道可以完成的情况下,他们才会给出承诺

另外,需要小心避免给出暗示性的承诺

10.2 PERT

计划评审技术

三元分析法

O,乐观估计
N,标称估计 
P,悲观估计

u = (O+4N+P)/6
u是任务期望完成时间

10.3 预估任务

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

10.4 大数定理

把大任务切分成许多小任务,分开预估再加总,结果会比单独平谷大人物要准确很多

10.5 结论

懂得如何为业务人员提供可信的预估结果,以便做出计划

如果做不到, 或者不确定能做到, 专业开发人员不会给出承诺.

第十一章 压力

即使有压力,专业开发人员也会冷静果断。尽管压力不断增大,他依然会坚守所受的训练和纪律,他知道这是他赖以战胜有最后期限和承诺所带来压力感的最好方法

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.1 程序员与人

12.1.1 程序员与雇主

专业程序员的首要职责是满足雇主的需求

专业程序员会花时间去理解业务

12.1.2 程序员与程序员

1.代码个体所有
不正常团队的糟糕症状
2.协作性的代码共有权
共有, 每个人都可以做出合适的修改
3.结对

12.2 小脑

专业人士会共同工作

有些时候,单独工作是正确的。但是一般来说,和他人紧密协作,在大部分时间段中结对工作,是最好的做法

12.3 结论

一定要学会交流,和人们交流

第十三章 团队与项目

13.1 只是简单混合吗?

13.1.1 有凝聚力的团队

形成团队是需要时间的.

团队成员首先需要建立关系。需要学习如何写作,需要了解彼此的批号,强项,弱项,最终,才能凝聚成团队

1.发酵期 
成员克服个体差异,默契配合,彼此信任,形成真正有凝聚力的团队,是需要一定时间的

2.团队和项目,何者为先
把项目分配给形成凝聚力的团队,而不是围绕项目来组件团队

有凝聚力的团队确实有些神奇之处, 他们能够一起创造奇迹.

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

每个团队都有自己的速度。团队的速度,即是在一定时间段内团队能够完成的工作量

13.1.3 项目承包人的困境

13.2 结论

团队比项目更难构建. 因此, 组建稳健的团队, 让团队在一个有一个项目中整体移动共同工作是较好的做法.

第十四章 辅导、学徒期与技艺

14.1 失败的学位教育

14.2 辅导

14.3 学徒期

14.3.1 软件学徒期

1.大师
2.熟练工
3.学徒、实习生

14.3.2 现实情况

程序员的水平是否能够提升和最终是否能够得到职位晋升,全视乎程序员自己的表现

14.4 技艺

技艺是工匠所持的精神状态