1 焦油坑:
1.大型软件系统开发就像史前各种巨兽在焦油坑中垂死挣扎的场景。在众多的大型项目开发中,大多数能够开发出可运行的系统,但是其中只有非常少数的项目满足了目标,时间进度和预算的需求。各种团队,大型的和小型的,庞杂的和精干的,一个接着一个淹没在了焦油坑中。表面上看起来没有任何一个单独的问题会导致困难,每个都能被独立解决,但是当他们相互纠缠和积累在一起的时候,团队和行动就会变得越来越慢。
2 .编程系统产品:程序和编程系统、编程产品、编程系统产品是截然不同的概念,最终的编程系统的开发成本大概是最初实现单元功能程序的九倍左右。
3.编程为什么有趣?作为回报,它的从业者期望得到什么样的快乐?
首先是一种创建事物的纯粹快乐。其次,快乐来自于开发对其他人有用的东西。第三是整个过程体现出魔术般的力量--将相互啮合的零部件组装在一起,看到它们精妙地运行,得到预先所希望的结果。比起弹珠游戏或点唱机所具有的迷人魅力,程序化的计算机毫不逊色。第四是学习的乐趣,来自于这项工作的非重复特性。编程非常有趣,在于它不仅满足了我们内心深处进行创造的渴望,而且还愉悦了每个人内在的情感。
2 人月神话
所有的编程人员都是乐观主义者。我们在估算项目进度的时候,容易隐含地假设人和月可以互换,从而错误地将进度和工作量相互混淆。然而人数和时间的护花仅仅适用于任务可以分解给独立地参与人员,并且这些参与人员不会进行任何交流的情况下。这在系统编程中近乎不可能。事实上,编程届有一个著名的Brooks法则:向进度落后的项目中增加人手,只会使得该项目的进度更加落后。在众多的软件项目中,缺乏合理的时间进度安排是造成项目进度落后的最主要原因。
3 外科手术队伍
优秀程序员和较差的程序员之间的差异非常巨大。绝大多数系统编程的经验指出,一拥而上的开发方法是高成本的,速度缓慢的,不充分的。开发出的是无法在概念上进行集成的产品。Harlan Mills建议大型项目的每一个部分由一个团队去解决,但是队伍的形式是以类似外科手术的方式组建,由一个人进行问题的分解,其他人给与他所需要的支持,以提高效率和生产力。这里外科医生就是首席程序员,他负责统筹需求,任务分解,架构设计和进度安排。其中需要有一个副手,也就是外科医生的后备,他在软件开发小组里面担任思考着和建议者,首席程序员会跟他进行沟通设计,但是不受他建议的限制。同时,外科手术团队中有一个管理员的角色,负责控制财务,人员,工作时间地点安排和机器的管理等责任。在软件开发中,一个管理员的角色可以为不止一个开发团队进行服务。此外,团队中还应该有编辑,程序职员等角色。程序员的专业化分工,使他们从书记的杂事中解放出来。外科手术式的团队人员分工如图所示:
QQ截图20150815205210.png4 贵族专制、民主政治和系统设计
-
在软件系统的设计中,概念完整性是最重要的考虑因素。为了反映一系列连贯的设计思路,宁可省略一些不规则的特性和改进,也不提倡独立和无法整合的系统,哪怕他它其实包含着许多很好的设计。
-
对于小型的项目,可以按照上一章中说的“外科手术队伍”的模式来组建开发团队,这样完全可以保证系统概念的完整性。
-
对于大型的项目,为了概念的完整性,最强有力的方法就是将设计与具体实现分离。设计由一个人或者极少数人来完成,具体实现交给人数较多的实现人员来完成。设计人员对整个系统的设计具有专制的权利,可以保留其他人员对设计提建议的权利,但建议是否采用完全取决于设计人员,一切都以不破坏系统概念的完整性为准则。
这样并未剥夺具体实现人员的创造性,因为在设计好的体系结构下进行实现,同样需要创造性、需要新的思路和卓越的才华。 同传统上将工作进行水平分割相比,垂直划分从根本上大大减少了劳动量,结果是使交流彻底地简化,概念完整性得到大幅度提高。
5 画蛇添足
-
尽早交流和持续沟通能使结构师有较好的成本意识,以及使开发人员获得对设计的信心,并且不会混淆各自的责任分工。
-
结构师如何成功地影响实现: 牢记是开发人员承担创造性的实现责任;结构师只能提出建议。听取开发人员在体系结构上改进的建议。
-
第二个系统是人们所设计的最危险的系统,通常的倾向是过分地进行设计。关于这一点也许是正确的,但是这是一个回避不了的问题,如果没有开发第二个系统经验的人,就不可能有开发第三个系统经验的人了。
6 贯彻执行
即使是大型的设计团队,设计结果也必须由一个或两个人来完成,以确保这些决定是一致的。
必须明确定义体系结构中与先前定义不同的地方,重新定义的详细程度应该与原先的说明一致。
出于精确性的考虑,我们需要形式化的设计定义,同样,我们需要记叙性定义来加深理解。
允许体系结构师对实现人员的询问做出电话应答解释是非常重要的,并且必须进行日志记录和整理发布。
项目经理最好的朋友就是他每天要面对的敌人——独立的产品测试机构/小组。
7 为什么巴比伦塔会失败?
-
巴比伦塔项目的失败是因为缺乏交流,以及交流的结果的组织。
-
因为左手不知道右手在做什么,从而进度灾难、功能的不合理和系统缺陷纷纷出现。由于对其他人的各种假设,团队成员之间的理解开始出现偏差。
-
团队应该以尽可能多的方式进行相互之间的交流:非正式、常规项目会议,会上进行简要的技术陈述、共享的正式项目工作手册。
8 胸有成竹
仅仅通过对编码部分的估计,然后乘以任务其他部分的相对系数,是无法得出对整项工作的精确估计的。
构建独立小型程序的数据不适用于编程系统项目。
程序开发与程序规模成指数增长趋势。
当使用适当的高级语言时,程序编制的生产率可以提高5倍。
9 削足适履
要解决项目投资与磁盘空间和内存之间的矛盾,但是这个矛盾在电脑硬件发展到现在的层次已经可以忽略掉了。
-
软件项目的要求:目标、用户手册、内部文档、进度、预算、组织机构图和工作空间分配。
-
即使是小型项目,项目经理也应该在项目早期规范化上述的一系列文档。
这一章强调文档重要性,但并没有将一些教条主义的道理让你相信文档的重要性,而是给项目经理给出了实实在在的操作步骤。
10 未雨绸缪
-
对于大多数项目,第一个开发的系统并不合用。它可能太慢、太大,而且难以使用,或者三者兼而有之。系统的丢弃和重新设计可以一步完成,也可以一块块地实现。这是个必须完成的步骤,如果将开发的第一个系统丢弃原型发布给用户,可以获得时间,但是它的代价很高。对于用户,使用极度痛苦;对于重新开发的人员,分散了精力;对于产品,影响了声誉,即使最好的再设计也难以挽回名声。
-
用户的实际需要和用户感觉会随着程序的构建、测试和使用而变化。
软件产品易于掌握的特性和不可见性,导致了它的构建人员面临着永恒的需求变更。
目标和开发策略上的一些正常变化无可避免,事先为它们做准备总比假设它们不会出现要好得多。 -
对于一个广泛使用的程序,其维护总成本通常是开发成本的40%或更多。
维护成本受用户数目的严重影响。用户越多,所发现的错误也越多。
缺陷修复总会以(20-50)%的机率引入新的bug。 -
在每次修复之后,必须重新运行先前所有的测试用例,从而确保系统不会以更隐蔽的方式被破坏。设计实现的人员越少、接口越少,产生的错误也就越少。
-
所有修改都倾向于破坏系统的架构,增加了系统的混乱程度。即使是最熟练的软件维护工作,也只是放缓了系统退化到不可修复混乱的进程。
11 干将莫邪
项目经理应该制订一套策略,以及为通用工具的开发分配资源,与此同时,他还必须意识到专业工具的需求。
12 祸起萧墙
-
一天一天的进度落后比起重大灾难,更难以识别,更不容易防范和更加难以弥补。
-
根据一个严格的进度表来控制项目的第一个步骤是制订进度表,进度表由里程碑和日期组成。
-
里程碑必须是具体的、特定的、可度量的事件,能进行清晰能定义。
-
如果里程碑定义得非常明确,以致于无法自欺欺人时,程序员很少会就里程碑的进展弄虚作假。
13 另外一面
-
对于软件编程产品来说,程序向用户所呈现的面貌与提供给机器识别的内容同样重要。
-
即使对于完全开发给自己使用的程序,描述性文字也是必须的,因为它们会被用户和作者所遗忘。
-
文档能在整个软件开发的生命周期对程序员克服懒惰和进度的压力起促进激励作用,但向编程人员成功地灌输对待文档的积极态度是一件困难的事情。
-
为了使文档易于维护,将它们合并至源程序是至关重要的,而不是作为独立文档进行保存。
14 没有银弹
人狼的传说可能有人听过也可能没听过,人狼是一种具有人和狼两种特征的恐怖生物,而银弹是消灭它的一种最有效的子弹,如果看过《吸血鬼传说》也许就能和容易的理解这一点。作者将软件开发比作人狼,而将提高软件开发效率的方法比作银弹。作者预言未来十年,想要试图通过寻找一种有效地银弹将软件开发效率提高一个甚至几个数量级,这种银弹不可能出现。
软件工程的焦油坑在将来很长一段时间内会继续困扰着人们。由于软件系统多变性和错综复杂性,这个行业只能是一步一个台阶的往上爬,而出现银弹的希望在我们可以想象的时间范围内是非常渺茫的。我们将长期与焦油作斗争。
网友评论