抽空把《人月神话》复习了一遍,回顾自己近期的工作,想对书中的一些观点谈谈自己的感受。
-
编程行业“满足我们内心深处的创造渴望和愉悦所有人的共有情感”,其提供了五种乐趣:
- 创建事物的快乐;
- 开发对其他人有用的东西的乐趣;
- 将可以活动、相互啮合的零部件组装成类似迷宫的东西,这个过程所体现出令人神魂颠倒的魅力;
- 面对不重复的任务,不断学习的乐趣
- 工作在如此易于驾驭的介质上的乐趣——纯粹的思维活动——其存在、移动和运转方式完全不同于实际物体
最近公司接了一个活,目标是把一个windows上的软件产品做成跨平台的,也就是windows和mac。雇主那边写了一个类似于WPF的框架,目前需要我们把原来用MFC写的界面换成用他们的框架写成的界面。写了2天之后我发现这个工作大部分是体力活。首先你需要把原来的界面用他们的框架画好,就跟写WPF界面差不多。然后把原来界面中的逻辑重新实现一下。因为没有文档,全靠参照前期领导写的代码和问同事,所以写得比较累。继续写了几天以后,感觉这个东西没有给我带来任何成就感。我觉得我成了流水线上的工人,原来编程带给我乐趣都不存在了,有的只是重复和被push的压力。原来觉得编程是一种脑力劳动,现在发现在你掌握了一定的技术基础之后,有些事情就变成了体力劳动。对于这种工作,我的态度是按时上班,按时下班,不付出额外的劳动。因为我觉得这个工作不值得我付出哪怕多一点的精力。它对程序员而言是一种痛苦。加班加点地做这种痛苦的事只会使自己逐渐丧失对编程的乐趣。所以我一直在自学一些觉得有意思的东西,始终让自己保持对编程的新鲜感。我知道我还要写几十年的程序,保持兴趣才能让我不断进步。
-
所有的编程人员都是乐观主义者,“一切都将动作良好”。
这个是我感受最深的一点。从我非常有限的编程实践中,我发现从project manager到一线程序员,普遍都对进度做了过于乐观的估计。书中提到了几个点说明为什么进度常常不是按照我们估计得那样进行。- 由于编程人员通过纯粹的思维活动来开发,我们期待在实现过程中不会碰到困难。但是我们的构思本身是有缺陷的,因此总会有bug.
- 围绕着成本核算的估计技术,混淆了工作量和项目进度。人月是危险和带有欺骗性的神话,因为它暗示人员数量和时间是可以相互替换的。
- 在若干人员中分解任务会引发额外的沟通工作量——培训和相互沟通。
做乐观的进度估计很多时候来自于客户或者雇主的压力。项目经理会受到来自于客户的压力,一线开发者又会受到同事和项目经理的压力。然而实际完成的时间并不会由于估计的时间少就会早完成。从实际来看,我完成的时间一般都是领导估计时间的3倍左右。我觉得我领导估计时间更多地考虑了代码变动所花的时间,而忽视了其它活动所花的时间。因此实际完成时间和预估时间相差比较大。
-
目标上(和开发策略上)的一些正常变化无可避免,事先为它们做准备总比假设它们不会出现好的多。
程序员都希望需求是一成不变的,可是实际项目的需求往往一变再变。来公司3个月的时候,领导给了我一个小需求。要求在原来的界面上加几个控件,本来位置和个数写死就行了,后来变成了控件类型和数量都可以动态变化,控件位置也要动态改变。我原来实现的时候,只用了一层抽象去实现,这样实现起来可以满足需求,但可能很难应对变化。领导建议我把控件分组,增加一层抽象。后来雇主又要求控件布局也要动态变化,我才想到领导的先见之明。提前想想可能出现的需求变化,在前期适当增加一些抽象,往往可以更容易应对以后的需求变化。当然这个其实要求你对业务比较熟悉,能够对可能的需求变化做一些预测。后来我想写出好的软件除了需要精通各种技术之外,还需要熟悉业务,不熟悉业务很难做出有价值的决策。 -
缺陷修复总会以20%~50%的几率引入新的bug.
在不断的改bug过程中,我越来越觉得这是真理。因为改bug需要你先理解原有的逻辑,对于老项目而言,特别是没有文档的老项目,理解它一个模块的各个逻辑是比较费力的。有时候你觉得你理解了它原有的逻辑,但你可能忽略了其中一个case,于是你的这次改动就引入了新的bug. 很多时候也是由于面前工期的压力,你没有时间完全理解原有的逻辑,只想快点解决这个比较严重的bug。这些都是导致新bug的原因。 -
即使是完全开发给自己使用的程序,描述性文字也是必须的,因为它们会被用户——作者遗忘
这条说的是文档的重要性。就我现在做的项目而言,是美国的外包项目。美国那边很重视文档,一开始就把详细的需求说明书(或者叫规格说明书)写好,并在以后根据情况随时更新。这样开发做起来就完全清楚要做什么功能,把功能具体做成什么样。原来待过一个月的A公司,经常是领导口头交待任务,具体做成什么样领导自己也不清楚,靠自己去问其他人,没有任何规范。我很难想像它这个项目能维护下去。现在做的这个项目已经有20多年的历史了,仍然能够维护下去,我觉得文档是很重要的一点。有什么问题,先看看原来的文档是怎么定义功能的,这样很多东西都有据可查。另外一点,代码中的注释也是极重要的,特别是针对特定case所写的代码,一定要写上注释,否则后面维护的人可能就倒霉了。在这一点上,我觉得我的领导给我做了很好的示范。通过他的code review,我逐渐明白了何时注释以及怎样写好的注释。 -
在未来的十年内,无论是在技术还是管理方法上,都看不出有任何突破性的进步,能够保证在十年内大幅度地提高软件的生产率、可靠性和简洁性。
这是Brooks博士最重要的论点。他认为软件开发中最主要的困难是规格说明、设计和测试这些概念上的结构,而不是对概念进行表达和对实现逼真程度进行验证。软件开发中有一些无法避免的内在特性:复杂度、一致性、可变性和不可见性。正是这些内在特性导致了软件开发的生产率不会得到大幅度的提高。在他论文发表后的几十年时间里,软件开发领域出现了很多新的语言、工具、程序库,但这些只解决了软件开发中的一部分次要困难。
不过,Brooks博士也提出了一些解决主要困难的方法。其中一个是需求精炼和快速原型。需求精炼是说,必须与客户进行深入的沟通,明确化客户需求中模糊的部分。但即使这样客户还是会有很多地方无法精确表达自己的需求,而改变传统的软件开发流程可能对解决这个问题有很大帮助,即快速原型。首先系统应该能够运行,即使未完成任何有用功能,只能正确调用一系列伪子系统。接着,系统一点一点被充实,子系统被轮流开发,或者在更低的层次调用程序、模块、子系统的占位符。这种方法要求自上而下的设计,因为它本身是一种自上而下增长的软件。
读完这个论点,我还是有点云里雾里的。可能是经验太少,做的只是一小块,所以感触也不多。
最后,想用书中的一段评论来结尾,送给国内的开发者:
现实世界中的管理就是在更大程度上以人员的生命为代价,让他们更努力、更长时间的工作。经理们总是不停地吹嘘他们的人员的加班时数和能从这些人身上榨取更多时间的小把戏。这种情况下,开发产品的质量一定会下降,甚至惨不忍睹,因为开发人员唯一能控制的是质量,当他们不得不牺牲质量,痛苦地面对自己的工作,践踏工作的乐趣时,可以想像项目成本会大大增加,并且项目的发布往往伴随着一大批程序员的倒下。… Read the rest