人月神话-摘抄

news/2024/11/17 13:31:10/文章来源:https://www.cnblogs.com/lhxBlogs/p/17109417.html

由于人员的分工,大型编程项目碰到的管理问题和小项目区别很大:我相信关键需要是维持产品自身的概念完整性。

1. 焦油坑(the tar pit)

过去几十年的大型系统开发犹如这样一个焦油坑,很多大型和强壮的动物在其中剧烈地挣扎。他们中大多数开发出了可运行的系统-不过,其中只有非常少数的项目满足了目标、时间进度和预算的要求。

表面上看起来好像没有任何一个单独的问题会导致困难,每个都能被解决,但是当它们相互纠缠和累积在一起的时候,团队的行动就会变得越来越慢。对问题的麻烦程度,每个人似乎都会感到惊讶,并且很难看清问题的本质。不过,如果我们想解决问题,就必须试图先去理解它。

1.1 编程系统产品

报纸上经常会出现这样的新闻,讲述两个程序员如何在经改造的简陋车库中,编出了超出大型团队工作量的重要程序。

image

1.2 职业的乐趣

首先是一种创造事物的纯粹快乐

其次,快乐来自于开发对其他人有用的东西。内心深处,我们期望其他人使用我们的劳动成果,并能对他们有所帮助

第三,整个过程体现出魔术般的力量-将相互咬合的零部组件组装在一起,看到它们精妙地运行,得到预先所希望的结果

第四,学习的乐趣,来自于这项工作的非重复特性。人们所面临的问题,在某个或其他方面总有些不同。因而解决问题的人可以从中学习新的事物:有时是实践上的,有时是理论上的,或者兼而有之

最后,乐趣还来自于工作在如此易于驾驭的介质上。很少有这样的介质-创造的方式如此的灵活,如此的易于精炼和重建,如此的容易实现概念上的设想。

1.3 职业的苦恼

首先,必须追求完美。将做事的方式往追求完美的方向调整

其次,是由他人来设定目标,供给资源,提供信息。

对于系统编程人员而言,对其他人的依赖是一件非常痛苦的事情。他依靠其他人的程序,而往往这些程序设计得并不合理,实现拙劣,发布不完整(没有源代码或测试用例),或者文档记录的很糟。所以,系统编程人员不得不花费时间去研究和修改,而它们在理想情况下本应该是可靠完整的。

概念性设计是有趣的,但寻找琐碎的bug却只是一项重复项的活动。伴随着创造性活动的,往往是枯燥沉闷的时间和艰苦的劳动。程序编制工作也不例外。

另外,人们发现调试和查错往往是线性收敛的,或者更糟糕的是,具有二次方的复杂度。结果,测试一拖再拖,寻找最后一个错误比第一个错误将花费更多的时间。

最后一个苦恼,有时也是一种无奈-当投入了大量辛苦的劳动 ,产品在即将完成或者终于完成的时候,却已显得陈旧过时。可能是同事和竞争对手已在追逐新的、更好的构思;也许替代方案不仅仅是在构思,而且已经在安排了。

现实情况比上面所说的通常要好一些。当产品开发完成时,更优秀的新产品通常还不能投入使用,而仅仅是为大家谈论而已。另外,它同样需要数月的开发时间。事实上,只有实际需要时,才会用到最新的设想,因为所实现的系统已经能满足要求,体现了回报。

诚然,产品开发所基于的技术在不断地进步。一旦设计被冻结,在概念上就已经开始陈旧了。不过,实际产品需要一步一步按阶段实现。实现落后与否的判断应根据其他已有的系统,而不是未实现的概念。因此,我们所面临的挑战和任务是在现有的时间和有效的资源范围内,寻找解决实际问题的切实可行方案。

2. 人月神话(the mythical man-month)

在众多软甲项目中,缺乏合理的时间进度是造成项目之后的最主要原因,它比其他所有因素加起来的影响还大。导致这种普遍性灾难的原因是什么呢?

首先,我们队估算技术缺乏有效的研究,更加严肃地说,它反映了一种悄无声息,但并不真实的假设-一切都将运作良好(技术评估)

第二,我们采用的估算技术隐含地假设人和月可以互换,错误地将进度与工作量相互混淆

第三,由于对自己的估算缺乏信息,软件经理通常不会有耐心持续地进行估算这项工作

第四,对进度缺少跟踪和监督

第五,当意识到进度的偏移时,下意识(以及传统)的反应是增加人力

2.1 乐观主义

系统编程的进度安排背后的第一个假设是:一切都将运作良好,每一项任务仅花费它所"应该"花费的时间

创造性活动分为三个阶段:构思、实现和交流

2.2 人月

第二个谬误的思考方式是在估计和进度安排中使用的工作量单位:人月。成本的确随开发产品的人数和时间的不同,有着很大的变化,进度却不是如此。因此我认为用人月作为衡量一项工作的规模是一个危险和带有欺骗性的神话。它暗示着人员数量和时间是可以相互替换的。

人数和时间的互换仅仅适用于以下情况:某个任务可以分解给参与人员,并且他们之间不需要相互的交流。这在割小麦或收获棉花的工作中是可行的;而在系统编程中近乎不可能。

image

当任务由于次序上的限制不能分解时,人手的添加对进度没有帮助

image

对于可以分解,但子任务之间需要相互沟通和交流的任务,必须在计划工作中考虑沟通的工作量。因此,相同人月的前提下,采用增加人手来减少时间得到的最好情况,也比未调整前要差一些

image

沟通所增加的负担由两个部分组成,培训和相互的交流。每个成员需要进行技术、项目目标以及总体策略上的培训。这种培训不能分解,因此这部分增加的工作流随人员的数量呈线性变化

相互之间交流的情况更糟一些。如果任务的每个部分必须分别和其他部分单独协作,则工作量按照 n(n-1)/2 递增。所增加的用于沟通的工作量

image

因为软件开发本质上是一项系统工作-错综复杂关系下的一种实践-沟通、交流的工作量非常大,它很快会消耗任务分解所节省下来的个人时间。从而, 添加更多的人手,实际上是延长了,而不是缩短了时间进度。

2.3 系统测试

在时间进度中,顺序限制所造成的影响,没有哪个部分比单元调试和系统测试所受到的牵涉更彻底。而且,要求的时间依赖于所遇到的错误、缺陷数量以及捕捉它们的程度。因此,系统测试进度的安排常常是编程中最不合理的部分。

1/3计划

1/6编码

1/4 构件测试和早期系统测试

1/4 系统测试,所有的构件已完成

在许多重要的方面,它与传统的进度安排方法不同:

1.分配给计划的时间比寻常的多。即便如此,仍不足以产生详细和稳定地计划规格说明,也不足以容纳对全新技术的研究和摸索

2.对所完成代码的调试和测试,投入近一半的时间,比寻常的安排多很多

3.容易估计的部分,即编码,仅仅分配了六分之一的时间

特别需要指出的是,不为系统测试安排足够的时间简直就是一场灾难。

2.4 空泛的估算

两种解决方案:

  • 开发并推行生产率图表、缺陷率、估算规则等,而整个组织最终会从这些数据的共享上获益。
  • 在基于可靠基础的估算出现之前,项目经理需要挺直腰杆,坚持它们的估计,确信自己的经验和直觉总比从期望派生出的结果要强很多

2.5 重复产生的进度灾难

在新的进度安排中分配充分的时间,以确保工作能仔细、彻底地完成,从而无需重新确定时间进度表。

向进度落后的项目中增加人手,只会使进度更加落后

项目的时间依赖于顺序上的限制,人员的数量依赖于单个子任务的数量,从这两个数值可以推算出进度时间表。

总之,在众多软件项目中,缺乏合理的时间进度是造成项目之后的最主要原因,它比其他所有因素加起来的影响还要大

3. 外科手术队伍(the surgical team)

如何在有意义的时间进度内创建大型的系统?

王刚做菜为什么做不来一样的?
菜品不一定完全买得到
刀工不行
处理步骤缺斤短两
掌握不好油温,火候
如果某一步提前了,后序如何做(烧糊了,烧老了),如何补救(只买了一次性食材),如何做到一气呵成(做不到,厨师也是作废了很多次菜才驾轻就熟的)

跨海大桥施工方案 - 百度文库 (baidu.com)

人力(技术人才+施工团队),运输,审批申请,投标方案,物资购买,水文、地理观测(地震,台风,水流),环境,天气,浇筑,载具,轮船租借,工厂部件验收,吊具

3.1 问题

需要协作沟通的人员的数量影响着开发成本(系统之间,开发部门内部人员之间,各个部门之间(技术与技术 业务与业务 技术与业务)),因为成本的主要组成部分是相互的沟通和交流,以及更正沟通不当所引起的不良后果(系统调试)。这一点,也暗示系统应该由尽可能少的人员来开发

信息交流,通用语言,信息的及时性,准确性,信息的能量在逐级递减,以致会出现偏差,错误,沟通成本在逐渐变大

得出的结论很简单:如果一个200人的项目中,有25个最能干的和最有开发经验的项目经理,那么开除剩下的175名程序员,让项目经理来编程开发

3.2 mills的建议

mills建议大型项目的每一个部分由一个团队解决,但是该队伍以类似外科手术的方式组件,而并非一拥而上。也就是说,同每个成员截取问题某个部分的做法相反,由一个人来进行问题的分解,其他人给予他所需要的支持,以提高效率和生产力。

外科医生。mills成为首席程序员。他亲自定义功能和性能技术说明书,设计程序,编制源代码,测试以及书写技术文档。他使用编程语言,拥有对计算机系统的访问能力;该计算机系统不仅仅能进行测试,还存储程序的各个版本(版本管理),以允许简单地文件更新,并对他的文档提供文本编辑能力。首席程序员需要极高的天分、十年的经验和应用数学、业务数据处理或其他方面的大量系统和应用知识

副手。他是外科医生的后备,能完成任何一部分工作,但是相对具有较少的经验。他的主要作用是作为设计的思考者、讨论者和评估人员。外科医生试图和他沟通设计,但不受到他建议的限制。副手经常在于其他团队的功能和接口讨论中代表自己的小组。他需要详细了解所有的代码,研究设计策略的备选方案。显然,他充当外科医生的保险机制。他甚至可能编制代码,但针对代码的任何部分,不承担具体的开发职责。

管理员。外科医生是老板,他必须在人员、加薪等方面具有决定权,但他绝不能在这些事务上浪费任何时间。因而,他需要一个控制财务、人员、工作地点安排和机器的专业管理人员,该管理员充当与组织中其他管理结构的接口。Baker建议仅在项目具有法律、合同、报表和财务方面的需求时,管理员才具有全职责任。否则,一个管理员可以为两个团队服务。

编辑。外科医生负责产生文档-处于最大清晰度的考虑,他必须书写文档。对内部描述和外部描述都是如此。而编辑根据外科医生的草稿或者口述的手稿,进行分析和重新组织,提供各种参考信息和书目,对多个版本进行维护以及监督文档生成的机制。

两个秘书。管理员和编辑每个人需要一个秘书。管理员的秘书负责项目的协作一致和非产品文件。

程序职员。他负责维护编程产品库中所有团队的技术记录。该职员接收秘书性质的培训,承担机器码文件和可读文件的相关管理责任。

我的职责:

  1. 根据问题反馈修复线上问题
  2. 根据功能改进建议,分析,评估,确认可以改进后,进行细节补充完善,与提出方进行最终确认,最后开发,测试,上线,提醒提出方进行使用、测试、及时反馈
  3. 统计分析线上频发问题,找到问题的根源出处,从根源上解决问题(可能业务方没发现或无所谓)
  4. 对代码进行优化(时间上,业务之间的联动性,内聚,解耦,重构代码,使用阿里巴巴规约进行项目工程扫描,进行改进)
  5. 持续梳理业务(形成深层认识),挖掘项目本质,划分领域模型,提炼核心模型、限界上下文,参考相关类似系统功能,持续集成

柯达相机最好的时候是在倒闭的前夕,即使做得再好,如果被颠覆,也难逃倒闭

所有的计算机输入汇集到这个职员处。如果需要,他会对它们进行记录或者标识。输出列表会提交给程序职员,由他进行归档和编制索引。另外,他负责将任何模型的最新运行情况记录在状态日志中。而所有以前的结果则按时间顺序进行归档保存。

mill概念的真正关键是"从个人艺术到公共实践"的编程概念转换。

程序职员的专业化分工,使程序员从书籍的杂事中解放出来,同时还可以对那些杂事进行系统整理,确保了它们的质量,并强化了团队最有价值的财富-工作产品。

工具维护人员。(运维?技术评审团队?团队协作工具?)文本编辑、文件编辑和交互调试等工具。外科医生是这些工具、服务可用性的唯一评判人员。他需要一个工具维护人员,保证所有基本服务的可靠性,以及承担团队成员所需要的特殊工具的构建、维护和升级责任。

测试人员。外科医生需要大量合适的测试用例,计划测试步骤,搭建测试平台。

语言专家。掌握多种复杂编程语言的人。外科医生主要是系统设计者以及考虑系统的整体表现。而语言专家则寻找一种简洁、有效的使用语言的方法来解决复杂、晦涩或者棘手的问题。他通常需要对技术进行一些研究(2-3天)。

3.3 如何运作

十个人,其中七个在解决问题,而系统是一个或者最多两个人思考的产物,因此客观上达到了概念的一致性。

首先,传统的团队将工作进行划分,每人负责一部分工作的设计和实现。在外科手术团队中,外科医生和副手都了解所有的设计和全部的代码。

第二,在传统的队伍中大家是平等的,出现观点的差异时,不可避免地需要讨论和进行相互的妥协和让步。在外科手术团队中,观点的不一致由外科医生单方面来统一

另外,团队中剩余人员职能的专业化分工是高效的关键,它使成员之间采用非常简单地交流模式成为可能

image

3.4 团队的扩建

扩建过程的成功依赖于这样一个事实,即每个部分的概念完整性得到了彻底的提高。

对于协调的问题,还是需要使用分解的技术。

整个系统必须具备概念上的完整性,要有一个系统结构师从上至下地进行所有的设计。要使工作易于管理,必须清晰地划分体系结构设计和实现之间的界线,系统结构师必须一丝不苟地专注于体系结构。

4. 贵族专职、民主政治和系统设计(aristocract,democracy,and system design)

4.1 概念一致性

  • 如何得到概念的完整性?
  • 这样的观点是否要有一位杰出的精英,或者说是结构设计师的贵族专制,和一群创造性天分和构思被压制的平民编程实现人员?
  • 如何避免结构设计师产出无法实现、或者是代价高昂的技术规格说明,使大家陷入困境?
  • 如何才能与实现人员就技术说明的琐碎细节充分沟通,以确保设计被正确地理解,并精确地整合到产品中?

4.2 获得概念的完整性

由于模板是易用性,功能与理解上复杂程度的比值才是系统设计的最终测试标准。

4.3 贵族专制统治和民主政治

概念的完整性要求设计必须由一个人,或者非常少数互有默契的人员来实现。

而进度压力却要求很多人员来开发系统。有两种方法可以解决这种矛盾。第一种是仔细地区分设计方法和具体实现。第二种是前一章节中所讨论的、一种崭新的组建编程开发团队的方法。

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

新的概念经常来自实现者或者用户。

系统的概念完整性决定了使用的容易程度。不能与系统基本概念进行整合的良好想法和特色,最好放到一边,不予考虑。如果出现了很多非常重要但不兼容的构思,就应该抛弃原来的设计,对不同基本概念进行合并,在合并后的系统上重新开始。

4.4 在等待时,实现人员应该做什么?

当建议由体系结构的团队来编写计算机和编程系统的所有外部技术说明时,编程人员提出三个反对意见:

  • 该说明中的功能过于繁多,而对实际情况中的成本考虑比较少
  • 结构师获得了所有创造发明的快乐,剥夺了实现人员的创造力
  • 当体系结构的队伍缓慢工作时,很多实现人员只能空闲地坐着等待

具体实现中创造和发明的机会,并不会因为制定了外部技术说明而大为减少,相反创造性活动会因为规范化而得到增强,整个产品也一样

在说明完成的时候,才雇佣编程实现人员。这也正是在搭建一座建筑时所采用的方法

在计算机这个行业中,节奏非常快,而且常常想尽可能地压缩时间进度,那么技术说明和开发实现能有多少重叠呢?

整个创造性活动包括了三个独立的阶段:

  • 体系结构(architecture)
  • 设计实现(implementation)
  • 物理实现(realization)

5. 画蛇添足(the second-system effect)

如果将制订功能规格说明的责任从开发快速、成本低廉的产品的责任中分离出来,那么有什么样的准则和机制来约束结构师的创造性热情呢?

基本回答是结构师和建筑人员之间彻底、仔细和谐的交流。

5.1 结构师的交互准则和机制

5.2 自律-开发第二个系统所带来的后果

6. 贯彻执行(passing the word)

6.1 文档化的规格说明-手册

规格说明的风格必须清晰、完整和准确。用户常常会单独提到某个定义,所以每条说明都必须重复所有的基本要素,所以所有文字都要相互一致。这往往使手册读起来枯燥乏味,但是精确比生动更加重要。

6.2 形式化定义

英语或者其他任何的人类语言,从根本上说,都不是一种能精确表达上述定义的手段。因此,手册的作者必须注意自己的思路和语言,达到所需要的精确程度。一种颇具吸引力的做法是对上述定义使用形式化标记方法。毕竟,精确度是我们需要的东西,这也正是形式化标记方法存在的理由和原因。

古老的格言说:"决不要携带两个时钟出海,带一个或三个"

6.3 直接整合

6.4 会议和大会

周例会,每周半天,由所有的架构师,加上硬件和软件实现人员代表和市场计划人员参与,由首席系统架构师主持

会议中,任何人可以提出问题和修改意见,但是建议书通常是以书面形式,在会议之前分发。新问题通常会被讨论一些时间。重点是创新,而不仅仅是结论。

该小组试图发现解决问题的新方法,然后少数解决方案会被传递给一个和几个架构师,详细地记录到书面的变更建议说明书中。

接着会对详细的变更建议做出决策。这会经历几个反复过程,实现人员和用户会仔细地进行考虑,正面和负面的意见都会被很好地描述。如果达成了共识,非常好;如果没有,则由首席架构师来决定。这需要花费时间,最终所发布的结论是正式和果断的。

周例会的决策会给出迅捷的结论,允许工作继续进行。如果任何人对结果过于不高兴,可以立刻诉诸于项目经理,但是这种情况非常少见。

1.数月内,相同小组-结构师、用户和实现人员-每周交流一次。因此,大家对项目相关内容比较了解,不需要安排额外时间对人员进行培训

2.上述小组十分睿智和敏锐,深刻理解所面对的问题,并且与产品密切相关。没有人是"顾问"的角色,每个人都要承担义务

3.当问题出现时,在界线的内部和外部同时寻求解决方案

4.正式的书面建议集中了注意力,强制了决策的制订,避免了会议草稿纪要方式的不一致

5.清晰地授予首席架构师决策的权利,避免了妥协和拖延

7. 为什么巴比伦塔会失败?(why did the tower of babel fail ?)

7.1 巴比伦塔的管理教训

这个故事在很多方面的不同层次都是非常深刻和富有教育意义的。让我们将它仅仅作为纯粹的工程项目,来看看有什么值得学习的教训。这个项目到底有多好的先决条件?他们是否有:

  1. 清晰的目标?是的,尽管幼稚的近乎不可能。而且,项目早在遇到这个基本的限制之前,就已经失败了。
  2. 人力?非常充足
  3. 材料?在美索不达米亚有着丰富的泥土和柏油沥青
  4. 足够的时间?没有任何时间限制的迹象
  5. 足够的技术?是的,金字塔、锥形的结构本身就是稳定的,可以很好分散压力负载。同样,项目远在达到技术限制之间,就已经失败了。

那么,既然他们具备了所有的这些条件,为什么项目还会失败呢?他们还缺乏些什么?两个方面-交流,以及交流的结果-组织。他们无法相互交谈,从而无法合作。当合作无法进行时,工作陷入了停顿。

7.2 大型编程项目中的交流

  • 非正式途径
    • 清晰定义小组内部的相互关系和充分利用电话,能鼓励大量的电话沟通,从而达到对所书写文档的共同理解
  • 会议
    • 常规项目会议。会议中,团队一个接一个地进行简要的技术陈述。这种方式非常有用,能澄清成百上千的细小误解
  • 工作手册
    • 在项目的开始阶段,应该准备正式的项目工作手册。理所应当,我们专门用一节来讨论他

7.3 项目工作手册

项目工作手册不是独立的一篇文档,它是对项目必须产出的一系列文档进行组织的一种结构。

项目所有的文档都必须是该结构的一部分。这包括目的、外部规格说明、接口说明、技术标准、内部说明和管理备忘录。

第二个原因是控制信息发布。控制信息发布并不是为了限制信息,而是确保信息能达到所有需要它的人的手中。

项目手册的第一步是对所有的备忘录编号,从而每个工作人员可以通过标题列表来检索是否有他所需要的信息。还有一种更好的组织方法,就是使用树状的索引结构。

工作手册的实时更新是非常关键的。所有接收的人员还是会面临消耗理解的问题。当他第一次收到更改页时,他需要知道,"修改了什么?"迟些时候,当他就问题进行咨询时,他需要知道"现在的定义是什么?"

理解的问题可以通过持续的文档维护来解决。文档变更的强调有若干个步骤。首先,必须在页面上标记发生改变的文本,例如,使用页边上的竖线标记每行变化的文字。第二,分发的变更页附带独立的总结性文字,对变更的重要性以及批注进行记录。

7.4 大型编程项目的组织架构

减少交流的方法是人力划分(division of labor)和限定职责范围(specialization of function)

8. 胸有成竹(calling the shot)

实践是最好的老师,但是,如果不能从中学习,再多的实践也没有用

9. 削足适履(ten pounds in a five-pound sack)

9.4 数据的表现形式是编程的根本

创造出自精湛的技艺,精炼、充分和快速的程序也是如此。技艺改进的结果往往是战略上的突破,而不仅仅是技巧上的提高。这种战略上突破有时是一种新的算法。

10. 提纲掣领(the documentary hypothesis)

文档的跟踪维护是项目监督和预警的机制。文档本身可以作为检查列表、状态控制,也可以作为汇报的数据基础。

10.1 计算机产品的文档

目标

技术说明

进度、时间表

预算

组织机构图

工作空间的分配

报价、预测、价格:这三个因素互相牵制,决定了项目的成败

11. 未雨绸缪(plan to throw one away)

不变只是愿望,变化才是永恒

11.2 唯一不变的就是变化本身

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

我从不建议顾客目标和需求的所有变更必须、能够、或者应该整合到设计中。项目开始时建立的基准,肯定会随着开发的进行越来越高,甚至开发不出任何产品。

然而,目标上的一些变化无可避免,实现为它们做准备总比假设它们不会出现要好得多。不但目标上的变化不可避免,而且设计策略和技术上的变化也不可避免。抛弃原型概念本身就是对事实的接收-随着学习的过程更改设计。

11.5 前进两步,后退一步

软件维护不包括清洁、润滑和对损坏器件的修复。它主要包含对设计的修复。

对于一个广泛使用的程序,其维护总成本通常是开发成本的40%或更多。令人吃惊的是,该成本受用户数目的严重影响。用户越多,所发现的错误就越多。
image

程序维护中的一个基本问题是-缺陷修复总会以(20-50)%的几率引入新的bug。所以整个过程是前进两步,后退一步。

为什么缺陷不能更彻底地被修复?首先,看上去很轻微的错误,似乎仅仅是局部操作上的失败,实际上却是系统级别的问题,通常这不是很明显。修复局部问题的工作量很清晰,并且往往不大。但是,更大范围的修复工作常常会被忽视,除非软件结构很简单,或者文档书写得非常详细。其次,维护人员常常不是编写代码的开发人员,而是一些初级程序员或者新手。

作为引入新Bug的一个后果,程序每条语句的维护需要的系统测试比其他编程要多。理论上,在每次修复之后,必须重新运行先前所有的测试用例,从而确保系统不会以更隐蔽的方式被破坏。实际情况中,回归测试必须接近上述理想状况,所以它的成本非常高。

11.6 前进一步,后退一步

所有修改都倾向于破坏系统的架构,增加了系统的混乱程度。

随着时间的推移,系统变得越来越无序,修复工作迟早会失去根基。每一步前进都伴随着一步后退。尽管理论上系统一直可用,但实际上,整个系统已经面目全非,无法再成为下一步进展的基础。而且,机器在变化,配置在变化,用户的需求在变化,所以显示系统不可能永远可用。崭新的、基于原有系统的重新设计是完全必要的。

系统软件开发是减少混乱度(减少熵)的过程,即使是最熟练的软件维护工作,也只是放缓了系统退化到非稳态的进程。

12. 干将莫邪(sharp tools)

通信工具,文档工具,组织协同工具,测试工具,编程语言

13. 整体部分(the whole and the parts)

如何开发一个可以运行的系统?如何测试系统?如何将经过测试的一系列构建集成到已测试过、可以依赖的系统?对这些问题,我们以前或多或少地提到了一些方法,现在就来更加系统地考虑一下。

13.1 剔除bug的设计

关键的工作时产品定义。许许多多的失败完全源于那些产品未精确定义的地方。

程序开发划分为:体系结构设计、设计实现和物理编码实现

14. 祸起萧墙(hatching a catastrophe)

14.2 "其他的部分反正会落后"

必须关心每一天的滞后,它们是大灾祸的基本组成元素。

并不是每一天的滞后都等于灾难。那么,如何判断哪些偏离是关键的呢?

只有采用pert 计划评审技术_百度百科 (baidu.com)或者AOE(关键路径)才能判断。它显示谁需要什么样的东西,谁位于关键路径上,他的工作滞后会影响最终的完成日期。另外,它还指出一个任务在成为关键路径时,可以落后的时间。

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

14.3 地毯的下面

所有的污垢都被隐藏在地毯之下。

但是每个老板都需要两种信息:需要采取行动的计划方面的问题,用来进行分析的状态数据。出于这个目的,他需要了解所有开发队伍的情况。但得到状态的真相是很困难的。

一线经理的利益和老板的利益是内在冲突的。一线经理担心如果汇报了问题,老板会采取行动,这些行动会取代经理的作用,降低自己的威信,搞乱了其他计划。所以,只要项目经理认为自己可以独立解决问题,他就不会告诉老板。

有两种掀开毯子把污垢展现在老板面前的方法,它们必须都被采用。一种是减少角色冲突和鼓励状态共享,另一种是猛地拉开地毯。

减少角色冲突:首先老板必须区别行动信息和状态信息。他必须规范自己,不对项目经理可以解决的问题做出反应,并且决不在检查状态报告的时候做安排。当然,事态发展到无法控制时,状态检查会议变成问题-行动会议。

猛地拉开地毯:不论写作与否,拥有能了解状态真相的评审机制是必要的。pert图以及频繁的里程碑是这种评审的基础。大型项目中,可能需要每周对某些部分进行评审,大约一个月左右进行整体评审。

15. 另外一面(the other face)

计算机程序是从人传递到机器的一些信息。为了将人的意图清晰地传达给不会说话的机器,程序采用了严格的语法和严谨的定义。

但是书面的计算机程序还有其他的呈现面貌:向用户诉说自己的"故事"。即使是完全开发给自己使用的程序,这种沟通仍然是必要的。因为记忆衰退的规律会使用户-作者失去对程序的了解,于是他不得不重拾自己劳动的各个细节。

公共应用程序的用户在时间和空间上都远离它们的作者,因此对这类程序,文档的重要性更是不言而喻!对软件编程产品来说,程序向用户所呈现的面貌和提供给机器识别的内容同样重要。

面对那些文档"简约"的程序,我们中的大多数人都不免曾经暗骂那些远在他方的匿名作者。因此,一些人试图向新人慢慢地灌输文档的重要性:旨在延迟软件的声明期、克服惰性和进度的压力。

如何做(才能产生一篇优秀的文档)

15.1 需要什么样的文档

不同用户需要不同级别的文档。某些用户仅仅偶尔使用程序,有些用户必须依赖程序,还有一些用户必须根据环境和目的的变动对程序进行修改。

  1. 目的。主要的功能是什么?开发程序的原因是什么?

  2. 环境。程序运行在什么样的机器、硬件配置和操作系统上?

  3. 范围。输入的有效范围是什么?允许显示的合法范围是什么?

  4. 实现功能和使用的算法。精确地阐述它做了什么。

  5. 输入-输出格式。必须是确切和完整的。

  6. 选项。用户的功能选项有哪些?如何在选项之间进行挑选?

  7. 操作指令。包括控制台及输出内容中正常和异常结束的行为。

  8. 运行时间。在指定的配置下,解决特点规模所需要的时间?

  9. 精度和校验。期望结果的精确程度?如何进行精度的检测?

使用程序

验证程序:测试用例

  1. 针对遇到的大多数常规数据和程序主要功能进行测试的用例
  2. 数量相对较少的合法数据测试用例,对输入数据范围边界进行检查,确保最大可能值、最小可能值和其他有效特殊数据可以正常工作
  3. 数量相对较少的非法数据测试用例,在边界外检查数据范围边界,确保无效的输入有正确的数据诊断提示

修改程序

  1. 流程图或子系统的结构图
  2. 对所用算法的完整描述
  3. 对所有文件规划的解释
  4. 数据流的概要描述
  5. 初始设计中,对已预见修改的讨论;特性、功能回调的位置以及出口:原作者对可能会扩充的地方以及可能处理方案的一些意见。另外,对隐藏缺陷的观察也同样很有价值。

15.3 自文档化(self-documenting)的程序

把文档整合到代码中

16. 没有银弹-软件工程中的根本和次要问题(no silver bullet-essence and accident in software engineering)

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

所有软件活动包括根本任务-打造由抽象软件实体构成的复杂概念结构,次要人物-使用编程语言表达这些抽象实体,在空间和时间限制内将它们映射成机器语言。软件生产率的近年内取得的巨大进步来自于对后天障碍的突破。

  • 仔细地进行市场调研,避免开发已上市的产品
  • 在获取和制订软件需求时,将快速原型开发作为迭代计划的一部分。
  • 有机地更新软件,随着系统的运行、使用和测试,逐渐添加越来越多的功能
  • 不断挑选和培养接触的概念设计人员

16.1 摘要

16.2 介绍

大家熟悉的软件项目具有一些人狼的特性(至少在非技术经理看来),常常看似简单明了的东西,却有可能变成一个落后进度、超出预算、存在大量缺陷的怪物。因此,我们听到了近乎绝望的互换,寻求一种可以使软件成本像计算机硬件成本一样降低的尚方宝剑。

解决管理灾难的第一步是将大块的"巨无霸理论"替换成"微生物理论",它的每一步-希望的诞生,本身就是对一蹴而就型解决方案的冲击。它告诉工作者进步是逐步取得的,伴随着辛勤的劳动,对规范化过程应进行持续不懈的努力。有此,诞生了现在的软件工程。

16.3 是否一定那么困难呢?-根本困难

软件开发中苦难的部分是规格化、设计和测试这些概念上的结构,而不是对概念进行表达和对实现逼真程度进行验证。当然,我们还是会犯一些语法错误。

现代软件系统中这些无法规避的内在特性:复杂度、一致性、可变性和不可见性

可预见性,可知行,不可预见性,混沌

数学和物理学在过去三个世纪取得了巨大的进步,数学家和物理学家们建立模型以简化复杂的现象,从模型中抽取出各种特性,并通过试验来验证这些特性。这些方法之所以可行-是因为模型中忽略的复杂的不是被研究现象的必要属性。当复杂度是本质特性时,这些方法就行不通了。

软件的复杂度是必要属性,不是次要因素。

复杂度导致的问题:

  1. 团队成员之间沟通非常困难,导致产品瑕疵、成本超支和进度延迟
  2. 列举和了解所有可能的状态十分困难,影响了产品的可靠性
  3. 函数的复杂度,函数调用变得困难,导致程序难以使用
  4. 结构性复杂度,程序难以在不产生副作用的情况下用新函数扩充
  5. 结构复杂度,造成很多安全机制状态上的不可见性
  6. 管理上:使全面理解问题变得困难,从而妨碍了概念上的完整性
  7. 管理上:使所有离散出口难以寻找和控制
  8. 引起大量学习和理解上的负担,使开发慢慢演变成了一场灾难

一致性:物理学家,爱因斯坦曾不断地重申自然界一定存在着简化的解释,因为上帝不是专横无端或反复无常的。

软件工程师却无法从类似的信念中获得安慰,他必须控制的很多复杂度是随心所欲、毫无规则可言的,来自若干必须遵守的人为惯例和系统。它们随接口的不同而改变,随时间的推移而变化,而且,这些变化不是必须的,仅仅由于它们是不同的人-而非上帝-设计的结果。

可变性:工业制造的产品在出厂之后不会经常地发生修改,它们会被后续模型所取代。部分原因是因为系统中的软件包含了很多功能,而功能是最容易感受变更压力的部分。另外的原因是因为软件可以很容易地进行修改-它是纯粹思维活动的产物,可以无限扩展。

所有成功的软件都会发生变更。现实工作中,经常发生两种情况。当人们发现软件很有用时,会在原有应用范围的边界,或者在超越边界的情况下使用软件。功能扩展的压力主要来自那些喜欢基本功能,又对软件提出了很多新用法的用户们。

其次,软件一定是在某种计算机硬件平台上开发,成功软件的生命期通常比当初的计算机硬件平台要长。即使不是更换计算机,则有可能是换新型号的磁盘、显示器或者打印架。软件必须与各种新生事物保持一致。

简言之,软件产品扎根于文化的母体中,如各种应用、用户、自然及社会规律、计算机硬件等。后者持续不断地变化着,这些变化无情地强迫着软件随之变化。

不可见性:控制流程、数据流、依赖关系、时间序列、名字空间的相互关系等等。做法:将关联分割,直到可以层次化一个或多个图形。

16.4 以往解决次要困难的一些突破

高级语言:可靠性、简洁性和理解程度也大为提高

分时:保证了及时性

统一编程环境:

16.5 银弹的希望

AI

专家系统

自动编程

大多数情况下所给出的技术说明本质上是问题的解决方法,而不是问题本身。

16.6 针对概念上根本问题的颇具前途的方法

需求精炼和快速模型

因此,软件开发人员为客户所承担的最重要的职能是不断重复地抽取和细化产品的需求。事实上,客户不知道他们需要什么,他们通常不知道哪些问题是必须回答的。并且,连必须确定的问题细节常常根本不予考虑,甚至只是简单地回答-"开发一个类似于我们已有的手工处理过程的新软件系统"-实际上都过于简单。客户绝不会仅仅要求这些。复杂的软件系统往往是活动的、变化的系统。所以,在计划任何软件活动时,要让客户和设计人员之间多次广泛的交流沟通,将其作为系统定义的一部分。这是非常必要的。

这里,我将向前多走一步,下一个定论。在尝试和开发一些客户定制的系统之前,即使他们和软件工程师一起工作,想要完整、精确、正确地抽取现代软件产品的需求-这,实际上也是不可能的。

因此,现在的技术中最有希望的,并且解决了软件的根本而非次要问题的技术,是开发作为迭代需求过程的一部分-快速原型化系统的方法和工具。

软件系统的快速原型对重要的界面进行模拟,并演示待开发系统的主要功能。原型不必受到相同硬件速度、规模或者成本约束的限制。原型通常展示了应用程序的功能主线,但不处理任何如无效输入、退出清除等异常情况。原型的目的是明确实际的概念结构,从而客户可以测试一致性和可用性。

对产品和原型不断往复地开发和规格化。

卓越的设计人员

17. 再论<没有银弹>(no silver bullet refired)

那些想看到完美方案的人,其实在心底里就认为它们以前不存在,以后也不可能出现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/835299.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Manjaro/Arch用怎么安装天翼云电脑(Ctyun-cloud-desk)?感谢信创,感谢国家

最近微信出了linux版,用vmware装linux不过瘾,把一台闲置的笔记本装上了Manjaro KDE Plasma,经过一段时间的发展,Linux桌面可用性大大提高。 Kindle->Kindle Mate->Anki这条路在linux下 我用 Kindle ->KindleVocab ->Anki这么代替了之后, 其他软件都能凑合用,…

Prometheus 和 Grafana 监控系统搭建

Prometheus 和 Grafana 监控系统的搭建和配置。Author: ACatSmiling Since: 2024-11-11Prometheus 的架构架构理解:Prometheus 既然设计为一个维度存储模型,可以把它理解为一个 OLAP 系统。 生态圈组件:Prometheus Server:主服务器,负责收集和存储时间序列数据。 Client L…

团队作业4——项目冲刺-6

DAY(11.16) 每日站立式会议 会议照片:会议内容:成员 昨天已完成的工作 今天计划完成的工作欧可贵 Day6博客的编写,会议的组织与展开 完成任务的对接,组织第六次会议的召开,准备用户测试吴灿豪 检查代码流畅性,美化页面,交互各个界面 继续优化代码,美化界面陈东阳 用户…

STM32F103简介

自从大学毕业之后,已经很久没有接触STM32控制器了,最近打算学习一下LVGL,控制芯片计划使用STM32,因此这里我们会简单介绍有关STM32的知识。 一、STM32F103RTC6介绍 1.1 命名规则 我从网上买了一块STM32F103RTC6开发板,STM32F103RCT6 各个字段的含义:STM32(芯片系列):S…

高级语言程序设计第七次个人作业(102400106刘鑫语)

这个作业属于哪个课程: https://edu.cnblogs.com/campus/fzu/2024C 这个作业要求在哪里: https://edu.cnblogs.com/campus/fzu/2024C/homework/13304 学号:102400106 姓名:刘鑫语 作业内容: 编写并运行博客园的八道题。 1,定义一个二维数组和指向该数组的指针,分别以数组…

20222312 2024-2025-1 《网络与系统攻防技术》实验六实验报告

1.实验内容及要求 本实践目标是掌握metasploit的用法。 指导书参考Rapid7官网的指导教程。 https://docs.rapid7.com/metasploit/metasploitable-2-exploitability-guide/ 下载官方靶机Metasploitable2,完成下面实验内容。 (1)前期渗透 ①主机发现(可用Aux中的arp_sweep,s…

解决 PbootCMS 网站转移后无法打开报错提示“No input file specified”的问题

确保所有文件路径正确无误。检查 index.php 文件确保 index.php 文件存在于网站根目录中,并且路径正确。检查其他配置文件确保 config.php 和其他配置文件路径正确。查看错误日志 查看服务器日志,获取更多详细的错误信息。PHP 错误日志通常位于 /var/log/php7.x-fpm.log 或 /…

织梦dedecms无法登录后台,提示用户名或密码错误怎么办

问题描述:无法登录后台,提示用户名或密码错误。 解决方案:检查用户名和密码:确保输入的用户名和密码正确。 清除Cookie:清除浏览器的Cookie,重新尝试登录。 检查数据库:确保数据库中的管理员账户信息正确。 检查文件权限:确保后台目录和文件的权限设置正确。 检查配置文…

网站数据库如何修改config.php,如何在网站配置文件中修改数据库连接信息

修改网站的数据库连接信息可以确保网站能够正确连接到数据库。以下是具体步骤:备份文件:在修改前,备份当前的config.php文件,确保数据安全。 使用FTP工具(如FileZilla)下载config.php文件到本地。编辑文件:使用代码编辑器(如Sublime Text、Visual Studio Code)打开con…

修改公司网站 插件,如何在公司网站后台安装和管理插件

插件可以扩展网站的功能,提升用户体验。以下是具体步骤:登录后台:打开浏览器,输入网站的后台地址,例如 http://yourdomain.com/admin。 输入管理员账号和密码,点击“登录”。进入插件管理:登录后,点击顶部菜单栏中的“插件”或“扩展”。 选择“插件管理”或“扩展管理…

网站首页修改标题描述,如何在网站后台或代码编辑器中修改首页标题和描述

修改首页标题和描述可以提升搜索引擎优化(SEO)。以下是修改首页标题和描述的步骤:登录网站后台:打开浏览器,输入网站的后台地址,例如 http://yourdomain.com/admin。 输入管理员账号和密码,点击“登录”。进入SEO设置:登录后,点击顶部菜单栏中的“SEO”或“设置”。 选…

腾讯在线文档去掉底色

现在在线文档在单位使用范围比较广泛,前两天领导给我一个问题,在线文档标黄了部分文字,需要保留格式的情况下把底色去掉。当时在领导电脑上没解决,后面自己弄了个文档来测试解决了。分享给需要的人一个参考。 觉得过程麻烦的直接看最后解决方法,前面是过程。 1、在线文档导…