我惊奇地发现,许多开发者似乎很沉醉于在工作中处于挣扎的状态。我也确实注意到,现如今,在我们所钟爱的软件开发社区中,人们似乎对于受虐狂始终表现出某种欣赏的态度。但事情不应该是这个样子的。
为什么会变成这样呢?在我开始进行分析之前,请先稍微思考一下刚刚所讲的内容。你在工作中经常会处于挣扎的状态吗?你是否曾经想过,你也会因自己的原因而让其它开发者处于挣扎中?如果你刚刚对某段代码进行了微小的改动,却因为它写的很糟而造成了整个系统无法动作,你会感动挫折吗?
让我们开始一次结对编程演练吧。当两位开发者同时处理某个挑战时,他们将要面对对方的意见和观点,他们的开发观念或许会受到具体行动的质量。理想的解决方案应该是通过和谐的协作而得出的,但也很有可能会发生某一位开发者的观点压倒另一人的情况,而原因是他提出了最好的解决方案。
这种尴尬会比人们想象中更容易造成失望情绪的产生,而如果某位开发者的态度非常暴躁,那么他们在代码的自主权上也可能会产生一些不同意见。换句话说,如果两位开发者都无法做到平静地共同克服挑战,那么“胜利者”也许会将最终的解决方案视为他或她自己的劳动成果,而将“失败者”的劳动视为毫无价值。
这就是开发者会因为他们自己本身,或是其他开发者的原因而感到受挫的一种现象。这种现象的原因在于开发者没有设身处地地考虑过其他开发者的感受。而这种挫折的根源在于开发者的个性。
开发者的个性
我们每个人都是聪明人,并且每个开发者在编码的时候都有着自己的原则。举例来说:
- 在处理某个挑战时的逻辑推论方式
- 在打造某个解决方案时的系统性步骤
- 对于代码优雅性、易读性和格式的偏好(比方说,每个缩进级别应该使用几个空格符?)
- 在“不够理想的解决方案”和“技术债务”之间不够清晰的界限(相信我,每个人都对这种界限有着自己的看法!)
如果你依然认为一个由人类组成的团队能够对以上这些观点完全达成一致,那么请你再好好想想。完全一致的观点是不可能达成的,因为任何一个开发者都不会轻易放弃已经形成的个人原则……这些原则已经成为了他或她的开发者个性了!
这也意味着,其他开发者只需通过阅读你的代码,就能够对你进行某些假设,并看出你的开发原则,从而指出你是谁。在这种情况下,开发者的个性是独一无二的,就像是人类的指纹一样。
在代码审查中,我们会非常自然地通过这种方式学习其他开发者的个性。在审查过程中会出现各种交杂在一起的感受,开发者可能会对某些观点表示赞同,而对其它观点表示反对。代码审查在两种开发者个性之间形成了一种单向的对抗意识,而结对编程则会形成一种双向的对抗。
对抗
两种开发者个性之间的对抗可能会造成不同的结果。一方面,它是非常有教育意义、并且令人振奋的,而另一方面,如果在对抗中缺乏积极的态度,它也会表现出令人受挫、并且令人烦恼的一面,正如上述的示例中所说的一样。
这种对抗造成的感受或许能够解释为什么在每个开发者第一次进行结对编程时,都会或多或少地感受到某些不适。只要亲身参与其中,每个参与者都会最终面对某种对抗性,而这种对抗性在结对编程之外是不会感受到的。因此,每个开发者都被迫远离那个令自己感到舒适的区域,并且个人的原则也遭到某种程度的挑战。
对抗本身决不是像它听起来那样糟糕的东西,但它确实会让所有人感到某种痛苦!实际上,这是因为我们没有正确地对极限编程中某个最简单的观念加以正确地实践,即集体所有权(Collective Ownership)。
所有权
回想一下,你自己了解多少种开源软件。几乎对所有的开源软件都会有好几本书教你如何使用,有时,软件的作者本人也会编写一些对应的书籍,而这些书籍很少是免费的。发生这种情形的原因在于,从所有权的角度来说,编写代码与编写文字是不同的。
参与集体性编码过程比起参与集体性写作来说要自然许多。换句话说,你可以很自然地与其他一些开发者共同写下 100 行左右的代码,但很难与其他作者共同写下 100 行左右的文字。
代码的所有权有时也会变得很复杂。让我们来看一看这个有争议的有关代码所有权的场景,它最近刚刚发生在我身上:
- 你所参与的一个项目具有庞大的代码量,而这些代码是由来自不同地区的许多开发者共同完成的,这些开发者之间彼此之间都一无所知。
- 为了完成你手头的任务,你可能会突然间需要对某些现有的代码进行修改。原有的代码能够正常工作,但你不喜欢它的结构,它明显不够优雅,而你又迫不急待地相要尝试一下最近刚刚学到的某些又酷、又时髦的新思想(例如函数式编程)。当你完成了改动之后,代码看上去变得很棒,你为新代码的优雅性陶醉不已!
- 在你完成了任务之后,就转而去做其它的工作了。在几个月之后,你的某个新任务需要你再次去接触那段相同的代码,却发现不知是哪个家伙打乱了你优雅的代码,使它看上去变得一点也不优雅了……这深深地刺痛了你,你对于这种优雅性(在某种意义上它是属于你的)原本感到十分自豪,但它已经一去不复返了!
- 但是,你的新任务中并不包括将这段代码进行重写的部分,并且对于已经上线的代码进行改动是一件相当高风险的事,尤其在没有 QA 帮助测试这个不存在于待办事项中的用户故事的情况下更是如此。
- 你继续工作于你的任务上,但每当你打开那个文件时,你总是会不断地看到那段令人沮丧的代码,一次又一次……终于,你选择偷偷地将这个文件进行了修改,这样一来,你就有正当的理由将那段肮脏的代码再次修改了。
- 恭喜你,你对这一段在整个公司中都需要用到的代码承担了所有权!每个人都可能出于不同的原因对这段代码进行修改,而你则会沉醉于不断地重新打开这段代码,然后为新代码的肮脏感到受挫的循环之中无法解脱。你会开始每周一次对这段代码进行审查,并且消耗了大量的时间用于修复对齐的问题、对方法进行重命名以保持风格一致,并且用更恰当的语言组织你的注释。在不断重复这些改动之时,你最终会把自己的名字写到代码的作者名之上。
我绝对不是说我们可以选择对技术债务视而不见。但是,必须以一种可持续的流程处理技术债务,而不是因为担心代码会变糟,就像圣母照顾婴儿一样时刻捧在手心里。你应该以一种普通的问题处理流程来面对它:探索、命名、计划,并且在重构之前进行适当的单元测试。而这些是整个团队的工作,是整个团队的共同责任!
集体所有权
极限编程虽然已经不像早些年那样热门了,但它毕竟还没有过时,其中还是有众多有价值的观点。其中的一个规则是集体所有权,它表现了一种协同工作的观念,即集体工作的价值大于每个个体生产价值的总和。
对于这一点,有一种非常危险的误解认为,虽然集体所有权鼓励每个开发者对整体的代码质量都负有责任,但实际上每个人都会感到没有一个人真正地在为质量负责,因此在提倡提高代码质量时,他们都会感到非常孤独。当然,如果他或她打算独立承担这一责任,那确实是相当困难的。
对于这一观点应该这样来看:当所有权属性集体的时候,那么每个开发者就不应当出于个人关注的原因来提倡代码质量。代码质量问题应该在整个团队的努力下进行处理。可以把它简单地看做一支棒球队 —— 我们一起获胜,也一起失利。
一个直接的结论是,每个人就不应该成为改动的瓶颈。如果某段代码背后的知识没有适当地分享给其他人,那么代码的演变逐渐地变为依赖于具体的某个人,瓶颈也就由此而产生。另一方面,在开发代码时能够为集体着想,这不仅能够对你有所启发,并且你也为代码提高了可靠性,这将极大地减少将来出现代码质量问题的机率。我将这一点称为深思熟虑的编程。
要成为一个思想更为缜密的程序员,我还有这样几条建议:
- 始终努力在开发代码时创建单元测试,并且在可能的时候应用测试驱动开发(TDD)方法。这是一种以开发者的角度对代码进行文档化的优秀方式。
- 确保你在不得不对现有的代码进行改动的同时,对单元测试同样进行更新。这不仅能够覆盖你的代码,也能够将你的改动背后的知识进行共享。如果这段代码原本的作者看到了你的新改动,却没有相应的单元测试,他或许会倾向于质疑新的改动是否与代码本来的意图相一致。
- 如果你需要在某个现有方法中加入一些额外的代码,请为这些额外的代码创建一个新的方法,让原来的方法调用这个新方法。这样可以保证原来的方法不会偏离原本创建它的目的,并且针对它的单元测试依然有效,因为可以通过一个桩(stub)的方式,将新的方法从原来的代码中隔离出来。
- 当编写复杂的代码时,请抽出一些时间,使用某些协作工具,例如 Wiki,将你的设计和相关的架构决策进行文档化。这种文档通常来说很快会腐化,原因在于开发者对它们的更新不够频繁,因此有必要在每次有相关的改动产生时,尽快地将这些改动进行文档化。
- 如果你正在编写某些实用代码,请提供一些使用它的示例。一种有效的途径是通过编写单元测试的方法,在一些实际的示例中调用这些实用代码,而不是编写虚构的代码。比方说,如果你正在编写一个计算器的程序,那么就应该在单元测试中依据你的业务逻辑编写更复杂的计算,而不是仅仅测试 2+2=4 这种简单的逻辑。
- 请遵循由整个团队共同制订的代码标准。如果你认为你能够比现有的标准做得更好,请暂时停下编码,并与你的技术领导进行沟通,以改善现有的代码标准,并将它推广到整个团队。不要因为你的代码标准更适合你,就偷偷地使用不同的标准。
- 也许你的代码更为出众,但也尽量不要让你的代码显得过于突出。与从不同的代码并不意味着一定更出色,因为它会带来代码的不一致性,也有可能产生其它问题,因为你无法保证团队中的其他成员也能够理解你的“新标准”(而且他们可能会认为你是在炫耀)。
- 遵守集体所有权总是一件好事,你应该做到自我激励、与他人讨论你的方法、征求他人的的反馈意见,并接受他人的贡献。此外,也应当做到积极地帮助他人,因为很多时候你会从帮助他人的过程中学到许多最有价值的东西。不要认为这是在浪费你的时间,要明白助人为乐的道理。
随着你对集体所有权的相关实践的深入,这种心态会变得越来越自然。在进行代码审查和结对编程过程中,在心中牢记这种观念是很有价值的,通过代码的集体所有权,就能够清晰地理解你和对方相处的位置,以此避免挫折感的产生。
我想在这里特别感谢 Sydney Burns,她慎密的思想与优秀的写作才能对本文起到了很大的贡献。
关于作者
Tiago Garcia**** 是就职于Avenue Code 的一名技术经理,同时也是 Macys.com 的技术主管。他对于各种前沿的前端技术有着深厚的兴趣。他参与了在旧金山举办的 Backbone.js Hackers 会议的组织过程,并且还在各种技术大会中举行演讲,例如 HTML5 Dev Conf。可以通过他的 Twitter 帐号 @tiagooo_romero 找到他,也可以在 tiagorg.com 网站上找到他的一些演讲视频、文章和项目。
查看英文原文: Revisiting XP: be a thoughtful programmer by exercising more collective ownership
评论