人月神话

《人月神话》是大学刚开始就很熟悉的一本书,当时被奉为软件工程的圣书,似乎都要在书架上摆上它才能表明软件工程学生的身份。时至今日我再读它,因为有了之前参与系统的开发的经验,很多的内容都通过记忆得到了验证,读来与大一时的“虽然不懂你在讲什么但好像很有道理” 的体会有了明显的不同。这里选择一些感触较深的章节写一些自己的理解。

入坑前,都会觉得自己战无不胜,就像陷入焦油坑的巨兽,自以为有着庞大的身躯就能在各种的地形中安然度过。在填写志愿的时候,对未来充满希望的孩子们还不知道自己将面临什么,只觉得代码的世界奇妙酷炫,然而代码对于软件系统的开发来说只是水面上的冰山。前人的智慧告诉我们如果没有认真地进行分析、设计、进度计划,真正开始开发后总会让自己陷入令人痛苦的麻烦。事实上,这种麻烦在我前期做过的绝大多数项目中都出现了,但是当你咬着牙从中脱身,还是会体验到创造与实现的快乐,通过这些经历和课程学习,我也慢慢能总结归纳经验教训,让自己今后能尽量少地陷入这样的“焦油坑”中。

人月神话

软件开发中最难掌握的莫过于过程管理,最开始的课程项目规模都很小,自己小作坊式的开发方式似乎也能很好完成要求,然而越到后来,项目规模越大,参与的人越多,开发进度的估计似乎成了一门玄学,每个人的能力不同,擅长的方面不同,开发中可能遇到的问题也不可预测,往往都是快到截止日期时集体赶工。我实习期间最深刻的印象正是来自于开发团队在每一个迭代开始前的计划方式。我们做完上一迭代的回顾后会讨论上一次的任务划分是否合理,时间分配是否过少或过多,然后根据产品经理对这一迭代的模块划分每个人独立进行开发测试的消耗估计。通过团队成员的集体商议确定模块需要的花费后,去除与上一迭代相比过多消耗的模块,结束后会写下来贴在白板上由每个人自由领取任务。这个过程是开发团队结合了长时间的经验积累和研究人员的研究成果所确定的方式,但是在执行的过程中仍然在不断探索改进以适应团队现阶段的开发能力。书中说“人月”是一个神话,是因为时间精力的消耗与独立投入的人力、时间不成线性相关,所以每一次的项目估算和调整都需要谨慎为之,落后太多的项目往往会滑向失败的深渊。

外科手术队伍

软件开发的团队选择往往是一个难题。在课程实践的过程中,大家往往渴望抱到大牛的大腿,因为经验丰富的程序员能起到以一敌十的效果,当一个团队中每个人的能力都很强那么这个队伍几乎就成了神话般的精英小队。对于大型的项目,小而美的团队往往有些力不从心,精英也不可能大量集中到一个团队中,这时外科手术团队的方式就值得借鉴。书中的对应是一名首席程序员相当于外科医生,一个经验相对较少的人员充当副手,一个管理员负责行政事务的决策,一个编辑用于生成文档,两个文秘使得文件与项目协作一致,一个程序职员用于维护技术记录,一个工具维护人员,一个测试人员,以及一个语言专家。这样的开发团队人员平等但是各司其职,保证了团队的有序运行。对于大型的项目,就需要在人员安排上使用分解的思路,由架构师负责整体设计,系统实现则由各个小团队协作完成。

贵族专制、民主政治和系统设计

一套大型的软件系统往往要持续开发运营,这就要求开发团队保持系统的概念一致性。世界需要秩序,就是因为每个人想法不一,产生矛盾时无法统一实现整体利益。在系统的开发中,人与人之间的思维差异是客观存在的,概念的完整性只能少数人员来实现,对于大型的项目,合理的团队组建方式就很重要。如同上一章所述,一个团队概念的提出需要架构师来实现,此时专制与民主的平衡就至关重要,对于设计的意见可以广泛征集,但是最后的决定却需要少数人来确定以统一整个团队的前进方向。

画蛇添足

过度设计的现象常常存在,据我的观察,这种现象往往出现于极度追求完美的人和刚刚经历过首次开发设计不足的经验教训的人。过度设计的系统在最初就引入了过多的复杂性,导致开发举步维艰,这个问题或许在一个架构师有了一定经历后就自然能够解决,但是“第二个系统”的困境出现时,我们可以有意识地约束自己做出一些舍弃。

贯彻执行

世界的规律就是一切往着混乱的方向发展,所以我们往往需要耗费很大的精力将上层的决策向基层贯彻执行。书中提出了几个方法来实现整个团队保持系统的概念完整性。首先是文档化的规格说明,文字是思想传播的载体,也正是文字和纸的出现,前人的思想才能流传至今,这足以证明文档对于维持概念完整性的重要性,文档的编写也需要形式化的定义保证概念的清晰和确定。对于软件开发这样的特殊团队,我们还可以通过建立模块间的结构来将各部分进行整合。虽然有了持久化的文字和代码,语言的交流会更有利于概念的确定,不至于在不同的人那里产生歧义,所以正式的会议和随意的交流都是必须的。书中还提出了多重实现、电话日志和产品测试的方法。

为什么巴比伦塔会失败

巴比伦塔的制造是一个神话故事,但是其中的道理却对今天人们的协作有着重要的启示。软件系统的开发完全通过计算机执行,为什么还是很少有远程协作的企业,这是因为远程协作很容易导致交流的缺失。大型的软件项目开发需要团队中的每个人能及时了解到整个团队在做些什么,这就需要经常的交流。交流的方式可以通过非正式的电话、网络,也需要正式的会议和工作手册。

提纲挈领

我们做课程作业时往往需要交大量的文档,而我们在写这些文档时就像填充八股文一样只考虑制式放弃了思考为什么要将它放在文档中。设计与决策的书面记录是必要的,但是文档存在的本意是为了沟通,我们写文档时应该考虑文档内容的现实指导意义,建立功能划分明确的文档类型和逻辑清晰的文档结构。

未雨绸缪

我们在实现功能时往往有很多思路,但是哪种思路能行得通并且最适合情况就需要我们进行试验性开发。试验性开发确实会造成精力的消耗,或许大量的测试方案最终还会被舍弃,但是我们必须这样做。实际上如果不进行方案的实验,正式的开发反而可能遭遇返工和混乱的拆补,会严重分散重新开发人员的精力和信心,甚至影响用户对产品的信任。这世界上唯一不变的就是变化本身,我们必须有未雨绸缪的能力,对未来可能产生的变化做出提前的设计,甚至对组织架构也需要进行提前的计划来规避变化造成的风险。除了开发,运营维护也需要适应变化,这就需要我们提高代码的质量和可读性,完善测试过程,保证系统在调整的过程中能够尽量少地引入更多问题。前人的智慧告诉我们,缺陷是永远存在的,我们需要通过质量管理放缓系统混乱度的提高。

干将莫邪

软件的开发离不开工具,从需求的分析,到系统的设计,到程序的编码,到构建、测试、发布和维护,我们要善于利用工具来提高我们工作的效率和质量。

整体部分

面向对象编程的“封装”思想和结构化编程的“精化”思想对于整个软件开发过程的各个粒度同样适用。整体的顺利运行离不开各个组成部分的优化。编码时各个信息隐藏的模块需要完成各自的任务,再通过接口互相配合。测试时需要从最小的单元测试开始,每一粒度都测试完全时,整个系统的运行才有保证。当系统出现问题,需要找到问题的发生点,这时就需要将问题在不同的模块和粒度上分解测试,最终找到问题的症结。

没有银弹

软件活动的根本任务是打造构成抽象软件实体的复杂概念结构。在软件实现的过程我们常常会遇到一个看起来简单的东西却严重影响了软件的质量和进度。人们希望找到一种方法能完美解决这个问题。然而,经过多年的探索,我们发现,这样的方法根本不存在,于是催生了软件工程这个学科来针对软件过程中的每个细分进行方法论的指导。在解决这个问题的过程中,人们也做了很多努力,提出了高级编程语言、面向对象编程、人工智能、专家系统、图形化系统、程序验证、工作站等方式,这些对于软件工程的发展都产生了重要的影响。

人月是一个神话,现如今软件工程却是真实地在解决软件过程中的问题,提高软件产品的质量。研究人员和实践人员的不断探索或许永远无法一劳永逸地解决所有问题,但是从中积累地经验却能够有效地指导我们更好地应对大型软件系统的实现与管理。

posted @ 2021-05-24 23:02  青竹之下  阅读(1046)  评论(0编辑  收藏  举报