《人月神话》读书笔记

到底什么是软件开发?

程序员,他们总会有另外一种头衔,软件工程师、高级工程师、架构师诸如此类。在软件开发中,程序员自己也喜欢用一些术语:模块、中间件、封装、框架结构等等。听起来是不是很像在搞建筑,没错,连程序员自己也乐于自嘲“搬砖”,久而久之,这些头衔和术语就会给外行一种感觉:“软件开发就是一种建设工程”。于是,当某个单位需要某种大型软件来支撑业务的时候,我们就把这场软件开发称之为:“信息化建设”。

这是罪孽的源头!我们正在把真实的建筑项目管理的思想灌输到软件研发中。

人月——完成一个人物所需的人力和时间,这是建筑工程惯用的思维模式。10个人盖一栋房子需要10个月,那好,把工人增加到100个三班倒,项目周期就可以压缩到1、2个月。不过很可惜,人月在软件项目中,只是一种神话

软件工程是一次协同创造,而非共同组装。它更像是拍一部电影、写一部小说、编一首曲子、画一幅壁画。你什么时候听过后者会用“工程”来描述自己所做的事情,他们更多会谈:灵感、节奏、创意等。而软件开发和它们稍微不同的地方在于,它总会有几个到上千个程序员负责开发——他们都是创造者,就好像一部电影有多个导演,一部小说由多人执笔……

大型软件开发就像陷入焦油坑的巨兽,永远抓不住重点。当需求变化时、当交付期临近时、当技术攻关受阻时,我们会想当然地认为原因是人手不足。于是工程思维登场了,时间、目标、成本、人力资源,通过科学估算后开始增派人手,希望在可控的时间成本下完成预期目标。

然而我们忽略了一个问题——项目复杂度。抱歉,程序员是项目复杂度的原因之一。如果是工地搬砖,那么人数和工作效率是成正比的。如果是编程呢?新加入的程序员需要熟悉业务、项目培训,由于个体差异,还会制造新bug。所以,当软件项目增加人手时,管理成本、沟通成本就会成指数上升,项目复杂度也会疯狂增长。好的情况下,项目进度会得到一点点改善,坏的情况下,不仅项目延期,整个团队都会陷入混乱。

不要用人月去规划软件工程的子任务,我们习惯于把软件研发的绝大部分事情划归给“编程”,然而作者的观点是:1/3计划、1/6编码、1/4构件测试、1/4系统测试。是的,编码只占少得可怜的计划时间,为何呢?

所谓集成,不是用胶水将模块粘到一起

软件开发中的模块化思想,是为将业务拆解,高内聚低耦合,从表面上看还有个好处:可以把不同的模块划分给不同的人或团队去开发。不同的业务模块并行开发,项目效率不就提高了吗?

我记得在读《Just for Fun》的时候,Linus点评过苹果OSX系统的“微内核”架构的,非常值得玩味。Linux的确是宏内核架构,它给人的感觉是大而全很笨重,所以有人会想到“把一个整体切成多个小块,等同于把一个大的困难切分成很多小困难”,一次性解决大的困难很棘手,拆分成很多小困难就容易多了。于是就有了模块化思想的微内核。Linus并没有说这种思想不好,而是提出了新视角。模块化思想就好比人的大脑,不同区域负责不同功能——但有没有考虑过各个功能模块之间存在联系

是的,设想一下,一部小说分为20章节,不同章节由不同的作家同时编写;一部电影被拆分成多个场景,不同场景由不同导演完成;一幅人像油画分为头/手/脚/身,由不同画家绘制。最后的最后,再把拆分的东西在合到一起。原本一个人需要一年完成的事情,现在10个人并行创造,一个月就搞定了。但是!你觉得这样的作品能看么?

没错,大型软件的矛盾就在于,它犹如给万里长城画壁画、拍10000小时的纪录片,写一千万字的小说,最后还要给人一气呵成的感觉。但想想都知道,一个人要完成如此巨著,要多长时间?市场能等吗?我们只能无奈地将其拆成模块,增加人手,东拼西凑,满身bug。

回看软件项目本身,作者是给出了自己的一些建议:

概念的完整性

还是以绘画为例,画家在下笔之前,脑子里是存在一幅模糊但完整的作品的,由于整个作品都是它自己完成,所以它可以按照自己的节奏和把握作画。

软件产品最初同样是存在少数几个人脑中,最有可能是产品经理或项目经理,但是实际开发软件的人未必是他,而是占大多数的程序员。那么问题来了,作为真正打磨作品的匠人,脑子里却没有一幅完整的画面,只是负责领导分配的某个局部,甚至连自己到底要做什么都不知道。这种项目大概率要偏离航道。

尽管很多软件项目负责人亲自编程,但作者还是建议,负责人应该是系统设计和架构师的角色,你自己必须非常清楚软件最终的样子,并使尽浑身解数灌输的团队每个人的脑子里。当遇到技术困难时,你应该提出你的建议,也仅止于建议,否则团队会觉得你瞎指挥,你自己也会累半死。

外科手术式队伍

这是很美妙的比喻!软件项目的团队应该像外科手术团队,而非建筑施工队。每个人在自己的专业领域,针对某个职能,从头负责到底。团队一般二三十人,必须有一个主刀人,还需要一个副手,不仅有程序员,还有项目助理、行政、文档管理等。

这是为了让架构师双手才能从细节中挣脱,严格把控项目的方向和节奏。研发手册、文档、会议记录等资料才能及时跟进,小团队的沟通和执行效率会更高。当整个团队都清楚自己的努力方向时,项目才是前进的。

贯彻执行!沟通!沟通!

进度滞后不是一天造成的,而是不知不觉的积累。软件研发有这样一种现象,领导不懂技术或者无法掌控细节,团队里的人就会找各种理由来掩饰自己的工作情况,表面上看都是一帆风顺,到项目后期却一再延期。

作者的建议是两个,要么随时通过会议、里程碑、沟通的方式,随时掌握最新动态;要么一下子掀开地毯,你会发现底下全是蟑螂(bug)。

即便在项目进展看似不错的情况下,也务必注意沟通。沟通效率低下的团队,项目失败的风险太大。所以,一是注意给团队营造良好的沟通氛围,二是沟通渠道通畅。此外务必记住,每增加一个人,团队的沟通成本也会增加。

交付体验,而不仅仅是产品

软件功能很重要,软件的使用体验也同样重要!多亏了苹果,让我们明白什么是体验,但真没想道本书40年前就洞见了这一点。

关于软件项目的管理,书中还介绍了很多工具和方法,有的现在已经很普及——比如自动化测试、高级语言;有的是杞人忧天——比如软件会把硬盘占满。

好软件是长出来的

传统工程思维难以在软件项目中实践,开发是一种创造,像生命的孕育,必须“十月怀胎”,那就站在生命的角度,思考一下新的软件开发模式。

增量开发

其实这种概念和后来的敏捷开发大同小异。废除瀑布模型,快速做出产品原型,然后交付——反馈——开发——交付——反馈,如此重复,渐进增长,直至达到预期。这就好比从受精卵到成人的过程,总是先有核心,然后在逐渐延伸出来。软件领域这么做,可以提早发现bug和新的需求,并及时跟进市场。

关于“没有银弹”

困扰软件行业的一大问题就是如何提升生产效率,就好像客户需要盖一栋房子,找建设单位,有了设计图纸,房子就能盖起来。可软件工程总是一再延期,总在维护。有没有什么方式,能从根本上提升软件项目的开发效率,作者的答案是没有。

作者一再强调,“根本”和“次要”问题。我的理解:根本问题是如何让软件开发效率翻几十倍,几个程序员可以在几个月就完成超大型软件项目;次要问题是,通过什么技术,能够提高编写代码的速度和质量。

用40年前的眼光来看,人工智能、面向对象、图形界面都是非常有潜力的技术。面向对象主要能实现软件的复用能力,就好像把软件做成各种零件,然后售卖给加工厂;而人工智能是为了尽量减少编写代码,减少bug,专家级程序员或架构师可以更高效看到结果。

毫无疑问,面向对象或集成开发环境等工具的使用,的确提升了现在程序员的效率,但项目管理依然失控,开发进度依然滞后。所以,这些工具其实解决的次要问题。我基本同意作者的观点——没有银弹。

《人月神话》书评

《人月神话》应该是我还在上大学的时候就听说的,工作多年后终于有幸拜读。坦白说,还好是现在的我读了此书——如果是学生时代的我读了的话,要么认为这是一本垃圾,要么跟风说它是传世之作。

本书总体有些晦涩,一是偏管理学术,二是年代久远、三是翻译确实不太好。比如我第一次看到“结构师”的时候一脸懵逼——以前的程序员还要负责制图么?然后我看到了architect,好吧。书中在讨论很多项目或产品研发时,把重点放在了该用高级语言还是汇编,该为用户保留多少内存空间,该不该搭建测试服务器等等。毫无疑问,这些问题在今天根本不值一提,然而40年前呢?那个内存按K来计算,CPU慢成狗,还没有图形界面,计算机还死贵死贵的年代,这些确实是问题。

作者用40年前的眼光思考了未来的软件开发模式,看看现在的大型软件开发管理,DDD/TDD、持续集成、持续部署、持续交付。不得不说,《人月神话》里外科手术队伍、系统测试、增量开发、交付体验等观点,确实在今天被一一验证了,也许这也是它越来越经典的原因吧。

这几年的程序员经历,让我对研发项目有切身的体会,在读此书的时候才有很多共鸣。

0%