THE MYTHICAL MAN-MONTH


人月神话 (not man moon hhhhh) FREDERICK P. BROOKS, JR. 翻译:Adams Wang 1975年第一版,20年后第二版。

人月神话的观点

  • 编程行业“满足我们内心深处的创造渴望和愉悦所有人的共有情感”,提供了五种乐趣:
    • 创建事物的快乐
    • 开发对其他人有用的东西的乐趣
    • 将可以活动、相互啮合的零部件组装成类似迷宫的东西,这个过程所体现出令人神魂颠倒的魅力
    • 面对不重复的任务,不间断学习的乐趣
    • 工作在如此易于驾驭的介质上的乐趣——纯粹的思维活动,其存在、移动和运转方式完全不同于实际物体
  • 同样,这个行业具有一些内在固有的苦恼:
    • 将做事方式调整到追求完美,是学习编程的最困难部分
    • 由其他人来设定目标,并且必须依靠自己无法控制的事物(特别是程序);权威不等同于责任
    • 实际情况看起来要比这一点好一些:真正的权威来自于每次任务的完成
    • 任何创造性活动都伴随着枯燥艰苦的劳动,编程也不例外
    • 人们通常期望项目在接近结束时,(bug、工作时间)能收敛得快一些,然而软件项目的情况却是越接近完成,收敛得越慢
    • 产品在即将完成时总面临着陈旧过时的威胁
  • 人月神话
    • 缺乏合理的时间进度是造成项目滞后的最主要原因,它比其他所有因素加起来影响还大。
    • 良好的烹饪需要时间,某些任务无法在不损害结果的情况下加快速度。
    • 所有的编程人员都是乐观主义者:“一切都将运作良好”。
    • 由于编程人员通过纯粹的思维活动来开发,所以我们期待在实现过程中不会碰到困难。
    • 但是,我们的构思是有缺陷的,因此总会有bug。
    • 我们围绕成本核算的估计技术,混淆了工作量和项目进展。人月是危险和带有欺骗性的神话,因为它暗示人员数量和时间是可以相互替换的。
    • 在若干人员中分解任务会引发额外的沟通工作量——培训和相互沟通。
    • 关于进度安排,我的经验是为1/3计划、1/6编码、1/4构件测试以及1/4系统测试。
    • 作为一个学科,我们缺乏数据估计。
    • 因为我们对自己的估计技术不确定,所以在管理和客户的压力下,我们常常缺乏坚持的勇气。
    • Brook法则:向进度落后的项目中增加人手,只会使进度更加落后。
    • 向软件项目中增派人手从三个方面增加了项目必要的总体工作量:任务重新分配本身和所造成的工作中断;培训新人员;额外的相互沟通。
  • 第3章外科手术队伍
    • 同样有两年经验而且在受到同样的培训的情况下,优秀的专业程序员的工作效率是较差程序员的十倍。(Sackman、Erikson和Grand)

      这较差程序员不就是说的我吗 [2019-11-03 15:08:40]

    • Sackman、Erikson和Grand的数据显示经验和实际表现之间没有相互联系。我怀疑这种现象是否普遍成立。
    • 小型、精干队伍是最好的——尽可能的少。
    • 两个人的团队,其中一个项目经理,常常是最佳的人员使用方法。[留意一下上帝对婚姻的设计。]
    • 对于真正意义上的大型系统,小型精干的队伍太慢了。?

      大型? 小型? 大型精英队伍?

    • 实际上,绝大多数大型编程系统的经验显示出,一拥而上的开发方法是高成本、速度缓慢、不充分的,开发出的产品无法进行概念上的集成。
    • 一位首席程序员、类似于外科手术队伍的团队架构提供了一种方法——既能获得由少数头脑产生的产品完整性,又能得到多位协助人员的总体生产率,还彻底地减少了沟通的工作量。
  • 贵族专制、民主政治和系统设计
    • “概念完整性是系统设计中最重要的考虑因素”。
    • “功能与理解上的复杂程度的比值才是系统设计的最终测试标准”,而不仅仅是丰富的功能。[该比值是对易用性的一种测量,由简单和复杂应用共同验证。]
    • 为了获得概念完整性,设计必须由一个人或者具有共识的小型团队来完成。
    • “对于非常大型的项目,将设计方法、体系结构方面的工作与具体实现相分离是获得概念完整性的强有力方法。”[同样适用于小型项目。]
    • “如果要得到系统概念上的完整性,那么必须控制这些概念。这实际上是一种无需任何歉意的贵族专制统治。”
    • 纪律、规则对行业是有益的。外部的体系结构规定实际上是增强,而不是限制实现小组的创造性。
    • 概念上统一的系统能更快地开发和测试。
    • 体系结构(architecture)、设计实现(implementation)、物理实现(realization)的许多工作可以并发进行。[软件和硬件设计同样可以并行。]
  • 画蛇添足
    • 尽早交流和持续沟通能使结构师有较好的成本意识,以及使开发人员获得对设计的信心,并且不会混淆各自的责任分工。
    • 结构师如何成功地影响实现:
      • 牢记是开发人员承担创造性的实现责任;结构师只能提出建议。
      • 时刻准备着为所指定的说明建议一种实现的方法,准备接受任何其他可行的方法。
      • 对上述的建议保持低调和平静。
      • 准备对所建议的改进放弃坚持。
      • 听取开发人员在体系结构上改进的建议。
    • 第二个系统是人们所设计的最危险的系统,通常的倾向是过分地进行设计。
    • OS/360是典型的画蛇添足(second-system effect)的例子。[Windows NT似乎是90年代的例子。]
    • 为功能分配一个字节和微秒的优先权值是一个很有价值的规范化方法。
  • 贯彻执行
    • 即使是大型的设计团队,设计结果也必须由一个或两个人来完成,以确保这些决定是一致的。
  • 其他
    • 团队应该以尽可能多的方式进行相互之间的交流:非正式、常规项目会议,会上进行简要的技术陈述、共享的正式项目工作手册
    • 更普遍的是,战略上突破常来自于数据或表的重新表达。数据的表现形式是编程的根本。
    • 编程需要技术积累,每个项目需要自己的标准组件库。

      自己的代码也需要组织成库

    • 缺陷修复总会以(20-50)%的机率引入新的bug。
    • “项目是怎样延迟了整整一年的时间?⋯一次一天。”
    • 一天一天的进度落后比起重大灾难,更难以识别、更不容易防范和更加难以弥补。
    • 如果里程碑定义得非常明确,以致于无法自欺欺人时,程序员很少会就里程碑的进展弄虚作假。
    • 进取对于杰出的软件开发团队,同优秀的棒球队伍一样,是不可缺少的必要品德。
    • 流程图是被吹捧得最过分的一种程序文档。详细逐一记录的流程图是一件令人生厌的事情,而且高级语言的出现使它显得陈旧过时。流程图是图形化的高级语言。
    • 为了使文档易于维护,将它们合并至源程序是至关重要的,而不是作为独立文档进行保存。
    • 只能根据过去判断将来。 帕特里克·亨利
    • 然而永远无法根据过去规划将来。 埃德蒙·伯克
    • 对于编程产品而言,这样的中间步骤是同样必要的,但是软件工程师在着手发布产品之前,却并不会常规地进行试验性系统的现场测试。[现在,这已经成为了一项普遍的实践,beta版本。它不同于有限功能的原型,alpha版本,后者同样是我所倡导的实践。]
    • 前进一步,后退一步——系统熵随时间增加。所有修改都倾向于破坏系统的架构,增加了系统的混乱程度。即使是最熟练的软件维护工作,也只是放缓了系统退化到不可修复混乱的进程,从中必须要重新进行设计。[许多程序升级的真正需要,如性能等,尤其会冲击它的内部结构边界。原有边界引发的不足常常在日后才会出现。]
    • 系统调试(相对于单元测试)花费的时间会比预料的更长。
    • 即使对于完全开发给自己使用的程序,描述性文字也是必须的,因为它们会被用户-作者所遗忘。