论软件开发中的三种重要角色
论软件开发中的三种重要角色
出处 本文原载于《程序员》杂志
刘天北
...因为人的灵魂中,有着某种三头政体,或者说,三个对手,三重政权,它之扰乱这一共和国的安宁,并不减于它之搅扰罗马的国制。
托马斯·布朗 《医生的宗教》I.19
1
“三”据说是玄学家们偏爱的数字。对于这种怪癖或狂热,我只能自认免疫力不足:在“三段论、三权分立、三位一体...”这个似乎无休止的列表上,我甚至想再加上一点儿自己的贡献——在我看来,通常称为“软件工程”的学科至少包括三个重要的组成部分:产品设计、系统构架设计和项目控制,而相应地,软件开发队伍中也有三个重要角色:产品经理、系统架构师和项目经理。
《人月神话》一书的读者都能理解“概念完整性”对于软件系统的重要性。概念完整性指的是,软件系统作为一个整体,对于使用者体现出的概念上的一致性、清晰度和简洁度。按照该书作者Brooks的看法,概念完整性是设计软件时需要考虑的首要因素,而为了确保概念完整性,应该要求1)区分系统设计和系统实现工作;2)系统设计的工作由一个人或不多的几个达成共识的人完成。这里谈的“系统设计”,基本上对应于我说的“产品设计”,即,确定软件系统的功能、性能指标、交互模式等方面的需求。质言之,产品设计者决定“做什么”的问题,而把“怎么做”的问题留给实现人员(implementers)来完成。
这样就引入了第一组工作划分。这里的重点是,产品设计应该由专人负责,而不是交给“程序员”代庖。相反的实践,即让具体开发者确定产品设计细节的做法,在国内软件业似乎仍很常见,但正如《人月神话》所言,这是一种非常危险的尝试。首先,如果产品的各个设计细节由多个开发者按各自的设想确定,那么概念完整性就几乎一定会被破坏。其次,具体开发者往往更注重系统实现中的技术因素,而对最终使用者的需求、动机和感受都缺乏体认,因而单纯出自程序员的产品设计,总是会偏离使用者对业务和易用性的实际需要,很难获得用户的欣赏——有一个略显过分的比喻甚至说,让程序员做产品设计,无异于让精神病患者们自己运营疯人院。
而谈到产品设计或系统需求确定,另一种流行的误解是,这应该是客户的任务:“需求调研人”至多需要记录下客户的所有需求,就能形成完美的需求规格设计书。天知道(至少,任何做过委托开发的人都知道)这种论调和国内客户的实际情况之间的差距。不止一次,我拿到的全部客户需求就是:开发一套电子商务系统。句号。设计产品或确定系统需求不仅需要行业、领域经验(这是“客户”的优势所在),更需要大量同类系统的使用经验(甚至开发经验)以及较强的抽象能力、表达能力等等。而目前很多客户,由于接触同类系统有限,自身业务流程也远未标准化,若指望他们提出清晰、明确的需求,好比是让一个只会喊“饿”的小孩儿进饭馆点菜。开发团队必须委派专人,通过耐心诱导和反复尝试才能获知他们的实际需要。
负责产品设计的“专人”通常称为“产品经理”。我心目中理想的产品经理,应同时具备较高的商业素质和较强的技术背景。
具体地说,首先,一个优秀的产品经理要有深厚的领域经验,也就是说,对该软件系统要应用到的业务领域非常之熟悉。比如,开发房地产销售软件的产品经理,应该对房地产公司的标准销售流程了如指掌,甚至比大多数销售人员还要清楚。如果开发的是通用产品,他/她还具备对市场、潜在客户需求的深刻洞察力。
其次,他/她应该善于完成从使用者视角到开发者视角的转化,善于将繁复的实际业务抽象为概念模型和人机交互操作。
再次,他/她在技术方面也应该具备足够的知识,能对特定需求的可行性做出初步的衡量,能够做出方案选型的抉择。功能需求往往符合Pareto's Principle(20-80原则),怎样设计一个开发代价最小,而覆盖需求最多的功能集,怎样确定各个功能在实现时的优先度,是产品经理必须懂得的艺术。另外产品经理应该知道采用特定开发平台、特定工具产品的优势和代价,并从商业角度出发做出选择。
最后,他/她还应该能够确定系统在人机交互方面的主要特征。程序员设计的产品为世人讥评,很大程度上要归咎于糟糕的交互(UI)设计。产品经理应该能够从商业角度出发,了解特定客户/潜在客户群在人机交互方面的需求,并能衡量特定的人机交互模式的实现难度——在很多场合中,某个微小的操作模式的变化会导致整个系统实现构架的变化,因此,尽早确定UI的主要特征,并要求它们在整个系统内保持一致,对于概念完整性和系统技术构架都是至关重要的。
对一次软件开发来说,产品设计是源头,是核心。因而产品经理的工作质量也直接关系到开发的成败。记得一位业内资深人士曾说,合格的产品经理需要一份MBA学历,再加上原先若干年的技术开发经验。综合考虑以上素质,我相信他提出了相当中肯的要求。
如上所述,产品设计是一个复杂、困难的过程,其中充斥着争论和妥协、权衡和决断,并且,根据软件处理的实际业务不同,这个过程的内涵也千差万别。让我们暂时告别这段恶魔般的旅程,轻快地考察另一个较为清晰的领域:“系统构架设计”。 软件开发网
系统构架,是对已确定的需求的技术实现构架。与产品设计相比,系统构架设计的工作更明确,而目前该领域也已经形成了较为成熟、完善的方法论和一整套易于掌握、传授的知识。相应地,系统架构师是一个不折不扣的技术人员,主要着眼于系统的“技术实现”。他/她的责任是最终确认和评估系统需求,给出开发规范,搭建系统实现的核心构架,并澄清技术细节、扫清主要难点。因此他/她应该是特定的开发平台、语言、工具的大师,对常见应用场景能马上给出最恰当的解决方案,同时要对所属的开发团队有足够的了解,能够评估自己的团队实现特定的功能需求需要的代价。
这里,最容易导致误解的部分是产品经理和系统架构师的区别。我感到现有的不少论述和实践都倾向于将二者混为一谈。但在我看来,如果把开发软件比作摄制电影,产品经理之于系统架构师,就正像编剧之于导演。产品经理虽然要有一定技术背景,但仍应属于“商业人士(business people)”,而系统架构师则肯定是一个技术专家。二者看待问题的立场、角度和出发点完全不同。当然,就像有时电影导演也出任编剧(甚至存在“作家电影”流派),对于特定的开发领域或项目,产品经理和系统架构师这两种角色的重合也可能是无害、甚至有益的(我能想到的一个领域是编程语言的设计),但即使如此,不加区别地对待需求和实现、产品设计和系统构架设计,肯定是危险的。如果你处在一人权充两种角色的情况下,你应该时刻意识到自己目前进行的是哪一种职责,并据此调节视角和思路。
我感到这两种角色的含混还来自人们对“architect”这个表达方式的不同用法。Architect和architecture,这组显然是借自建筑学的隐喻,经常被不加区别地使用在产品设计和技术实现这两个不同的方面。Brooks本人在《人月神话》做出的“architect”和“implementer”区分,基本上对应于我在上面谈到的“产品设计”和“技术实现”,但是由于“技术构架”本身也可以称作architecture,所以一般谈到system architecture或system architect时,人们关注的却主要是技术实现方面。正如Martin Fowler所说,人人都想被称为architect而不只是engineer,所以这里用语的含混可能也体现了不同领域的人们对architect这个好词的争夺。
必也正名乎。有一派哲学理论认为,多数“大问题”实际上都源自琐碎的语词误用。希望上述讨论也能通过区分名称而澄清软件开发中的一个重要事实。
如果继续上面的电影隐喻,那么摄制组中的“制片”职责也就对应于我所说的“项目控制”。显而易见,项目控制工作与上面谈到的产品设计、构架设计都不同,如果说产品设计偏重于“商业”、系统构架设计偏重于“技术”,那么项目控制注重的就是“管理”。它主要关注的是项目本身的进度、质量等方面。软件开发项目需要专人负责这些内容,我愿意称此为“项目经理”。
项目控制/管理已经形成了一个专门的学科(Project Management),对于软件项目经理,其职责也未脱离该学科的描述,包括项目计划、进度跟踪/监控、质量保证、配置/发布/版本/变更管理、人员绩效评估等方面。优秀的项目经理需要的素质,并不仅在于会使用几种软件或是了解若干抽象的方法论原则,更重要的在于从大量项目实践中获得的宝贵经验,以及交流、协调、激励的能力,甚至还应具备某种个性魅力或领袖气质(charisma)。通俗地说,也许学校里的学生会主席要比“学习尖子”更适合这样的职位。
由此可见,项目经理和系统架构师在职责上有很大差异。混同这两个角色,往往也会导致低效、无序的开发。特别是,从性格因素上讲,单纯的技术人员倾向于忽视“人”的因素,而这正是管理活动的一个主要方面。另外,就像战争中的空军掩护(air cover)一样,专职的项目经理能够应付开发过程中大量的偶发事件和杂务,对于一个规模稍大的项目(《人月神话》似乎说的是6个人以上),这些杂务本身就能占用一个全职工作者的几乎全部时间。
2
也许我已经论证了上述三种角色分工的必要性。笼统地说,正如其他人类制度一样,分工自身也同时具有益处和代价。如果允许一个空泛的概括,分工的优点至少有:1)集中特定的知识、技能——想想自己左右手、左右脑的分工,我们也许就可以理解这对提高生产率的重要性;2)职责明确,不同职责的人为自己做出的决定负责;3)增进交流:各个角色之间为确保顺畅的协作,必须要求高质量的交流,这也就能使很多原本不言而喻的事情书面化、明晰化。
但分工也有其自身的弊病。首先,不少人天性追求完满,要让他们接受分工,只完成整个工作的一个枝节部分,可能是非常痛苦的事。我记得自己刚刚参加工作后参与开发的一个系统,直到开发接近尾声,项目经理才在一次每周例会上说:“大家开发了这么久,对整个系统的用途可能还不很清楚,今天我们简单谈谈”——这时我才知道自己参与的是整个店铺系统的销售子系统的订货部分的一个底层数据模块。
另外,分工往往导致等级制度和不同角色间的疏离。既然分工的要义是把高要求的工作集中在少数人手中,在少数和大多数之间,不同的工种之间,必然会导致等级差异和隔阂。《人月神话》中也谈到,在区分了产品设计和技术实现之后,单纯的实现者会感到仅仅听命于人,常常缺乏独自开发时的“成就感”。这也是素朴的、混沌未开的开发过程一旦引入分工,就必然产生的异化。
如果说,上面谈到的这两点还应该算是人类各种分工制度共有的“必要的恶”,软件开发中的分工还有一种特有的弊端:细致的分工与“重量级方法论”之间有很强的亲和性,倾向于导致更高的开发成本和开发风险。
对于产品设计和系统构架设计来说,将决策权集中在产品经理和系统架构师手中,意味着一种集权式的专制体制。这也要假设,这些负责人对产品或系统构架具备了充分的、无遗漏的了解。整个系统从他们头脑中的理念萌芽演化,再通过文档等介质,最终被实现为软件产品。如果产品经理确实能够从一开始就清晰、完整地把握客户需求,选定的开发平台、技术对系统架构师也不存在任何难点,那么类似的集权制可能是合理而且高效的。但软件开发往往充满革新和变数,客户需求一日千变,开发技术也日新月异,大量不确定因素的引入,使集权体制变得非常可疑。如果需求和设计无法自顶向下、一步到位的给出,而是需要多次反复、迭代才能渐趋完善,那么一个多级的、细分工的开发体制与扁平的、粗分工的体制相比,就需要更大的初期代价(initial investment),更多的文档和交流,并缺乏后者灵活、自适应的应变能力。
极限编程(XP)方法论,就在很大程度上抵制了上面提到的分工体制。
XP开发过程中用“素材(user stories)”取代了需求规格设计书(SRS)。一组由“客户”粗略书写的素材,直接由程序员加以评估和实现,并根据现场客户(on-site customer)意见修改。因此上面所说的产品经理角色,就被客户和程序员之间的合作完全取代了:无须产品经理给出细化、明晰的需求,只要程序员体会素材中的意思,做出实现,再通过客户反馈逐次迭代,就能获得不错的系统。
而系统架构师在XP方法论中也没有容身之处。系统构架不再是充分设计的产物,而是一个不断演进、不断完善过程的结果。具体的决策权留给了程序员自身,团队中的顶尖程序员不再充当系统架构师,而是担任“教练(coach)”的角色,启发新手自己找到合适的构架,并在确实困难的时候扮演救火者。
事实上,传统的“按照蓝图设计建筑物”的隐喻在XP方法论中失去了价值。对比一下《人月神话》和《XP Explained》中“architect”一词的出现频率(在后者中我只发现了两次,而且用的都是否定意义),我们就可以发现这种态度上的变化。取而代之的是某种自适应的、渐进式的开发过程。因此,很难说XP方法论中包含完整意义上的“产品设计”或“系统构架设计”工作。
相对而言,项目控制工作仍然在XP方法论中具有重要意义。只是这里更强调,程序员的身上的责任是他/她主动接受而来的,而不是强加的(accepted responsibility, not given),因此对于任务的分配、项目进度的估算都由程序员首先决策,而不是由管理者直接指派。项目管理者被称为“跟踪员(tracker)”。他/她负责监督项目进度,并通过各种衡量尺度,及时地将情况反映给开发者自身(比如提示目前的开发进度是提前还是落后于时间表)。这样的职责被形象地比喻为“镜子(mirror)”。
3
从表面上看,XP方法论似乎抵制了传统的分工体制。但是,仔细考察就能发现,这里仍保留着对“商业”、“技术”和“管理”三种职责的划分,而“客户”、“教练/顾问”和“跟踪员”身上也还存有一些我们熟悉的角色的痕迹。只不过,决策权被最大限度地交给了实际开发人员。这是一种“轻装上阵(travel light)”式的开发体制。受益于扁平的权力结构,开发者能够以最小的初期代价开始开发,并及时反馈客户意见和变更需求。
在此我乐意给XP方法论和传统分工体制的区别做一个浅显的哲学解释。柏拉图以来的一派哲学认为理念/本质(eidos)先于、而且高于实际事物。以建筑为例,抽象、初始的蓝图中蕴含了建筑物的整个存在。本质主义倾向于认为本质是静止而奥妙的,只能为少数人所领会,而把握了本质,也就穷尽了事物的一切方面和一切发展可能。由此,传统的集权式分工体制就对应于这种本质主义态度。
另一方面,不少人也认为,很多事物无本质可言,事物并非在初始、根源中就蕴含了其后的所有变数,而是一直处于偶然、不可预知的演进之中。如果一个事物渐趋完善,那也不是因为它达到了自身的本质,而是在反复尝试-修改之中,在对于外界变化的不断自适应调整之中逐步发展的结果。显然,XP方法论更接近于这种非本质主义的渐进论态度。
不同哲学态度之间的争论,似乎已经有两千年以上的历史,至今仍是教授们热衷的论文题目。在实践中,人们可能在某些场景下偏爱本质论,在其他地方则倒向渐进论。无论如何,二者都已成为我们重要的思想资源。而不同方法论之间的优劣看似比这更为显而易见。通常的论调是,随着新方法论的问世,旧方法论也失去了原来的价值。软件行业在方法论上的逐新倾向,似乎与时尚女性对衣着的关注属于同一个病理学范畴。
而以我个人所见,不同方法论的有效性,只能根据具体情形判断。XP方法论对变化的拥抱和对轻装上阵的强调固然可喜,但是,在不少场合,它的分工原则也是可疑、甚至成问题的。比如说,XP开发过程中“客户”扮演着非常重要的角色。而一旦缺乏现场客户的支持,或是客户不具备完成“素材”的能力,自适应的需求获取就很难奏效。再如,与集中决策相比,分散决策虽然能够鼓舞士气,但产品的概念完整性和技术构架的一致性都会受到威胁。一个专职的产品经理肯定会比客户、程序员的合作更能有效地设计出简洁、明确的人机交互模式。
也许,在需求不确定的场合,或是当团队中没有哪个开发者在产品设计/系统构架设计方面有足够经验时,采用XP模式开发是规避风险的最优选择。在变数较大的情形下,如果沿用传统的重量级方法论,势必大量的前期文档、设计工作在多次迭代中被抛弃,从而导致高昂的投入。但是,当业务需求清晰,团队较为成熟时,传统的分工体制不失为稳健、高效的工作模式。另外,不同的开发领域也会对分工产生不同形式的要求。游戏开发的团队构成肯定与嵌入式开发不同,这二者又都与企业应用开发相差很远。如果根据某个先验的“软件”定义,而推导出所有这些领域都共通的方法论原则,那只能是上面提到的“本质主义”幽灵对我们心智的一次最新侵袭。
就我个人熟悉的企业应用领域而言,一个优秀的领域专家/产品经理能保证较高的成功率。另外,快速原型法(而不是简单的user stories)、迭代式的发布计划(而不是一步到位)、成熟的技术框架(而不是每次都从头设计)和温和的项目管理(而不是盲目施加压力)能起到正面作用。如果允许比喻的话(就像我们在其他拙于描述的场合做的那样),我感到与写诗、谈恋爱或练气功相比,这个领域的软件开发更接近于写长篇小说、设计建筑或拍电影的过程