人月神话

一、 焦油坑
1、焦油坑的意思说明了即使你足够强大,也无法摆脱束搏而沉到坑底。IT项目也是这样,不论是开发大型软件系统
 还是小型项目,都会遇到诸多复杂的问题和影响因素,项目本身就是一个足够复杂的动态系统,没有最优,只有满意。


2、项目四要素,人员,组织环境,干系人,外部依赖和约束,风险和假设,团队,人等诸多问题都是你必须要考虑的问题,任何一个要素出现大的差错都可能导致项目失败,只有所有要素能够平衡好,团队能够协调一致才能够保证项目成功。


3、类似帕金森定律中的金字塔上升想象,每个人都很忙但组织效率确越来越低,每个人都在往上走,导致在每个岗位角
  色上都难得到技能过关高效率的人员。IT项目管理者需要致力于改善这些苦恼,这里面一方面是绩效机制的改善,
  一方面是适当的过程保证。项目管理者带领项目取得成功不仅仅是体现了自我价值,也让团队每个团队成员意识到
  他们存在的价值和贡献的力量。


4、编程系统产品(Programming Systems Product)开发的工作量是供个人使用的、独立开发的构件程序的九倍。
  我估计软件构件产品化引起了3倍工作量,将软件构件整合成完整系统所需要的设计、集成和测试又强加了3倍的
  工作量,这些高成本的构件在根本上是相互独立的。


二、人月神话
1、向进度落后的项目中增加人手,只会使进度更加落后。(Brooks法则)


2、关于进度安排,我的经验是为1/3计划、1/6编码、1/4构件测试以及1/4系统测试。


3、当任务由于次序上的限制不能分解时,人手的添加对进度没有帮助。无论多少个母亲,孕育一个生命都需要十个月。
  由于调试、测试的次序特性,许多软件都具有这种特征。


4、在众多软件项目中,缺乏合理的时间进度是造成项目滞后的最主要原因,它比其他所有因素加起来的影响还大。
  导致这种普遍性灾难主要原因是:
  (1)我们对估算技术缺乏有效的研究。
  (2)我们采用的估算技术隐含地假设人和月可以互换,错误地将进度与工作量相互混淆。
  (3)由于对自己的估算缺乏信心,软件经理通常不会有耐心持续地进行估算这项工作。
  (4)对进度缺少跟踪和监督。其他工程领域中,经过验证的跟踪技术和常规监督程序,在软件工程中常常被认为
    是无谓的举动。
  (5)当意识到进度的偏移时,下意识(以及传统)的反应是增加人力。这就像使用汽油灭火一样,只会使事情更糟。
  越来越大的火势需要更多的汽油,从而进入了一场注定会导致灾难的循环。


5、当进度出现严重问题时候最有效的方法仍然是消减任务,与其交付10个不可用的功能点,还不如交付5个优先级
  高的功能点。其二进度落后的时候,盲目的加班往往是无济于事的。按照时间管理的方法论,你越忙的时候你越该
  停止下来,好好的反省究竟慢在哪里,瓶颈和根源究竟在哪里,只有当问题的根源真正被挖掘出来和解决后,
  才可能真正提高效率和加速度。


6、对于进度落后的问题根源,我们可以做如下考虑。
  (1)需求本身频繁变动而且不受控,开发频繁的修改和返工,全是无效工作量。
  (2)开发人员技能本身问题,或者是开发效率低,或者是对业务需求理解不深。
  (3)开发人员自身的态度和责任感,是否有一种能够刺激他们潜在创造激情的氛围。
  (4)没有一个安静专注的环境,经常被各种无意见的会议,电话和琐事打断。


三、外科手术队伍
 1、外科手术队伍

2、团队的扩建

3、同样有两年经验而且在受到同样的培训的情况下,优秀的专业程序员的工作效率是较差程序员的十倍。


4、一位首席程序员、类似于外科手术队伍的团队架构提供了一种方法——既能获得由少数头脑产生的产品完整性,
  又能得到多位协助人员的总体生产率,还彻底地减少了沟通的工作量。


四、贵族专制、民主政治和系统设计
1、概念完整性是系统设计中最重要的考虑因素,为了获得概念完整性,设计必须由一个人或者具有共识的小型团队
  来完成。这实际上是一种无需任何歉意的贵族专制统治。


2、对于非常大型的项目,将设计方法、体系结构方面的工作与具体实现相分离是获得概念完整性的强有力方法。
  [同样适用于小型项目]


3、不论你软件项目规模的大小,不论你采取的软件生命周期方法论,我们都不要忽视了总体架构设计这个过程,
  而总体设计的一个重点就是概念完整性。概念完整性是系统设计首要考虑的内容,为了反映一系列连贯的设计思路,
  宁可省略一些不规则的特性和改进,也不提倡独立和无法整合的系统,哪怕它们其实包含着许多很好的设计。


4、总体架构设计的重点就是理清楚整个系统的骨架和体系结构,架构设计是从实际的需求到抽象的实现之间
  重要的衔接。体系结构描述的是发生了什么,而实现描述的是如何实现。


5、贵族专制和民主政治并不是否定民主和大家共同的智慧的力量,而是最终的合并和统一决策全力要高度统一,
  团队成员有的创意和意见仍然可以积极的反馈。但是系统架构师必须要注意到,他是为整个系统负责,而不是对
  系统的某个独立的功能模块负责,我们需要的不是头脑发达却四肢不健全的人,这是让大家无法满意的。
  因此不能和系统的基本概念进行整合的想法和创意,都必须暂时放在一边。


五、画蛇添足
1、画蛇添足就是过分设计,过分设计往往出现在设计和开发第二个系统的时候,对于第一个系统他们小心谨慎,
  倾向于精炼和简洁,但是到了第二个系统他们太想去追求完美,又加上盲目的自信,再加上没有太多的成本和进度
  等意识,导致了画蛇添足和过分设计。


2、结构师如何避免画蛇添足,如何成功地影响实现:
  (1)牢记是开发人员承担创造性的实现责任;结构师只能提出建议。
  (2) 时刻准备着为所指定的说明建议一种实现的方法,准备接受任何其他可行的方法。
  (3)对上述的建议保持低调和平静。
  (4)准备对所建议的改进放弃坚持。
  (5)听取开发人员在体系结构上改进的建议。


3、在我们常见的软件开发中,类似画蛇添足和过分设计的例子有:
  (1)完全根据自己主观思维,花哨的界面和不适用的功能。
  (2)过分和过度的考虑系统的可扩展性而成倍加大系统复杂度。
  (3)没有项目目标意识,追求完美的系统,但是去无法达到项目预期的进度和成本目标。
  (4)没有迭代和渐进的思路,老想一次就尽善尽美,结果往往确实难产。
  (5)自我欣赏和盲目自信,完全沉醉到技术的乐趣而忘记了产品创造价值本身。


六、贯彻执行
1、贯彻执行和提供执行力首先要要考虑纪律,在《专业主义》里面提到过,要想成为专家,有一个重点就是具有
  永不厌倦的好奇心和进取心,严格遵守纪律。有了纪律仅仅是有了执行的基础,但是我们看到往往就是有纪律无执行,
  有规程不实践的情况,因此个人任务目标愿景+纪律+团队=贯彻执行力。只有这三方面都是具备了才可能有很好的
  执行能力,有了执行力再加上经验总结和反馈才能带来持续的改进。仅有纪律无执行是僵化的流程,仅有执行无纪律
  是散兵游勇无法铸造高战斗力的团队。


2、即使是大型的设计团队,设计结果也必须由一个或两个人来完成,以确保这些决定是一致的。


3、会议,永无休止的低效会议浪费了我们太多的时间。但是会议仍然是必要的贯彻执行各种战略、目标和任务的
  重要沟通场所。我们始终要意识到会议的目的就是要对目标达成共识并解决时间的问题,否则可能都会造成
  低效的会议,会议的时间不在于长短而在于切实解决问题。在软件项目团队中最重要的就是团队正式的周例会
  以及里程碑会议,在敏捷软件开发团队中我们更加强调每天10到20分钟的站立会议。


4、会议的卓有成效是由于:
  (1)每周交流一次,大家对项目相关的内容比较了解,不需要安排额外时间对人员进行培训。
  (2)上述小组十分睿智和敏锐,深刻理解所面对的问题,并且与产品密切相关。
  (3)没有人是“顾问”的角色,每个人都要承担义务。
  (4)当问题出现时,在界线的内部和外部同时寻求解决方案。
  (5)正式的书面建议集中了注意力,强制了决策的制订,避免了会议草稿纪要方式的不一致。
  (6)清晰地授予首席结构师决策的权力,避免了妥协和拖延。


5、项目经理最好的朋友就是他每天要面对的敌人——独立的产品测试机构/小组。该小组根据规格说明检查机器
  和程序,充当麻烦的代言人,查明每一个可能的缺陷和相互矛盾的地方。每个开发机构都需要这样一个独立的
  技术监督部门,来保证其公正性。


七、为什么巴比伦塔会失败
1、据《创世纪》记载,巴比伦塔是人类继诺亚方舟之后的第二大工程壮举,但巴比伦塔同时也是第一个彻底失败的
  工程。巴比伦塔项目的失败是因为缺乏交流,以及交流的结果——组织。


2、因为左手不知道右手在做什么,从而进度灾难、功能的不合理和系统缺陷纷纷出现。由于对其他人的各种假设,
  团队成员之间的理解开始出现偏差。


3、沟通是整个项目团队的核心要素,关于项目的共同愿景,目标,进度任务,问题,风险,思想等都需要通过沟通
  来传达。有效的团队沟通是提升团队竞争力必不可少的要素,项目经理有90%的时间都花费在沟通上面,有了沟通
  就有了共同的愿景和协作氛围,就有了思想的交换和碰撞。

4、团队应该以尽可能多的方式进行相互之间的交流:非正式、常规项目会议,会上进行简要的技术陈述、
 共享的正式项目工作手册以及电子邮件。
 
5、树状编程队伍存在三种可能的关系,在实践中都得到了很好的应用:
  (1)产品负责人和技术主管是同一个人。这种方式非常容易应用在很小型的队伍中,可能是三个或六个开发人员。
    在大型的项目中则不容易得到应用。原因有两个:第一,同时具有管理技能和技术技能的人很难找到。
    第二,大型项目中,每个角色都必须全职工作。
  (2)产品负责人作为总指挥,技术主管充当其左右手。这种方法有一些困难。很难在技术主管不参与任何管理
    工作的同时,建立在技术决策上的权威。
  (3)技术主管作为总指挥,产品负责人充当其左右手。这种安排对小型的团队是最好的选择。而对于真正
   大型项目中的一些开发队伍,产品负责人作为管理者是更合适的安排。

八、胸有成竹
1、仅仅通过对编码部分的估计,然后乘以任务其他部分的相对系数,是无法得出对整项工作的精确估计的。
  程序开发呈程序规模的指数增长。
 
2、实践是最好的老师,但是,如果不能从中学习,再多的实践也没有用。

3、最早用的估算方法是建立需求->设计->编码->测试各个阶段工作量之间的比例关系,然后根据需求的工作量
  来推导其它各个阶段的工作量或者是根据编码工作量来反推上游各个阶段的工作量。这种方式在项目规模比较
  稳定的小型项目中是比较适用的,但是它不能简单的类别应用到大型软件项目,因为随着项目规模的扩大,
  规模和工作量之间已经不是简单的线性关系了。

九、削足适履
1、软件开发人员必须设立规模目标,控制规模,发明一些减少规模的方法——就如同硬件开发人员为减少元器件
  所做的一样。


2、在大型的团队中,各个小组倾向于不断地局部优化,以满足自己的目标,而较少考虑团队用户的整体影响。
  这种方向性的问题是大型项目的主要危险。


3、培养开发人员从系统整体出发、面向用户的态度是软件编程管理人员最重要的职能。


4、编程需要技术积累,每个项目需要自己的标准组件库。


5、软件产品的规模应该从顶向下进行预算,分解到各个子系统和模块。这是一种从系统整体出发的统筹思路,
  这样分解到每个开发人员后他们都必须要考虑如何达到期望的规模目标,尽量同程序设计,算法等各个方面
  去优化程序规模。


6、在规模控制的技能上常用的有两种方法:一种是通过提供功能点的多少来换取空间,一种是通过牺牲性能
  和时间来换取空间。而如何做好空间和时间上的折衷?一方面是要加强培训提高开发人员的编程技能水平
  (核心的可能是数据结构和算法),另一方面是要进行长期的技术积累,提倡复用和开发更多的公共构件。


十、提纲挈领
1、对于软件项目,关键文档是:
  (1)目标:定义待满足的目标和需要,定义迫切需要的资源、约束和优先级。
  (2)技术说明:计算机手册和性能规格说明。它是在计划新产品时第一个产生,并且最后完成的文档。
  (3)内部文档、
  (4)进度、
  (5)预算:预算不仅仅是约束。预算的存在会迫使技术决策的制订,否则,技术决策很容易被忽略。更重要的是,
    它促使和澄清了策略上的一些决定。
  (6)组织机构图
  (7)工作空间分配。


2、项目经理的基本职责是使每个人都向着相同的方向前进。项目经理的主要日常工作是沟通,而不是做出决定;
  文档使各项计划和决策在整个团队范围内得到交流。


3、为什么要有正式的文档?
  (1)书面记录决策是必要的。只有记录下来,分歧才会明朗,矛盾才会突出。
  (2)文档能够作为同其他人的沟通渠道。
  (3)项目经理的文档可以作为数据基础和检查列表。通过周期性的回顾,他能清楚项目所处的状态,以及哪些
    需要重点进行更改和调整。


十一、未雨绸缪
1、不变只是愿望,变化才是永恒。


2、普遍的做法是,选择一种方法,试试看;如果失败了,没关系,再试试别的。不管怎么样,重要的是先去尝试。

3、软件产品易于掌握的特性和不可见性,导致了它的构建人员面临着永恒的需求变更。为变更计划系统,它们
  包括细致的模块化、可扩展的函数、精确完整的模块间接口设计、完备的文档。另外,还可能会采用包括调用队列
  和表驱动的一些技术。

4、只要管理人员和技术人才的天赋允许,老板必须对他们的能力培养给予极大的关注,使管理人员和技术人才
  具有互换性;特别是希望能在技术和管理角色之间自由地分配人手的时候。


5、开发人员交付的是用户满意程度,而不仅仅是实际的产品。用户的实际需要和用户感觉会随着程序的构建、
  测试和使用而变化。

6、对于大多数项目,第一个开发的系统并不合用。它可能太慢、太大,而且难以使用,或者三者兼而有之。
  要解决所有的问题,除了重新开始以外,没有其他的办法——即开发一个更灵巧或者更好的系统。系统的丢弃和
  重新设计可以一步完成,也可以一块块地实现。所有大型系统的经验都显示,这是必须完成的步骤。


7、对于应用程序,维护总成本通常是开发成本的40%或更多。程序维护中的一个基本问题是——缺陷修复总
  会以(20-50)%的机率引入新的bug。所以整个过程是前进两步,后退一步。


十二、干将莫邪
1、巧匠因为他的工具而出名。工欲善其事,必先利其器。


2、项目经理应该制订一套策略,以及为通用工具的开发分配资源,与此同时,他还必须意识到专业工具的需求。


3、项目的关键问题是沟通,个性化的工具妨碍——而不是促进沟通。其次,当机器和语言发生变化时,技术也会
  随之变化,所有工具的生命周期是很短的。毫无疑问,开发和维护公共的通用编程工具的效率更高。


4、在软件项目团队中涉及到计划,沟通和变更的往往是一些通用的整个团队都必须要使用的工具。但是随着团队的
  专业化分工,还有涉及到各个岗位&角色的专业化工具,比如开发编程人员需要属性各种IDE开发环境,系统分析员
  需要熟悉UML建模工具,测试人员需要熟悉相应的测试工具等。因此项目经理在项目计划阶段必须要考虑到在整个
  软件生命周期的过程管理,产品开发,质量管理等各个环节需要用的各种工具。


5、软件开发生命周期阶段的一些工具技术:
  (1)需求阶段工具。需求阶段主要分为需求收集,需求开发和需求管理三个方面的内容。需求收集主要是如何捕获
    和描述清楚用户需求,可以用Excel来完成需求的收集;需求开发对于面向对象一般采用使用ROSE工具采用UML
    用例建模的方式进行,用例建模一般又分为用例建模,行为建模和界面建模三个层次的内容。需求管理一般采用
    RP工具进行需求的追踪,采用CQ等工具进行需求变更的控制。
  (2)设计开发阶段工具。设计开发阶段工具主要是前台应用和架构的设计以及后台数据库的设计。数据库设计一般
    采用PowerDesigner或ERWin进行数据库的建模,采用Rose,Together或XDE等工具进行架构和功能模块
    的设计。采用相关高效的IDE环境进行编码,或者引入一些第三方的组件或应用程序开发框架提高开发效率。
    同时项目也可以使用Nunit,Nant,NLog等开源项目借鉴其相关的架构和模式。
(3)测试工具。对于测试管理一般可以用TestManager进行,对于性能测试一般采用LoadRunner或WinRunner,
  WAS等进行。而对于系统测试一定要注意边界和异常条件的测试,相关业务流程分支的分析和覆盖。开发人员可以
  用Nunit进行单元测试,可以采用PureCoverage检验自己的测试代码覆盖率情况。
(4)辅助工具。项目还要配置管理,变更管理,知识库,即时通讯,MindManager,CMMI过程控制和管理等相关
  工具进行辅助。保证流程的规范性和可控性。


十三、整体部分
1、好的自顶向下设计从几个方面避免了bug。
  (1)清晰的结构和表达方式更容易对需求和模块功能进行精确的描述。
  (2)模块分割和模块独立性避免了系统级的bug。
  (3)细节的隐藏使结构上的缺陷更加容易识别。
  (4)设计在每个精化步骤的层次上是可以测试的,测试可以尽早开始,并且每个步骤的重点可以放在合适的级别上。


2、许许多多的失败完全源于那些产品未精确定义的地方。这要求我们在需求和设计阶段要保持高质量,减少缺陷泄漏。


十四、祸起萧墙
1、带来坏消息的人不受欢迎。当人们听到某个项目的进度发生了灾难性偏离时,可能会认为项目一定是遭受了一
  系列重大灾难。然而,通常灾祸来自白蚁的肆虐,而不是龙卷风的侵袭。一天一天的进度落后比起重大灾难,
  更难以识别、更不容易防范和更加难以弥补。


2、根据一个严格的进度表来控制项目的第一个步骤是制订进度表,进度表由里程碑和日期组成。里程碑必须是
  具体的、特定的、可度量的事件,能进行清晰能定义。


3、PERT的准备工作是PERT图使用中最有价值的部分。它包括整个网状结构的展开、任务之间依赖关系的识别、
  各个任务链的估计。这些都要求在项目早期进行非常专业的计划。第一份PERT图总是很恐怖的,不过人们总是
  不断地进行努力,运用才智制订下一份PERT图。


4、必须有评审的机制,从而所有成员可以通过它了解真正的状态。出于这个目的,里程碑的计划和完成文档是关键。
  对于大型项目,一个对里程碑报告进行维护的计划和控制(Plan and Control)小组是非常可贵的。


5、当进度出现偏差后,项目经理往往把问题掩盖起来,而且经常主观的认为可以通过各种赶进度的手段来挽回
  进度损失,但是往往情况并不是这么简单。因为很多时候引起进度的偏差往往存在一些问题的根源,而这些根源
  往往是需要老板提前介入并采取一些行动,因此老板必须仔细区分状态报告、毫无惊慌地接收报告、决不越俎代庖,
  将能鼓励诚实的汇报。


十五、另外一面
1、为了得到一份有用的文字描述,就必须放慢脚步,稳妥地进行。
  (1)目的。主要的功能是什么?开发程序的原因是什么?
  (2)环境。程序运行在什么样的机器、硬件配置和操作系统上?
  (3)范围。输入的有效范围是什么?允许显示的合法范围是什么?
  (4)实现功能和使用的算法。精确地阐述它做了什么。
  (5)输入-输出格式。必须是确切和完整的。
  (6)操作指令。包括控制台及输出内容中正常和异常结束的行为。
  (7)选项。用户的功能选项有哪些?如何在选项之间进行挑选?
  (8)运行时间。在指定的配置下,解决特定规模问题所需要的时间?
  (9)精度和校验。期望结果的精确程度?如何进行精度的检测?

2、流程图是被吹捧得最过分的一种程序文档。事实上,很多程序甚至不需要流程图,很少有程序需要一页纸以上的
  流程图。当流程图绘制在一张图上时,它能非常优雅地显示程序的判断流向,但当它被分成几张时,也就是说需要
  采用经过编号的出口和连接符来进行拼装时,整体结构的概观就严重地被破坏了。


3、数据处理的基本原理告诉我们,试图把信息放在不同的文件中,并努力维持它们之间的同步,是一种非常费力
  不讨好的事情。更合理的方法是:每个数据项包含两个文件都需要的所有信息,采用指定的键值来区别,并把它们
  组合到一个文件中。在程序文档编制的实践中却违反了我们自己的原则。典型的,我们试图维护一份机器可读的
  程序,以及一系列包含记叙性文字和流程图的文档。相应的解决方案是“合并文件”,即把文档整合到源代码。
  这对正确维护是直接有力的推动,保证编程用户能方便、即时地得到文档资料。

4、即使对于完全开发给自己使用的程序,描述性文字也是必须的,因为它们会被用户-作者所遗忘。程序修改
  人员所使用的文档中,除了描述事情如何以外,还应阐述它为什么那样。对于加深理解,目的是非常关键的,但即使
  是高级语言的语法,也不能表达目的。


十六、没有银弹
  1、没有任何技术或管理上的进展,能够独立地许诺十年内使生产率、可靠性或简洁性获得数量级上的进步。


  2、在所有恐怖民间传说的妖怪中,最可怕的是人狼,因为它们可以完全出乎意料地从熟悉的面孔变成可怕的怪物。
  为了对付人狼,我们在寻找可以消灭它们的银弹。大家熟悉的软件项目具有一些人狼的特性(至少在非技术经理看来),
  常常看似简单明了的东西,却有可能变成一个落后进度、超出预算、存在大量缺陷的怪物。


3、开发软件系统的过程中,最困难的部分是确切地决定搭建什么样的系统。概念性工作中,没有其他任何一个部分
  比确定详细的技术需求更加困难,详细的需求包括了所有的人机界面、与机器和其他软件系统的接口。需求工作对
  系统的影响比其他任何一个部分的失误都大,当然纠正需求的困难也比其他任何一个部分要大。


4、增量开发——增长,而非搭建系统。即,首先系统应该能够运行,即使未完成任何有用功能,只能正确调用一系
  列伪子系统。接着,系统一点一点被充实,子系统轮流被开发,或者是在更低的层次调用程序、模块、子系统的
  占位符(伪程序)等。


5、卓越的设计人员。关键的问题是如何提高软件行业的核心,一如既往的是——人员。尽管很多杰出、实用的软件
  系统是由很多人共同设计开发,但是那些激动人心、拥有广大热情爱好者的产品往往是一个或者少数伟大设计
  师们的思想。


6、软件开发的过程必须要考虑如何适应变化,在需求,设计和编码过程中都需要考虑如何快速响应变化,如何提高
  软件产品的可扩展性。我们在软件开发生命周期模型上强调增量迭代的思路,强调测试驱动的思路其根本目的就是
  为了快速响应变化,降低变化带来的风险。


7、面向对象编程的特征:
  (1)它强调模块化和清晰的接口。
  (2)它强调了封装,即外界无法看到组件的内部结构
  (3)它还强调了继承和层次化类结构以及虚函数。
  (4)强调了强抽象数据类型化,它确保某种特定的数据类型只能由它自身的相应函数来操作。


8、现在有很多快速开发平台,但是真正能够不写代码就完成业务功能的开发平台基本上没有成功的,特别是在业务
  场景比较复杂情况下,编程自动化基本是不可能的事情。唯一看到有所突破的是关于统一框架和技术平台等方面
  的建设,在原有的框架基础上我们来构建一个产品开发平台,将跟业务关系不大的权限模型,工作流引擎等集成
  进去,将常用的可复用组件集成进去,加快开发速度。


9、不要在追求自动编程平台上下功夫,可以在加强组件复用和技术平台建设上下功夫。


10、要多从开发模式的改进上来解决没有银弹所提出的各种实际问题,虽然不能够彻底解决,但是可以通过努力
  来改进。比如增量迭代的开发模型,快速原型法,测试驱动,高级语言和图形化编程等。


猜你喜欢

转载自clq9761.iteye.com/blog/1678930