程序员的职业素养(读书笔记)-- 第一章
程序员的职业素养(读书笔记)
第1 章 专业主义
1.1 清楚你要什么
“专业主义”有很深的含义,它不但象征着荣誉与骄傲,而且明确意味着责任 与义务。这两者密切相关,因为从你无法负责的事情上不可能获得荣誉与骄傲。 做个非专业人士可轻松多了。非专业人士不需要为自己所做的工作负责,他 们大可把责任推给雇主。如果非专业人士把事情搞砸了,收拾摊子的往往是雇主; 而专业人士如果犯了错,只好自己收拾残局。
1.2 担当责任
经过反省,我意识到未对“例程”进行测试就交付软件是不负责任的。为了 如期交付产品,我忽略了测试环节,整个过程中只考虑要如何保全自己的颜面, 却没顾及客户和雇主的声誉。我本该早点儿担起责任,告诉Tom 测试还未完成、 自己不能按时交付产品。那么做绝非易事,Tom 一定会不高兴,但客户不会丢失 数据,客服经理也不会打电话来轰炸。
1.3 首先,不行损害之事
1.3.1 不要破坏软件功能
软件开发太复杂了,不可能没什么bug。但很不幸,这 并不能为你开脱。人体太复杂了,不可能尽知其全部,但医生仍誓言不伤害病人。 如果他们都不拿“人体的复杂性”作托辞,我们又怎么能开脱自己的责任呢?所谓专业人士,就是能对自己犯下的错误负责的人,哪怕那些错误实际上在 所难免。所以,雄心勃勃的专业人士们,你们要练习的第一件事就是“道歉”。 道歉是必要的,但还不够。你不能一而再、再而三地犯相同的错误。职业经验多 了之后,你的失误率应该快速减少,甚至渐近于零。失误率永远不可能等于零, 但你有责任让它无限接近零。
1. 让QA 找不出任何问题
发布软件时,你应该确保QA 找不出任何问题。故意发送明知有缺陷 的代码,这种做法是极其不专业的。什么样的代码是有缺陷的呢?那些你没把握 的代码都是!
2. 要确信代码正常运行
你怎么知道代码能否常运行呢?很简单,测试!一遍遍地测,翻来覆去、颠 来倒去地测,使出浑身解数来测!你或许会担心这么狂测代码会占用很多时间,毕竟,你还要赶进度,要在截 止日期前完工。如果不停地花时间做测试,你就没时间写别的代码了。言之有理! 所以要实行自动化测试。写一些随时都能运行的单元测试,然后尽可能多地执行 这些测试。
要用这些自动化单元测试去测多少代码呢?还要说吗?全部!全部都要测! 我是在建议进行百分百测试覆盖吗?不,我不是在建议,我是在要求!你写 的每一行代码都要测试。完毕!我是开源项目FitNesse 的主要贡献者和代码提交者。在写作本书的时候, FitNesse 的代码有6 万多行。在这6 万行代码中有2000 多个单元测试,共2.6 万 多行。Emma 的报告显示,这2000 多个测试对代码的覆盖率约为90%。
3. 自动化QA
作为开发人员, 你需要有个相对迅捷可靠的机制,以此判断所写的代码可否正常工作,并且不会 干扰系统的其他部分。因此,你的自动化测试至少要能够让你知道,你的系统很 有可能通过QA 的测试。
1.3.2 不要破坏结构
成熟的专业开发人员知道,聪明人不会为了发布新功能而破坏结构。结构良 好的代码更灵活。以牺牲结构为代价,得不偿失,将来必追悔莫及。
所有软件项目的根本指导原则是,软件要易于修改。如果违背这条原则搭建 僵化的结构,就破坏了构筑整个行业的经济模型。描述如何创建灵活可维护的结构的软件设计原则和模式①已经有许多了。专业 的软件开发人员会牢记这些原则和模式,并在开发软件时认真遵循。但是其中有 一条实在是没几个软件开发人员会认真照做,那就是,如果你希望自己的软件灵 活可变,那就应该时常修改它!
这一策略有时也叫“无情重构”,我把它叫作“童子军训练守则”:对每个 模块,每检入一次代码,就要让它比上次检出时变得更为简洁。每次读代码,都 别忘了进行点滴的改善。
这完全与大多数人对软件的理解相反。他们认为对可工作软件不断地做一系 列修改是危险的。错!让软件保持固定不变才是危险的!如果一直不重构代码, 等到最后不得不重构时,你就会发现代码已经“僵化了”。 为什么大多数开发人员不敢不断修改他的代码呢?因为他们害怕会改坏代 码!为什么会有这样的担心呢?因为他们没做过测试。
1.4 职业道德
职业发展是你自己的事。雇主没有义务确保你在职场能够立于不败之地,也 没义务培训你,送你参加各种会议或给你买各种书籍充电。这些都是你自己的事。 将自己的职业发展寄希望于雇主的软件开发人员将会很惨。
另外,雇主也没义务给你留学习时间。有些雇主会这么做,有些甚至要求你 这么做。但是还是那句话,他们待你不薄,你应该适当表示感激。因为这些优待 不是你理所当然就该享有的。
雇主出了钱,你必须付出时间和精力。为了说明问题,就用一周工作40 小时 的美国标准来做参照吧。这40 小时应该用来解决雇主的问题,而不是你自己的 问题。 你应该计划每周工作60 小时。前40 小时是给雇主的,后20 小时是给自己的。 在这剩余的20 小时里,你应该看书、练习、学习,或者做其他能提升职业能力的 事情。
在此,我不是说要占用你全部的业余时间。我是指每周额外增加20 小时,也 就是大约每天3 小时。如果你在午饭时间看看书,在通勤路上听听播客,花90 分 钟学一门新的语言,那么你就都能兼顾到了。 做个简单的计算吧。一周有168 小时,给你的雇主40 小时,为自己的职业发 展留20 小时,剩下的108 小时再留56 小时给睡眠,那么还剩52 小时可做其他的 事呢。 或许你不愿那么勤勉。没问题。只是那样的话你也不能自视为专业人士了, 因为所谓“术业有专攻”那也是需要投入时间去追求的。
或许你会觉得这样做只会让人精力枯竭。恰恰相反,这样做其实能让你免于 枯竭匮乏。假设你是因为热爱软件而成为软件开发者,渴望成为专业开发者的动 力也正是来自对软件的热情,那么在那20 小时里,就应该做能够激发、强化你的 热情的事。那20 小时应该充满乐趣!
1.4.1 了解你的领域
旧见解过时了这种说法明显是不对的。过去50 年中产生的理念,已经过时的 其实很少。有一部分理论确实在慢慢淡出,比如说“瀑布式开发”的理论确实不 再流行了。但这并不表示我们不需要了解它,不需要知道他的长处和短处。 总的来说,那些在过去50 年中来之不易的理念,绝大部分在今天仍像过去一 样富有价值,甚至宝贵了。 别忘了桑塔亚纳的诅咒:“不能铭记过去的人,注定重蹈先人的覆辙。” 下面列出了每个专业软件开发人员必须精通的事项。 设计模式。必须能描述GOF 书中的全部24 种模式,同时还要有POSA 书
中的多数模式的实战经验。
设计原则。必须了解SOLID 原则,而且要深刻理解组件设计原则。
方法。必须理解XP、Scrum、精益、看板、瀑布、结构化分析及结构化设 计等。
实践。必须掌握测试驱动开发、面向对象设计、结构化编程、持续集成和 结对编程。
工件。必须了解如何使用UML 图、DFD 图、 结构图、Petri 网络图、状态 迁移图表、流程图和决策表。
1.4.2 坚持学习
1.4.3 练习
那么软件开发者该怎样来不断训练自己呢?本书会用一整章的篇幅来谈论各 种练习技巧,所以在此先不赘述了。简单说,我常用的一个技巧是重复做一些简单 的练习,如“保龄球游戏”或“素数筛选”,我把这些练习叫作“卡塔”(kata)①。 卡塔有很多类型。 卡塔的形式往往是一个有待解决的简单编程问题,比如编写计算拆分某个整 数的素数因子等。做卡塔的目的不是找出解决方法(你已经知道方法了),而是 训练你的手指和大脑。 每天我都会做一两个卡塔,时间往往安排在正式投入工作之前。我可能会选 用Java、Ruby、Clojure 或其他我希望保持纯熟的语言来练习。我会用卡塔来培养 某种专门的技能,比如让我的手指习惯点击快捷键或习惯使用某些重构技法等。 不妨早晚都来个10 分钟的卡塔吧,把它当作热身练习或者静心过程。
1.4.4 合作
学习的第二个最佳方法是与他人合作。专业软件开发人员往往会更加努力地 尝试与他人一起编程、一起练习、一起设计、一起计划,这样他们可以从彼此身 上学到很多东西,而且能在更短的时间内更高质量地完成更多工作。
1.4.5 辅导
俗话说:教学相长。想迅速牢固地掌握某些事实和观念,最好的方法就是与 由你负责的人交流这些内容。这样,传道授业的同时,导师也会从中受益。
1.4.6 了解业务领域
每位专业软件开发人员都有义务了解自己开发的解决方案所对应的业务领 域。如果编写财务系统,你就应该对财务领域有所了解;如果编写旅游应用程序, 那么你需要去了解旅游业。你未必需要成为该领域的专家,但你仍需要勤勉,付 出相当的努力来认识业务领域。
最糟糕、最不专业的做法是,简单按照规格说明来编写代码,但却对为什么 那些业务需要那样的规格定义不求甚解。相反,你应该对这一领域有所了解,能 辨别、质疑规格说明书中的错误。
1.4.7 与雇主/客户保持一致
雇主的问题就是你的问题。你必须弄明白这些问题,并寻求最佳的解决方案。 每次开发系统,都应该站在雇主的角度来思考,确保开发的功能真正能满足雇主 的需要。 开发人员之间互相认同是容易的,但把一方换成雇主,人们就容易产生“彼”、 “此”之分。专业人士会尽全力避免这样的狭隘之见。