如何扮演程式经理的角色?

作者:周思博(Joel Spolsky)
属于Joel on Software, http://www.joelonsoftware.com

制作伟大软体的秘方之一是:有个好的程式经理。你的团队里应该没有这号人物,因为大部分的团队都没有。

Charles Simonyi,那位发明了「所见即所得」(WYSIWYG) 文字处理软体、跟Martha Stewart 约会、赚进价值亿万的微软股票而且上了太空的天才程式设计师,是首位尝试着组织超大开发团队来解决[人月神话](http://www.amazon.com/gp/product/ 0201835959?ie=UTF8&tag=joelonsoftware&linkCode=as2&camp=1789&creative=390957&creativeASIN=0201835959)的人。他创造了这样的制度:由一位超强工程师来设计系统里最高阶、最上层的函式,然后一群菜鸟工程师就根据这些设计来实作较低阶的函式与其中的细节。这「超强工程师」的职位就是本文所说的程式经理。虽然 Simonyi 如此的聪明,但是这个方法确不是很高明。我猜,原因是没有人想当菜鸟工程师。

八经零年代后期,微软Mac Excel 团队的Jabe Blumenthal 回收「程式经理」这个职称并拿来作为其它用途。他注意到软体规模日趋复杂,几乎没有工程师有时间搞清楚怎么做出好用且有用的软体。但是工程单位却没有人有时间和高举顾客需求的大旗的市场单位做沟通,或是把这些 MBA 专用语言转换成真正有意义的功能。设计一个产品要做的事真的好多:跟使用者沟通、可用性测试、检视竞争产品还有努力的让产品变得更简单易用。但是大部分的工程师真的没有时间做这些事情(或是不适合做这些事情)。Blumenthal 重新定义了「程式经理」这个职位的工作内容。

程式经理做些什么?

此后,程式经理的工作变成:

  • 1. 设计使用者操作介面
  • 2. 撰写功能规格书
  • 3. 协调开发团队
  • 4. 作为使用者的代言人
  • 5. 穿破Banana Republic 衬衫

小型产品或许只需要一个程式经理,不过在大一些的产品则可能有好几个,其中每个人都负责一部分的功能。实用的规则是:一个程式经理搭配四个程式设计师。有个我从 Mike Conte 那里学到的方法可以解决切分系统功能时遇上的困难:依照使用者的活动来拆解系统。比如说,我们可以把 Twitter 拆解成四种使用者活动:

  • 1. 注册与启用
  • 2. 发文、读取回应
  • 3. 设定帐号
  • 4. 找新闻

我初次担任程式经理是在微软Excel 产品中负责「自订」这个使用者活动,例如撰写脚本或是巨集指令。我要做的第一件事是去厘清使用者需要什么,所以我尽可能的多做客户访谈,直到我发觉客户给的都是一样的回馈而觉得无聊为止。为了想知道一​​年半开发周期能做到哪些事,我花了很多时间跟开发团队沟通。也用了许多时间询问 Visual Basic 团队是否能够提供编译器、程式编辑器与对话盒编辑器给Excel 里的巨集语言功能。我曾经去过当时正在开发AppleScript 这个通用巨集语言的苹果电脑。还有微软里的许多与Excel 产品类似的团队诸如Word,Access,Project 与 Mail。大多数时候,这个过程大多是由交谈、开会、email 与电话所组成。因为被这样的生活吓到了,我是缩在办公室里害怕电话铃声响起。

接下来则是写下一份愿景声明:这是种概略的高阶文件,说明了诸如VisualBasic 如何在Excel 里运作、一些巨集程式的例子、待开发的主要功能以及这些东西解决了什么问题等。当其他人对这份文件不再有太多异议时,我便开始制作更详细的规格,连最不起眼的细节都做出解释、使用者看到的每个东西长什么样子等。

这是一份功能规格,不是技术文件。意思是这整份文件都在阐述使用者看到什么,而不是怎么实作这些功能(这里可以找到一切关于功能规格的资讯);程式经理不关心工程师怎么实作这些东西。接下来当我把一些章节拿给研发主任 Ben Waldman 时,他和他的团队坐下来讨论并说明将会如何实做这些功能。他们最后得出了相当高明又简洁的表格,把我当时定义的物件导向使用者介面套进 Excel 的内部实作。不过这不是我的工作,我不太了解Excel 内部细节也不知道怎么实作这些功能。

老实说,我不是万能的天神。身为一个刚毕业的新鲜人,我没有太充分的程式、测试、文件、行销或可用性测试的经验。幸运的,微软在前述每个领域都有经验极丰富的大师级人物;而这些人成就了今天的我,而且真正动手作出产品正是这些人。例如,当使用者在 Excel 里想把格子里的数值复制到某个变数里:

x = [A1]

问题是这格子的内容可能是数值或字串,但是在Basic里,阵列的资料型态必须在变数被使用之前就完成宣告。

看来要Basic 可以动态处理型别才行,但是我没聪明到晓得该怎么做。没关系,Visual Basic 的Tom Corbett 解决了这个问题。因此,Variants 和IDispatch 问世了,而且Basic 变成你们这些小朋友现在所说"duck typing” 程式语言。不过,重点是我的工作并不需要解决这些问题。我的工作是搞清楚客户需要什么,并确定工程师知道怎么解决这些问题。

当规格底定且开发团队开工之后,我的职责变成:解决开发过程中出现的规格问题、与其他开发团队沟通以便让工程师专心工作。我也向测试人员解释这些功能该怎么运作并协助他们作测试计画。我也确认了文件编辑人员真的了解怎么写出好的 Excel Basic 教学与参考文件。我还跟localization 专家研究出localization 策略。也和行销部门深入解释VBA 能对产品销售带来什么好处。还跟软体可用性专家安排了一些可用性测试。

好的程式经理一定要开很多的会,但是除了文件之外不会产出太多东西。这就是为什么一个菜鸟如我都可以接下这份工作的原因。你不会因为没写过十四年的程式而当不成程式经理(事实上,十四年的程式经验可能会使你因为懂得太多而不适合成为使用者的代言人)。

冲突

如果没有程式经理,那些天才程式设计师会做出让你五体投地的操作介面,不过前提是:如果你是瓦肯星人的话。我们都知道,最优秀的程式设计师通常无法想像竟然有人记不住十六种命令列参数。这些程式设计师也倾向在写完程式以后就坚守已经做好的结果。

程式经理为软体设计过程所能做的最棒的事情是「对于该怎么设计一个功能提出不同的意见」,希冀能让人们用同理心来看待使用者:那些令人讨厌的傻瓜。他们要求在不阅读说明书之前就能顺利使用软体、用 lisp 自订emacs 函式、或是转换为八进位的心算。

好的程式经理会提出她觉得使用者介面该怎么运作的想法,可能比开发人员想到的要好、甚至较差,然后就是冗长的争论了。通常程式经理的方向是让使用者容易上手的设计,像是能感知使用者意向的操作介面、一个能塞进口袋的三十吋萤幕。而工程师想做的则是整合 Python 的文字操作介面(哪里不好用了?)。

在我的记忆中,Excel 5 专案里最重要的一次辩论是关于枢纽分析表的显示。程式设计师想让枢纽分析表浮在试算表上方的绘图层,而他的程式经理则坚持要让分析表显示试算表中的格子里。这个争论真的持续了非常久。终于,程式经理占了上风。不过最后的设计比两人各自主张的都好上了许多。

让程式经理和工程师处于相等地位绝对是确保辩论过程相互尊重并持续以理性、事实为基础的重点。如果工程师归程式经理管辖,则在争得昏头的程式经理很容易就会丢下一句:「好了,讨论得够多了,就照我说的作吧。」,这样的事情在双方地位平等时则不会发生。这有点像是法院法里的:「我们不允许某方律师变成法官,所以我们致力于『当双方地位平等之时的辩论最能够揭发真相』的理论」。一场辩论只有在没有一方具有不公平优势的状况下才可能公平。

这一点很重要,如果你刚作了想知道就读十一年级时的莎莉现在在哪的白日梦,醒醒吧。她现在是个住在Scottsdale 的生物学家兼共和党员。注意了:程式设计师不能是程式经理的下属。此外,开发主任,技术长或是执行长都不该是决定规格的人。

大部分公司最大的错误是让程式设计师的经理来写规格与设计产品。为什么这是个错误呢?因为这样的设计过程里没有公平的审视,也没有经过冲突与辩论,所以结果不会像它该有的那么好。

我之前是那样一路跌跌撞撞走过来的。而我自己在Fog Creek 公司也作很多程式管理的工作,我必须不断地提醒同事必须在我说错事情的时候跟我争论。Fog Creek 不是个大公司,但是现在也大到需要有程式经理了,他们是Dan 与Jason,程式设计师很爱跟他们辩论。

当然,当程式设计师跟程式经理处于平等状况下,常常是程式设计师占上风。曾经有好几次,程式设计师要我干预他们跟程式经理之间的辩论:

「这个程式是谁要实做的?」,我问道

「我…」

「好吧,然后是谁把程式码commit进版本管理呢?」

「我猜,是我吧…」

「那到底有什么问题?」,我问道:「产品任何一个bit 的长相你都有绝对的控制权,你还需要什么?让你当教宗吗?」

明白了吧,这个系统把压力摆到程式经理身上,让他们设法去说服工程师。因为一个绝望的程式设计师可能会凭自己的感觉做事,这样的结果对程式经理是有风险的。因此,要成为有效率的程式经理,你必须要 1)正确,2)赢得工程师的尊敬,然后他们才会认同你的看法。

怎么得到工程师的尊敬?

无论对方有多聪明,程式设计师通常更尊重会写程式的人。所以有个方法是:程式经理本身很能写程式。但是这并不公平,因为程式经理并不被期待是个程式设计师。所以能干的程式经理可以不会写程式,但是这样要赢得程式设计师的尊重会难上一些。

另一种让程式设计师尊敬你的方法是展现你的智慧、开放的心胸与公平处理每次的争论。当程式经理讲了傻话,程式设计师就会把他标示成「傻瓜」。如果程式经理一意孤行,作了不合理的事情,就会失去他人的信任。程式经理特别需要在争论中屏除个人情绪,并乐于将证据纳入考量,根据事实改变看法。最后,如果程式经理为了赢得争论而去搞政治手段,例如私底下找老板、搞各个击破等,则他们终将失去程式设计师的信任。

程式经理若失去程式设计师的信任,那一切就完了。这团队将不再是有效率的团队。程式设计师开始不把程式经理当一回事,并且搞他们自己想要的东西。结果就是浪费时间又产出一堆烂程式码而已。这时候你除了支付薪水给这个没用的程式经理之外,这个人还会把大家拉去开会并耗光大家的时间,但是结果终究不会变得更好。

规格?这样实在很不Agile

「不写文件」的想法正在许多撰写规格书形同具文的研发单位里如雨后春笋般的冒出来。其实,这些人都被误导了。撰写功能规格是敏捷软体开发的核心之一,因为它让我们在动手写程式之前有机会迅速的审视多种设计的可行性。跟修改写好的程式比起来,修改一份文件实在是容易多了。认真撰写规格文件强迫我们仔细去思考自己脑袋里的设计并迅速发现其中的问题,所以我们可以尝试更多的设计。采用功能性规格设计的团队能产出设计较好的软体,因为他们有机会发掘更多可行的方案。而这样子写起程式来也快了许多,因为工程师在开始写程式的时候已经很清楚接下来需要做什么。「没规格就不写程式」是 Fog Creek 公司的一个不能妥协的原则。

功能规格书并没有一定的形式。所有规格必须做的是去解释程式的行为而非程式如何运作之类的事情。我们从最高阶的「愿景描述」开始,使用少于一页的篇幅来描述这个新功能的重点。愿景确定之后就开始作分镜,也就是仿制使用过程的画面原型,并详细标示这些东西如何运作。对于许多功能,尤其是与使用者操作介面高度相关的功能,这些分镜完成就大致代表工作完成了,这就是你的规格。Jason Fried,滚吧。

你必须为分镜里没有提到的复杂功能所伴随的隐藏行为写下更多的细节。无论如何,写文件能让你在开始写程式之前就发现问题、冲突与设计上的缺陷。所以当你真正开始写程式的时候,遭遇未曾思考过的问题而导致程式重写的机会就比较低了;更惨的则是,较差的设计。

怎么学习当个程式经理?

大多时候,作为程式经理是一种学习:学习技术、了解人性、搞懂怎么在组织政治里有效率的做事。好的程式经理能把工程师的想法整合到设计里,并像政治家一样把人聚在一起并建立共识。当你在做这些事情的时候,可以读一读这些书:

就我所知,Scott Berkun 的「Making Things Happen」是唯一一本内容涵盖了程式经理所要做的事情的书。所以从这一本开始吧。Scott 曾经在Internet Explorer 团队担任多年的程式经理。

程式经理的一大部分工作是设计使用者操作介面。首先可以读Steve Krug 的「Don't Make Me Think」,然后是我写的「User Interface Design for Programmers」。

最后,我知道这听起来很俗气,不过Dale Carnegie 在1937 年写的「How to Win Friends & Influence People」真的是的超棒的人际关系入门书。这是我所指定的在Fog Creek 里受训的经理人要阅读的第一本书。这些人一开始总是在私底下窃笑,不过大家在读完之后都会爱上这本书。