编码习惯

《高效程序员的45个习惯》学习点

2016-06-28  本文已影响107人  神助

一灯能除千年暗,一智能灭万年愚。 —— 慧能,中国禅宗第6代祖师


第1章 敏捷 —— 高效软件开发之道

不管是预料之外的波浪冲击,还是预想不到的设计失败,在这两种情况下敏捷都意味着可以快速地适应变化

敏捷开发就是在一个高度协作的环境中,不断地使用反馈进行自我调整和完善

第2章 态度决定一切

专业的态度应该着眼于项目和团队的积极结果,关注个人和团队的成长,围绕最后成功开展工作


习惯1:做事

指责不能该修复Bug(Blame doesn't fix bugs)

过程符合标准并不意味着结果是正确的,敏捷团队重结果胜于过程

清晰地表明你的目的是解决问题,而不是指责他人或者进行争辩

把矛头对准问题的解决办法,而不是人。这是真正有用处的正面效应

“这不是我的错”这句话不对,“这都是你的错”这句话更不对

习惯2:欲速则不达

防微杜渐(Beware of land mines)

不要孤立地编码(Don't code in isolation)

使用单元测试(Use unit tests)

不要坠入快速的简单修复之中,要投入时间和精力保持代码的整洁、敞亮

不要急于修复一段没能真正理解的代码。这种+1/-1的病症始于无形,但是很快就会让代码一团糟。要解决真正的问题,不要治标不治本


习惯3:对事不对人

消极扼杀创新(Negativity kills innovation)

负面的评论和态度扼杀了创新

你不需要很出色才能起步,但是你必须起步才能变得很出色

能容纳自己并不接受的想法,表明你的头脑足够有学识

没有最好的答案,只有更合适的方案

设定期限能够 帮你在为难的时候果断作出决策,让工作可以继续进行

设计充满了妥协(生活本身也是如此),成功属于意识到这一点的团队

对事不对人。让我们骄傲的应该是解决了问题,而不是比较出谁的主意更好

只有更好,没有最好。尽管“最佳实践”这个术语到处在用,但实际上不存在“最佳”,只有在某个特定条件下更好的实践

习惯4:排除万难,奋勇前进

做正确的事。要诚实,要有勇气去说出实情。有时,这样做很困难,所以我们要有足够的勇气

如果涉及或代码中出现了奇怪的问题,花实践去理解为什么代码会是这样的。如果你找到了解决办法,但代码仍然令人费解,唯一的解决办法是重构代码,让它可读性更强。如果你没有马上理解那段代码,不要轻易地否定和重写它们。那不是勇气,而是鲁莽

第3章 学无止境

在一个企业化的社会中,只有一个人会为你负责 —— 你自己。是否能跟上变化,完全取决于你自己

如果你跟踪技术变化,那么学习这些新东西对你来说就是了解这些增量变化

学习新的技术和新的开发方法和重要,同时你也要能摒弃陈旧和过时的开发方法

习惯5:跟踪变化

迭代和增量式的学习、了解最新行情、参加本地的用户组活动、参加研讨会议、如饥似渴地阅读

跟踪技术变化。你不需要精通所有技术,但需要清楚知道行业的动向,从而规划你的项目和职业生涯

你不可能精通每一项技术,没有必要去做这样的尝试。只要你在某些方面成为专家,就能使用同样的方法,很容易成为新领域的专家

每天进步一点点,长年累月就是巨大的进步

习惯6:对团队投资

一个学习型的团队才是较好的团队

坚持有计划有规律地举行讲座。持续、小步前进才是敏捷。稀少、间隔时间长的马拉松式会议非敏捷也

习惯7:懂得丢弃

在学习一门新技术的时候,多问问自己,是否把太多旧的态度和方法用在了新技术上

根深蒂固的习惯不可能轻易地就丢弃掉(Expensive mental models aren't discarded lightly)

丢弃的第一步,就是要意识到你还在使用过时的方法,做到真正丢弃旧习惯

不是完全忘记旧的习惯,而是只在适当的技术时才使用它

习惯8:打破沙锅问到底

为了解决问题,你需要很好地了解系统的全局。你需要查看所有你认为和问题相关的部分 —— 即便其他人觉得这并不想干

“这个,我不知道”是一个好的起点,应该由此进行更进一步的调查,而不应该在此戛然而止

习惯9:把握开发节奏

让你的工作有一个节奏,在每天下班的时候,提交所有的工作,开心地收工。这样,明天就能开始新的内容,解决下一系列难题

项目开发需要有一致和稳定的节奏。编辑,运行测试,代码复审,一致的迭代,然后发布

第4章 交付用户想要的软件

你不可能战胜变化,敏捷 —— 取决于你识别和适应变化的能力

习惯10:让客户做决定

决定什么不该决定(Decide what you shouldn't decide)

开发者能做的一个最重要的决定就是:判断是哪些是自己决定不了的,应该让企业主做决定

当你和客户讨论问题的时候,准备好几种方案。不是从技术的角度,而是从业务的角度,介绍每种方案的优缺点,以及潜在的成本和利益

不要随意假设低级别的问题不会影响他们的业务,如果能影响他们的业务,就是有价值的问题

习惯11:让设计指导而不是操纵开发

设计满足实现即可,不必过于详细(Design should be only as detailed as needed to implement)

设计可以分为两层:战略和战术

冯诺依曼:“如果你自己都不清楚所谈论的东西,就根本不可能精确地描述它

战略级别的设计不应该具体说明程序方法、参数、字段和对象交互精确顺序的细节

好的设计应该是正确的,而不是精确的

“不要在前期做大量的设计”并不是说不要设计。只是说在没有经过真正的代码验证之前,不要陷入太多的设计任务。当对设计一无所知的时候,投入编码也是一件危险的事。如果深入编码只是为了学习或创造原型,只要你随后能把这些代码扔掉,那也是一个不错的办法

习惯12:合理地使用技术

盲目地为项目选择技术框架,就好比是为了少交税而生孩子(Blindly picking a framework is like having kids to save taxes)

这个技术框架真能解决这个问题吗?如果需要,先做一个小的原型

也许为了迎合你发现的给你,你正在为它们找问题

不要开发你能下载到的东西(Don't build what you can download

虽然有时需要从最基础开发所有你需要的东西,但那是相当危险和昂贵的

习惯13:保持可以发布

任何时候只要你没有准备好,那就是敌人进攻你的最佳时机

已提交的代码应该随时可以行动(Checked-in code is always ready for action)

如果你不得不让系统长期不可以发布,那就做一个(代码和架构的)分支版本,你可以继续进行自己的实验,如果不行,还可以撤销,从头再来。千万不能让系统既不可以发布,又不可以撤销

习惯14:提早集成,频繁集成

在产品的开发过程中,集成是一个主要的风险区域

绝不要做大爆炸式的集成(Never accept big-bang integration)

成功的集成就意味着所有的单元测试不停地通过。正如医学界希波克拉底的誓言:首先,不要造成伤害

习惯15:提早实现自动化部署

不幸的是,大部分开发者只会在项目的尾期才开始考虑部署问题

质量保证人员应该测试部署过程(QA should test deployment)

如果你打算把持续部署系统和产品CD或者DVD刻录机连接到一起,你就可以自动地为每个构建制作出一个完整且有标签的光盘。任何人想要最新的构建,只要从架子上拿最上面的一张光盘安装即可

习惯16:使用演示获得频繁反馈

需求就像是流动着的油墨(Requirements are as fluid as ink)

你生产出了他们曾经要求过的软件,但却不是他们现在真正想要的。那最后的结果就是:惊讶、震惊和失望,而不是满意

清晰可见的开发。每隔一两周,邀请所有的客户,给他们演示最新完成的功能,积极获得他们的反馈

演示是用来让客户提出反馈的,有助于驾驭项目的方向。如果缺少功能或者稳定性的时候,不应该拿来演示,那只能让人生气

可以及早说明期望的功能:让客户知道,他们看到的是一个正在开发中的应用,而不是一个最终已经完成的产品

习惯17:使用短迭代,增量发布

给我一份详细的长期计划,我就会给你一个注定完蛋的项目(Show me a detailed long-term plan, and I'll show you a project that's doomed)

对付大项目,最理想的办法就是小步前进

大部分用户都是希望现在就有一个够用的软件,而不是在一年之后得到一个超级好的软件

增量的发布必须是可用的,并且能为用户提供价值。你怎么知道用户会觉得有价值呢?这当然要去问用户。

使用MVP的思想来指导开发

习惯18:固定的价格就意味着背叛承诺

固定的价格就是保证要背叛承诺(A fixed price guarantees a broken promise)

敏捷不是意味着“开始编码,我们最终会知道何时可以完成”。你仍然需要根据当前的知识和猜想,做一个大致的评估,解释如何才能到达这个目标,并给出误差范围

第5章 敏捷反馈


习惯19:守护天使

编写能产生反馈的代码(Coding feedback)

人们不编写单元测试的很多借口都是因为代码中的设计缺陷。通常,抗议越强烈,就说明设计越糟糕

习惯20:先用它再实现它

编程之前,先写测试(Write tests before writing code)

好的设计并不意味着需要更多的类(Good design doesn't mean more classes

不要把测试优先和提交代码之前的测试等同起来。测试先行可以帮助你改进设计,但是你还是需要在提交代码之前做测试。

习惯21:不同环境,就有不同问题

使用自动化会节省时间(Automate to save time)

硬件比开发人员的时间便宜。但如果你有很多配置,要支持大量的平台,可以选择哪些平台需要内部测试

习惯22:自动化测试

为核心的业务逻辑创建测试。让你的客户单独验证这些测试,要让它们像一般的测试一样可以自动运行

习惯23:度量真实的进度

专注于你的方向(Focus on where you're going)

一周工作40个小时,不是说你就有40个小时的编码时间。你需要减去会议、电话、电子邮件以及其他相关活动的时间

习惯24:倾听用户的声音

这是一个bug(It is a bug)

每一个抱怨的背后都隐藏了一个事实。找出真相,修复真正的问题

没有愚蠢的用户,只有愚蠢、自大的开发人员

学会倾听

第6章 敏捷编码


习惯25:代码要清晰地表达意图

C.A.R Hoare:“设计软件有两种方式,一种是设计得尽量简单,并且明显没有缺陷。另一种方式是设计得尽量复杂,并且没有明显的缺陷。”

代码清晰程度的优先级应该排在执行效率之前

应该让自己或团队的其他任何人,可以读懂自己一年前写的代码,而且只读一遍就知道它的运行机制

习惯26:用代码沟通

不要用注释来包裹你的代码(Don't comment to cover up)

源代码可以被读懂,不是因为其中的注释,而应该是由于它本身优雅而清晰

代码能够自解释,而不用依赖注释

良好的命名可以向读者传递大量的正确信息,不好的命名不会传递任何信息,糟糕的命名则会传递错误的信息

不必费尽新机去用繁冗的名字替换大家已习惯的名称

解释代码做了什么的注释用处不那么大。相反,注释要说明为什么会这样写代码

习惯27:动态评估取舍

问题的关键是要多长个心眼儿,而不是总按照习惯的思路去解决问题

没有最佳解决方案(No best solution)

过去用过的解决方案对当前的问题可能适用,也可能不适用。不要事先预设结论,先看看现在是什么状况


习惯28:增量式编程

在写了几行代码之后,你会迫切地希望进行一次构建/测试循环。在没有得到反馈时,你不想走得太远

习惯29:保持简单

简单不是简陋(Simple is not simplistic

代码几乎总是可以得到进一步精炼,但是到了某个点之后,再做改进就不会带来任何实质性的好处了。这是开发人员就该停下来,去做其他方面的工作了

习惯30:编写内聚的代码

根据单一职责原则,一个模块应该只有一个发生变化的原因

感觉类和组件的功能都很集中:每个类或组件只做一件事,而且做得很好。bug很容易跟踪,代码也易于修改,因为类和组件的责任都很清晰

习惯31:告知,不要询问

面向过程的代码取得信息,然后做出决策。面向对象的代码让别的对象去做事情

将命令与查询分离开来(Keep commands separate from queries)

不要抢别的对象或组件的工作,告诉它做什么,然后盯着你自己的职责就好了


习惯32:根据契约进行替换

针对is-a关系使用继承,针对has-a或uses-a关系使用委托(Use inheritance for is-a, use delegation for has-a or uses-a)

相对继承来说,委托更加灵活,适应力更强

第7章敏捷调试


习惯33:记录问题解决日志

不要在同一处跌倒两次(Don't get burned twice)

维护一个问题及其解决方案的日志

习惯34:警告就是错误

将警告视为错误。签入带有警告的代码,就跟签入有错误或者没有通过测试的代码一样,都是极差的做法

习惯35:对问题各个击破

用原型进行分离(Prototype to isolate)

以二分查找的方式来定位问题是很有用的。也就是说,将问题空间分为两半,看看哪一半包含问题,再将问题的一半进行二分,并不断重复这个过程

习惯36:报告所有的异常

处理或是向上传播所有的异常。不要将它们压制不管,就算是临时这样做也不行。在写代码时要估计到会发生问题

习惯37:提供有用的错误信息

提供给用户的信息可以包含一个主键,以便于在日志文件或是审核记录中定位相关内容

第8章 敏捷协作


习惯38:定期安排会面时间

站会每个人要回答三个问题:昨天有什么收获?今天计划要做哪些工作?面临哪些障碍?

迅速地开始可以保证会议短小,不要浪费时间等着会议开始

习惯39:架构师必须写代码

不可能在PowerPoint中进行编程(You can't code in PowerPoint

Donald E. Knuth:“新系统的设计者必须要亲自投入到实现中去。”

真正的架构师,如果不允许参与编码的话,他们会提出强烈的抗议

不要允许任何人单独进行设计,特别是你自己

习惯40:实行代码集体所有制

在团队中实行任务轮换制,让每个成员都可以接触到不同部分的代码,可以提升团队整体的知识和专业技能

要强调代码的集体所有制。让开发人员轮换完成系统不同领域中不同模块的不同任务

习惯41:成为指导者

教学相长(Knowledge grows when given

努力爬到高处,再以蔑视的眼神轻视其他人,这似乎是人类本性

为团队成员在寻求帮助之前陷入某个问题的时间设定一个时限,一个小时应该是不错的选择

习惯42:允许大家自己想办法

感觉不是以填鸭式的方式给予别人帮助。不是有意掩饰,更非讳莫如深,而是带领大家找到自己的解决方案


习惯43:准备好后再共享代码

绝不要提交尚未完成的代码,故意签入编译未通过或是没有通过单元测试的代码,对项目来说,应被视为玩忽职守的犯罪行为


习惯44:做代码复查

Capers Jones《估算软件成本》:“要寻找深藏不露的程序bug,正式地进行代码检查,其效果是任何已知形式测试的两倍,而且是移除80%缺陷的唯一已知办法。”

要确保代码复查参与人员得到每次复查活动的反馈。作为结果,要让每个人知道复查完成后所采取的行动

习惯45:及时通报与问题

接受一个任务,也就意味着做出了要准时交付的承诺

经常抬头看看四周,而不是只埋头于自己的工作


也许你会喜欢:

5分钟阅读:Java程序猿篇-筑基01

《产品经理的20堂必修课》学习点

5分钟阅读:知识大爆炸-《一个故意不通过图灵测试的人》-第1部分

上一篇下一篇

猜你喜欢

热点阅读