软件工程管理小结---Man看了会流泪

软件工程管理


Intro

软件工程知识域:

软件需求。软件设计。软件构造。软件测试。软件维护。软件配置管理。软件工程管理。软件工程过程。软件工程模型与方法。软件质量。软件工程职业实践。软件工程经济学。计算基础。数学基础。工程基础

软件工程存在于各种应用中,存在于软件开发的各个方面。而程序设计通常包含了程序设计和编码的反复迭代的过程,它是软件开发的一个阶段。

软件工程力图对软件项目的各个方面作出指导,从软件的可行性分析直到软件完成以后的维护工作。

软件工程是建立在计算机科学基础上的学科。
•计算机科学:“做的出”
•软件工程:“做的好”、“做的快”


没有银弹

思考软件工程中的根本和次要问题。

根本任务(essential)——打造由抽象软件实体构成的复杂概念结构。
次要任务(accidental)——使用编程语言表达这些抽象实体,在空间和时间限制内将它们映射成机器语言。
除非次要任务占了所有工作的9/10,否则即使全部次要任务的时间缩减到零,也不会给生产率带来数量级上的提高。

软件项目 -- 常常看似简单明了的东西,却有可能变成一个落后进度、超出预算、存在大量缺陷的怪物。

为什么软件的发展比硬件慢?
不是软件发展慢,而是硬件发展太快。“从人类文明开始,没有任何其他产业技术的性价比,能在30年之内取得6个数量级的提高,也没有任何一个产业可以在性能提高或者降低成本方面取得如此的进步。这些进步来自计算机制造产业的转变,从装配工业转变成流水线工业。”

亚里士多德的观点,将软件开发的问题分成根本的(essence)——软件特性中固有的困难,次要的(accident)——出现在目前生产上的,但并非那些与生俱来的困难。

一个相互牵制关联的概念结构,是软件实体必不可少的部分,它包括:数据集合、数据条目之间的关系、算法、功能调用等等。这些要素本身是抽象的,体现在相同的概念构架中,可以存在不同的表现形式。尽管如此,它仍然是内容丰富和高度精确的。

我认为软件开发中困难的部分是规格化、设计和测试这些概念上的结构,而不是对概念进行表达和对实现逼真程度进行验证。

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

复杂度

(1)软件实体可能比任何由人类创造的其他实体都要复杂,因为没有任何两个软件部分是相同的,如果有我们会将它们合并。
(2)数字计算机本身就比人类建造的大多数东西复杂。计算机拥有大量的状态,这使得构思、描述和测试都非常困难。软件系统的状态又比计算机系统状态多若干个数量级。

(3)软件实体的扩展也不仅仅是相同元素重复添加,而必须是不同元素实体的添加。整个软件的复杂度以很大的非线性级数增长。

(4)软件的复杂度是必要属性,不是次要因素。抽掉复杂度的软件实体描述常常也去掉了一些本质属性。

复杂度问题造成软件产品开发问题团队。成员之间的沟通非常困难,导致了产品瑕疵、成本超支和进度延迟由于复杂度,列举和理解所有可能的状态十分困难,影响了产品的可靠性。

由于函数的复杂度,函数调用变得困难,导致程序难以使用。由于结构性复杂度,程序难以在不产生副作用的情况下用新函数扩充。由于结构性复杂度,造成很多安全机制状态上的不可见性

复杂度引发管理上的问题。全面理解问题变得困难,从而妨碍了概念上的完整性。它使所有离散出口难以寻找和控制。它引起了大量学习和理解上的负担,使开发慢慢演变成了一场灾难—信息隐藏原则

一致性

软件开发面对的复杂度往往是随心所欲、毫无规则可言的,来自若干必须遵循的人为惯例和系统。软件开发面对的是人,不是上帝。 很多复杂性来自保持与其他接口的一致。

可变性

软件实体经常会遭受到持续的变更压力。
• 汽车、建筑可以修改,但很少有人修改,大家都知道成本很高。
• 软件包含了很多功能。
• 软件可以很容易地进行修改——它是纯粹思维活动的产物,可以无限扩展。

•软件的变更
• 人们要求扩展,更改功能
• 硬件的变化
• 软件与整个社会联成一体,后者在不断变动,它强迫软件也跟着变动。

不可见性

软件是不可见的和无法可视化的。抽象的功能:几何抽象、机械制图、化学分子模型。帮助我们捕获物理存在的几何特性。软件的客观存在不具有空间的形体特征。现在没有任何一种2维、3维的图形可以描述软件。 这限制了个人的设计过程,也严重的阻碍了相互之间的交流。
• UML

一些当年的银弹

• Ada和其他高级编程语:它通过使用更加抽象的语句来开发,降低了机器的次要复杂度。
• 面向对象编程:它们的出现都消除了开发过程中的非本质困难,允许设计人员表达自己设计的内在特性,而不需要表达大量句法上的内容。对于抽象数据类型和层次化类型,它们都是解决了高级别的次要困难和允许采用较高层次的表现形式来表达设计。使得修改局部化,提高了可维护性
• 人工智能:现在有两种差异非常大的AI定义被广泛使用。AI-1:使用计算机来解决以前只能通过人类智慧解决的问题。AI-2:使用启发式和基于规则的特定编程技术。在这种方法中,对人类专家进行研究,判断他们解决方法的启发性思维或者经验法则⋯⋯。程序被设计成以人类解决问题的方式来运作。
• 专家系统:专家系统是包含归纳推论引擎和规则基础的程序,它接收输入数据和假设条件,通过从基础规则推导逻辑结果,提出结论和建议,向用户展示前因后果,并解释最终的结果。推论引擎除了处理推理逻辑以外,通常还包括复杂逻辑或者概率数据和规则。专家系统最强有力的贡献是给缺乏经验的开发人员提供服务,用最优秀开发者的经验和知识积累为他们提供了指导。

• “自动”编程:人们一直在预言和编写有关“自动编程”的文字,从问题的一段
陈述说明自动产生解决问题的程序。大多数情况下所给出的技术说明本质上是问题的解决方法,而不是问题自身。
• 图形化编程:流程图是一种非常差劲软件结构表达方法。现在的屏幕非常小,像素级别,无法同时表现软件图形的所有正式、详细的范围和细节。软件非常难以可视化。
• 程序验证:是否有可能出现银弹,能够在系统设计级别、源代码级别消除bug呢?是否可以在大量工作被投入到实现和测试之前,通过采用证实设计正确性的“深奥”策略,彻底提高软件的生产率和产品的可靠性?不能保证节约劳动力。程序验证不意味着零缺陷的程序。 完美的程序验证只能建立满足技术说明的程序,而这时,软件工作中最困难的部分已经接近完成,形成了完整和一致的说明。
• 环境和工具:IDE这样的工作是非常有价值的,它能带来软件生产率和可靠性上的一些提高但是,由于它自身的特性,目前它的回报很有限。
• 工作站:硬件速度的加快。 编译速度,开发速度。
• 购买和自行开发:构建软件最可能的彻底解决方案是不开发任何软件。通用软件。
• 需求精炼和快速原型:概念性工作中,没有其他任何一个部分比确定详细的技术需求更加困难。事实上,客户不知道自己需要什么。快速原型明确实际的概念结构,让用户知道他们需要什么。
• 增量开发——增长,而非搭建系统,迭代式开发。
• 卓越的设计人员:软件开发是一个创造性的过程。

没有银弹的影响:

软件开发本质的认识,软件过程。


软件工程管理 第一讲 概述

软件自身的变化

规模,比例

软件工程的核心问题

软件工程的管理视角:“成功是否可以复制?”

软件过程:软件过程是为了实现一个或者多个事先定义的目标而建立起来的一组实践的集合这组实践之间往往有一定的先后顺序,作为一个整体来实现事先定义的一个或者多个目标。

生命周期模型:对软件过程的一种人为的划分。

软件工程的技术视角:“问题是否可以解决得更好?”

软件项目管理概念

管理的三大关键要素:目标、状态、纠偏

软件项目管理:典型的三大目标:成本、质量、工期

软件项目管理是应用方法、工具、技术以及人员能力来完成软件项目,实现项目目标的过程。 估算、计划、跟踪、风险管理、范围管理、人员管理、沟通管理,等等

广义软件过程

理论基石:软件产品和服务的质量,很大程度上取决于生产和维护该软件或者服务的过程的质量。广义软件过程包括技术人员以及狭义过程

广义软件过程的同义词:软件开发方法、软件开发过程,净室Cleanroom方法、极限编程方法、SCRUM方法、Gate方法;而更一般的,敏捷软件过程/方法、轻量型过程/方法以及重型过程/方法等描述也是恰当的。

生命周期模型与软件过程

区别和联系:生命周期模型是对一个软件开发过程的人为划分;生命周期模型是软件开发过程的主框架,是对软件开发过程的一种粗粒度划分;生命周期模型往往不包括技术实践

典型生命周期模型:瀑布模型、迭代式模型、增量模型、螺旋模型、原型法等等

软件过程管理

管理对象是软件过程

管理的目的是为了让软件过程在开发效率、质量等方面有着更好性能绩效(performance)

软件项目管理(SCRUM,XP)-----产品生产管理

软件过程管理(CMMI,SPICE)----流水线的设计、建设、维护、优化以及升级改造

软件过程管理与软件过程改进

两者意思接近:软件过程管理参考模型 CMM/CMMI, SPICE等;软件过程改进参考模型 PDCA,IDEAL


软件工程与管理 第二讲 软件过程的历史演变和经典工作

软件开发有很多困难,但是本质难题是:不可见性。复杂性。可变性。一致性。

进一步分析:三个本质难题因项目而异,四大本质难题相互促进,本质难题变化带动软件方法(过程)演变。

软件发展三大阶段

软硬件一体化阶段(50年代~70年代):

软件完全依附于硬件

​ 软件应用典型特征:软件支持硬件完成计算任务,功能单一,复杂度有限,几乎不需要需求变更

​ 软件开发典型特征:硬件太贵,团队以硬件工程师和数学家为主

​ Measure twice, cut once

软件作坊:

​ 软件应用典型特征:功能简单,规模小。

​ 软件开发典型特征:很多非专业领域的人员涌入软件开发领域,高级程序语言出现,质疑权威文化盛行。

​ Code and fix不适合大型软件项目开发!

软件成为独立的产品(70年代~90年代)

​ 软件应用特征:摆脱了硬件束缚(OS),功能强大,规模和复杂度剧增,个人电脑出现—》普通人成为软件用户(需求多变,兼容性要求),来自市场的压力。

​ 典型软件过程和实践:方法之一:形式化方法;方法之二:结构化程序设计和瀑布模型,成熟度模型

​ 问题和不足(效率和质量):形式化在扩展性和可用性方面存在不足;瀑布模型成为一个重文档,慢节奏的过程。

网络化和服务化(90年代中期迄今)

​ 软件应用特征:功能更复杂,规模更大;用户数量急剧增加(这会带来什么问题?);快速演化和需求不确定;分发方式的变化(SaaS)。

​ 典型软件过程和实践:

​ 迭代式:大型软件系统的开发过程也是一个逐步学习和交流的过程;软件系统的交付不是一次完成,而是通过多个迭代周期,逐步来完成交付。

​ 雪鸟会议和敏捷宣言:个体和互动胜过流程和工具;可以工作的软件胜过详尽的文档;客户合作胜过合同谈判;响应变化胜过遵循计划。也就是说,尽管右项有其价值,我们更重视左项的价值。

​ XP(eXtreme Programming) 方法:偏重于一些工程实践的描述。

​ SCRUM:管理框架和管理实践。

​ Kanban:精益生产(丰田制造法)的具体实现;可视化工作流、限定WIP、管理周期时间 。

​ 开源软件开发方法:是一种基于并行开发模式的软件开发的组织与管理方式

​ “Linus定律”:“如果有足够多的beta测试者和合作开发者,几乎所有问题都会很快显现,然后自然有人会把它解决。”*

​ “早发布,常发布,倾听用户的反馈 ”、“把你的用户当成开发合作者对待,如果想让代码质量快速提升并有效排错,这是最省心的途径”、“设计上的完美不是没有东西可以再加,而是没有东西可以再减”

​ 代码管理:严格的代码提交社区审核制度

​ 内部开源(inner source)

​ 众包(Crowdsourcing)


表征软件过程

国防部于1984年在卡内基梅隆大学成立了软件工程学院,以建立卓越的软件工程标准,并加速先进技术和方法向实践的过渡。结果就是形成了软件过程成熟度框架,任何软件组织都可以使用该框架来评估其自身的能力并确定最重要的改进领域。

软件过程idea:首先,这是可预测的:以合理的一致性满足成本估算和进度承诺,并且最终产品的质量通常可以满足用户需求。

统计控制:

当且仅当在该过程中进行的度量与该过程的模型所预测的度量足够接近时,该过程才处于统计控制。

软件过程管理的基本原理是,如果开发过程处于统计控制之下,则只有改进过程才能始终获得更好的结果。 当一个过程处于统计控制之下时,以大致相同的方式重复工作将产生大致相同的结果。

测量:

统计控制的基本原理是测量。将测量范围限制为仅会实际使用的少量项目也很重要。测量既昂贵又破坏性。

开发过程改进:

解决软件问题的重要第一步是将整个开发任务视为可以控制,度量和改进的过程。我们将流程定义为一系列任务,这些任务在正确执行后会产生预期的结果。

要提高软件功能

1.了解其开发过程或过程的当前状态,

2.对所需过程的愿景,

3.按优先顺序建立所需过程改进措施的清单,

4.制定完成这些措施的计划,

5.投入资源执行计划。

过程成熟度模型

初始。

在流程受到统计控制之前,流程改进不可能有条不紊地进行。

最初的流程可以适当地称为临时流程,而且通常甚至很混乱。 组织的运作通常没有正式的程序,成本估算和项目计划。 工具既没有很好地与流程集成在一起,也没有得到统一的应用。 变更控制不严格,高层管理人员很少接触或了解问题。 由于问题常常被推迟甚至被遗忘,因此软件的安装和维护经常会带来严重的问题。

事例:

这样的组织在危机中的表现。如果放弃既定的程序,而仅返回编码和测试,则可能处于初始过程级别。 如果技术和方法适当,则必须在危机中使用;如果技术和方法不合适,则根本不要使用。

组织行为混乱的原因之一是他们没有获得足够的经验来理解这种行为的后果。

改善过程:

项目管理。 项目管理系统的基本作用是确保对承诺的有效控制。这需要充分的准备,明确的责任和公开声明。

管理监督。纪律严明的软件开发组织必须具有高级管理人员的监督。这包括在正式承诺之前对所有主要发展计划进行审查和批准。

质量保证。 一个质量保证小组负责确保管理人员按照预期的方式实际完成了软件开发工作。 为了保证有效性,保证组织必须有独立的高级管理人员报告线,并有足够的资源来监视所有关键计划,实施和验证活动的绩效。 这通常要求组织的规模约为开发组织的5%至6%。

变更控制。 控制软件开发变更对于业务和财务控制以及技术稳定性至关重要。 为了按可预测的时间表开发高质量的软件,必须在整个开发周期内建立并维护需求,并使之保持合理的稳定性。 必须进行更改,但是必须有序地进行管理和引入。

可重复。

通过对承诺,成本,进度和变更进行严格的项目管理,组织已实现了稳定的过程并具有可重复的统计控制级别。

与初始过程相比,可重复过程具有一项重要优势:它提供承诺控制。 与初始流程相比,这是一个巨大的进步,组织中的人们倾向于认为他们已经掌握了软件问题。 可重复流程级别的组织面临新的挑战时将面临重大风险

挑战

新的工具和方法可能会影响流程的执行方式,从而破坏组织所依赖的直观历史基础的相关性。

当组织必须开发一种新产品时,它正在进入新的领域。 例如,如果一个具有丰富的编译器开发经验的软件小组被指派编写控制程序,则可能会遇到设计,调度和估计方面的问题。

重大的组织变革可能会造成极大的破坏。在“可重复过程”组织中,新经理没有井井有条的基础来了解正在发生的事情,新团队成员必须通过口口相传来学习。

改善过程:

1.建立一个过程组。 流程组是专门致力于改善软件开发流程的技术组。 流程组的职责包括定义开发流程,确定技术需求和机会以及对流程状态和性能进行季度管理审查。

2.建立一个软件开发过程架构,描述正确执行开发过程所需的技术和管理活动。架构是将开发周期分解为任务的结构。 分解将继续,直到每个定义的任务由单个或单个管理单元执行。

3.如果尚未安装,请介绍一系列软件工程方法和技术。 这些包括设计和代码检查,正式设计方法,库控制系统和综合测试方法。 在采用现代实现语言的同时,还应考虑原型设计。

已定义。

组织已经定义了流程,以确保一致的实施并为更好地理解流程提供基础。此时,可以有用地引入先进技术。

借助“定义的过程”,组织已为重大且持续的进步奠定了基础。 例如,开发小组在遇到危机时可能会继续使用“定义的过程”。

改善过程:

定义的过程仍然只是定性的:几乎没有数据表明过程正在进行或过程真正有效。 关于软件过程测量的价值和最佳使用方法的争论很多。

1.建立最小的基本过程测量集,以识别每个过程步骤的质量和成本参数。 目的是量化每个主要过程活动的相对成本和收益,例如错误检测和纠正方法的成本和收益。

2.用资源来管理和维护过程数据库。 应集中维护成本和产量数据,以防止损失,并促进过程质量和生产率分析。

3.提供足够的过程资源来收集和维护此数据,并就其使用向项目成员提供建议。 指派熟练的专业人员来监视数据质量,然后再输入数据库,并提供有关分析方法和解释的指导。

4.评估每种产品的相对质量,并在未达到质量目标的情况下通知管理层。 独立的质量保证小组应评估每个项目的质量措施,并根据其质量计划跟踪其进度。 将这一进展与类似项目的历史经验进行比较,通常可以进行非正式评估。

管理。

除成本和进度绩效外,该组织已启动了全面的过程度量。这是最重要的质量改进开始的时候。最大的潜在问题是收集数据的成本。收集和维护数据非常昂贵。

谨慎处理数据收集并事先精确定义每个数据。除非明确定义,否则生产力数据通常毫无意义。 新代码或更改的代码。非注释,非空行,可执行指令或等效的汇编程序指令。 如何衡量管理,测试,文档和支持人员。

测量数据的趋势是使用它来比较几个组,并对排名最低的组施加压力。这是过程数据的错误应用。 首先,很少有两个项目可以通过任何简单的方法进行比较。由不同产品类型引起的任务复杂性差异可能超过五比一。

过程数据不得用于比较项目或个人。其目的是照亮正在开发的产品,并为改进过程提供信息基础。 管理层将此类数据用于评估个人或团队时,数据本身的可靠性将下降。很少有人可以依靠自己的表现提供可靠的数据。

从管理过程到优化过程:

1.支持自动收集过程数据。有些数据无法手工收集,所有手动收集的数据都会出错和遗漏。

2.使用该数据来分析和修改过程,以防止出现问题并提高效率。

优化。

该组织现在为持续改进和优化流程奠定了基础。到目前为止,软件开发经理主要专注于他们的产品,通常只会收集和分析与产品改进直接相关的数据。 在“优化过程”中,可以使用数据实际调整过程本身。

为了减少清除错误的成本,应强调检查以及其他任何具有成本效益的技术。 然后应将功能测试和系统测试的角色更改为寻找症状之一,然后进一步探讨该症状是否是一个孤立的问题,或者它表明需要更全面分析的设计问题。

优化过程以多种方式提供帮助:帮助管理人员了解在何处需要帮助以及如何最好地为人们提供所需的支持。 让专业人士以简洁,定量的方式进行交流。 为专业人士提供框架,使他们了解他们的工作绩效并了解如何提高绩效。

为什么只有5个阶段?

合理地代表实际软件组织的演进改进的实际历史阶段;代表从上一个级别可以合理实现的改进措施;提出临时改进目标和进度措施;明确列出一组立即改进的重点,一旦知道组织在此框架中的地位。


软件工程与管理 过程裁剪、融合和定制

软件过程“One fits all”是不存的,一个合适的软件过程往往需要将多个不同类型的软件过程的优势整合起来。

三大流派

天然的组合:XP+SCRUMPSP+TSP

极限编程(eXtreme Programming)是敏捷过程中最负盛名的一个,其名称“极限”二字的含义是指把好的开发实践运用到极致。

极限编程的有效实践

​ 客户作为开发团队的成员——客户代表

​ 使用用户素材

​ 短交付周期

​ 验收测试

​ 结对编程——结对编程就是由两名开发人员在同一台计算机上共同编写解决同一个问题的程序代码,通常一个人编码,另一个人对代码进行审查与测试,以保证代码的正确性与可读性。结对编程是加强开发人员相互沟通与评审的一种方式。

​ 测试驱动开发——极限编程强调“测试先行”。在编码之前,应该首先设计好测试方案,然后再编程,直至所有测试都获得通过之后才可以结束工作。
​ 集体所有
​ 持续集成
​ 可持续的开发速度 <=40h/week
​ 开放的工作空间
​ 重构
​ 使用隐喻

Scrum

Scrum是一种迭代式增量软件开发过程,通常用于敏捷软件开发。

•虽然Scrum是为管理软件开发项目而开发的,它同样可以用于运行软件维护团队。

PSP/TSP

PSP/TSP都是由美国卡内基.梅隆大学软件工程研究所(SEI)的Humphrey等人设计和开发。PSP着重于软件开发人员的个人能力提升,体现在估算能力、计划能力、计划执行以及质量管理等方面。
TSP能够提供了
①一个已经定义的团队构建过程;
②一个团队作业框架;
③一个有效的管理环境。

平衡敏捷和规范

如果只有强有力的规范而缺乏敏捷,将导致官僚作风,进而停滞不前;
缺乏规范的敏捷则如同一个新创公司在盈利之前的不负责任的狂热。
敏捷过程与规范过程各有自己的特点和优点,在本质上和在实际项目中,敏捷与规范是可以平衡的.
Boehm等在《Balancing Agility and Discipline :A Guide for the Perplexed》一书中详细总结了敏捷与规范两种方法各自的擅长领域,并给出了基于风险分析平衡敏捷与规范的策略,而平衡的策略可以综合两种方法的优点。影响敏捷与规范方法选择的五个维度(动态性、危险性、规模、人员和文化)。

敏捷与规范,软件开发中看似对立的两个属性,实际上相得益彰。
计划驱动的开发人员必须敏捷,敏捷开发人员必须规范。成功的关键在于找到两者的平衡点。
这个平衡点随项目所处的环境以及所涉及的风险而变化。仅凭一腔热情径直地采用极端方法的开发人员,必须学会如何根据实际情况恰当地平衡敏捷与规范。

找影响软件过程组合、裁剪和定制的项目上下文(context)特征

Rational统一过程(Rational Unified Process,RUP)是由Rational软件公司提出的一种完整而且完美的软件过程。
RUP最佳实践
(1)迭代式开发
(2)管理需求
(3)使用基于构件的体系结构
(4)可视化建模
(5)验证软件质量
(6)控制软件变更

RUP软件开发生命周期
工作阶段
初始阶段:建立业务模型,定义最终产品视图,并且确定项目的范围。
精化阶段:设计并确定系统的体系结构,制定项目计划,确定资源需求。
构建阶段:开发出所有构件和应用程序,把它们集成为客户需要的产品,并且详尽地测试所有功能。
移交阶段:把开发的产品提交给用户使用。
RUP迭代式开发

水晶方法,Crystal ,是由 Alistair Cockburn 和 Jim Highsmith 建立的敏捷方法系列
Crystal 家族实际上是一组经过证明、对不同类型项目非常有效的敏捷过程,它的发明使得敏捷团队可以根据其项目和环境选择最合适的 Crystal 家族成员
分为Crystal Clear, Crystal Yellow, Crystal Orange和Crystal Red分别适用于不同的项目

•过程实践(practice) VS. 过程框架(framework)

​ 一个可以工作的软件过程应当既提供整体观(即过程框架),让过程使用者(即工程师)形成统一的项目愿景;同时,也应该提供非常具体的实践指南,让过程使用者知道该如何完成每一项关键任务 。

•团队(team) VS. 个人(individual)

​ 即便软件项目的开发是以团队形式进行,在整个过程中大部分的工作都是软件工程师以个人工作的方式进行的 。因此,软件过程应该同时覆盖团队和个人。

•反应式(reactive) VS. 前摄式(proactive)

软件开发尤其是现代软件开发面临着很多不确定性,提升应变能力(reactive)是非常有必要的。尽管如此,从控制风险,提升质量,降低返工成本等因素出发,软件过程仍然应该引入更多具有前摄(proactive)特性的过程元素。在不确定中找确定性因素,并进而强化确定性,消除不确定性应该是一种基本策略 。

实践/过程特征描述

我们可以用一个三元组来描述软件过程。
定义 1. 一个软件过程是一个三元组: SP = (G,L,C),其中:
G = {Framework, Practice}
L = {Team, Individual}
C = {Reactive, Proactive}

XP (Practice,Team,Reactive)
TSP (Framework,Team,Proactive)


理性的设计过程:如何以及为何要伪造它

为什么要进行理性的设计过程

一个完全理性的人是一个总是对自己的工作有充分理由的人。可以证明,采取的每个步骤都是达到明确目标的最佳方法。

但是,对于许多观察者来说,通常的软件设计过程似乎很不合理。

我们许多人对这样的设计过程不满意(程序员开始时并没有明确说明所需的行为和实现约束。 他们做出了一系列长久的设计决策,但没有明确说明为什么以这种方式做事。 他们的基本原理很少得到解释。)。 这就是为什么要进行软件设计,编程方法,结构化编程和相关主题的研究。 理想情况下,我们希望从要求的陈述中得出程序,就像定理是从已发表的证明中的公理中得出一样。 所有可以被认为是“自上而下”的方法是我们渴望拥有一种理性,系统的软件设计方法的结果。

好坏消息

坏消息是,我们认为,我们永远找不到哲学家的石头。 我们永远找不到能够以完全合理的方式设计软件的过程。

好消息是我们可以伪造它。 我们可以向其他人展示我们的系统,就像我们曾经是理性的设计师一样,并且在开发和维护期间假装这样做是值得的。

为何软件设计过程总是理想化?

我们将永远不会看到以“理性”方式进行的软件项目。以下列出了一些原因:(1)在大多数情况下,负责构建软件系统的人员并不确切知道他们想要什么,也无法告诉我们他们所知道的一切。 (2)即使我们知道要求,但在设计软件时还需要了解许多其他事实。随着我们在实施过程中的进展,许多细节只有我们知道。我们学到的一些东西会使我们的设计无效,我们必须回溯。(3)即使我们在开始之前就了解所有相关事实,经验也表明,人类无法完全理解设计和构建正确系统所必须考虑的细节。 设计软件的过程就是我们试图分离问题的过程,以便我们处理可管理的信息量。但是,除非我们分开关注点,否则我们肯定会犯错误。 (4)即使我们能够掌握所需的所有细节,但除最琐碎的项目外,所有其他项目都可能由于外部原因而发生变化。其中一些更改可能会使先前的设计决策无效。最终的设计不是通过合理的设计过程来完成的。(5)只有避免有人使用,才能避免人为错误。即使关注点分离之后,也会出错。 (6)我们常常会受制于先入为主的设计思想,我们发明的思想,在相关项目中获得的思想或在课堂上听说过的思想。有时我们会进行项目以尝试或使用喜欢的想法。这些想法可能不是通过合理的过程从我们的要求中得出的。(7)通常出于经济原因,我们被鼓励使用为其他项目开发的软件。在其他情况下,我们可能被鼓励与正在进行的另一个项目共享我们的软件。生成的软件可能不是任何一个项目的理想软件,即不是我们仅根据其需求开发的软件,但它足够好并且可以节省工作量。

由于所有这些原因,软件设计人员从需求说明中以合理,无错误的方式得出其设计的图景是不现实的。 从来没有以这种方式开发过系统,而且可能永远也不会。 甚至教科书和论文中显示的小程序开发都是不现实的。对它们进行了修改和完善,直到作者向我们展示他希望自己做的事情,而不是向我们展示实际发生的事情。

为何要对理性的理想化过程进行描述

如果我们已经确定了理想的过程但不能完全遵循,那么我们仍然可以尽可能地严格遵循它,并且可以编写如果遵循理想的过程将会产生的文档。这就是我们所说的“伪造理性的设计过程”。

这样的假装的原因:(1)设计师需要指导。当我们进行一个大型项目时,我们很容易被任务的艰巨所淹没。我们不确定首先要做什么。对理想过程的充分理解将有助于我们知道如何进行。 (2)如果我们尝试遵循流程而不是临时进行,我们将更接近合理的设计。 例如,即使我们不知道设计理想系统所需的所有事实,但在开始编写代码之前发现这些事实的工作也将有助于我们更好地设计并减少回溯。(3)当一个组织从事许多软件项目时,采用标准程序是有好处的。 这样可以轻松进行良好的设计审查,将人员,想法和软件从一个项目转移到另一个项目。如果我们要指定一个标准流程,那应该是一个合理的流程是合理的。(4)如果我们就理想的过程达成了一致,那么衡量项目的进度将变得更加容易。 我们可以将项目的成就与理想流程要求的成就进行比较。我们可以确定我们落后(或领先)的区域。 (5)外部人员对项目进度的定期审查对于良好的管理至关重要。如果项目尝试遵循标准流程,则将更易于审核。

理性的设计过程是什么?

A.建立并记录需求。

如果我们要成为理性的设计师,我们必须开始知道为成功必须要做的事情。该信息应记录在称为需求文档的工作产品中。在开始之前完成本文档将使我们能够设计出摆在我们面前的所有要求(1)我们需要一个地方来录用户向我们描述的系统的期望行为;我们需要用户或其代表可以查看的文档。 (2)我们希望避免在设计程序时意外地做出需求决策。 在系统上工作的程序员通常对应用程序不熟悉。对外部可见行为有完整的参考可以使他们无需再决定最适合用户的行为。 (3)我们要避免重复和不一致。 没有需求文档,设计人员,程序员和审阅者在整个开发过程中都会反复询问它回答的许多问题。这将很昂贵,并且通常会导致答案不一致。(4)完整(但不充分)的需求文档对于正确估算构建系统所需的工作量和其他资源是必要的。 (5)需求文件是防止人员流动成本的宝贵保险。当有人离开项目时,我们获得的关于需求的知识不会丢失。 (6)需求文件为测试计划的制定提供了良好的基础。没有它,我们不知道要测试什么。(7)长期使用系统后,可以使用需求文档来定义将来更改的约束。 (8)需求文档可用于解决程序员之间的争论;一旦有了完整且准确的需求文档,我们就不再需要或咨询需求专家。 因为确定详细的需求可能是软件设计过程中最困难的部分,因为通常没有组织良好的信息源。

理想需求文档的定义很简单:应该包含编写客户可以接受的软件所需的所有知识,并且仅此而已。(1)每项声明对所有可接受的产品均有效;没有人应该依赖于实施决策。 (2)从某种意义上说,文件应是完整的,只要产品满足每个声明,就应该可以接受。 (3)在必须开始开发之前无法获得信息的地方,应明确指出不完整的领域。 (4)产品应组织为参考文件,而不是有关系统的介绍性叙述。 尽管制作此类文档需要花费大量精力,并且参考文献比简介更难以浏览,但从长远来看,它可以节省人工。 在此阶段获得的信息将以易于在整个项目中参考的形式记录。

理想情况下,需求文档应由用户或其代表编写。 实际上,用户很少具备编写此类文档的能力。取而代之的是,软件开发人员必须生成文档草稿并对其进行审查,并最终由用户代表批准。

需求文档组织:

(1)计算机规格:必须在其上运行软件的计算机的规格。 (2)输入/输出接口:软件为了与外界通信而必须使用的接口的规范; (3)输出值的规范:对于每个输出,根据系统环境的状态和历史来指定其值; (4)时序约束:对于每个输出,需要软件多长时间或多长时间重新计算一次; (5)精度约束:对于每个输出,要求其精度。 (6)可能的更改:如果要求系统易于更改,则要求应包含对可能更改的区域的定义。 (7)不良事件处理。

B.设计并记录模块结构

除非产品足够小,能由一个程序员生产,否则必须考虑如何将工作分为工作分配,我们称其为模块。 模块指南应具有树形结构,将系统分为少量模块,并以相同方式处理每个这样的模块,直到所有模块都非常小。

C.设计和记录模块接口

高效且快速的软件生产要求程序员能够独立工作。 模块指南定义了责任,但没有提供足够的信息以允许独立实施。 必须为每个模块编写模块接口规范。它必须是正式的,并提供每个模块的黑匣子图片。

D.设计和记录使用层次

一旦我们知道所有模块及其访问程序,就可以设计“使用”层次。 “使用”层次结构定义了可以通过删除整个程序而无需重写任何程序而获得的子集集。

E.设计并记录模块内部结构
F.编写程序
G.维护

如果进行了更改,则必须更改所有无效的文档。

如果更改使外观设计文件无效,则必须伪造该外观设计文件和所有后续设计文件,以使外观看起来像更改是原始设计。

伪造理想过程

本文描述了我们希望遵循的理想过程以及在该过程中产生的文档。 如果我们以理想的方式完成工作,就会产生我们会产生的文件,从而“伪造”了该过程。如果发现错误,则必须纠正它们,并且必须在后续文档中进行相应的更改。 文档是我们的设计媒介,在将其纳入文档之前,不会做出任何设计决策。 无论我们走多久,最终文件都是合理准确的。

成为一个理性的设计师是非常困难的。甚至伪造这个过程都非常困难。 但是,结果是可以理解,维护和重用的产品。


大教堂与市集-开放源代码软件

《大教堂与市集》(The Cathedral and the Bazaar)是埃里克·斯蒂芬·雷蒙(Eric Steven Raymond)所撰写的软件工程方法论。以Linux的核心开发过程以及作者自己主持开发的开放原代码软件──fetchmail为讨论案例。文章在1997年5月27日发表,并在1999年出版成书。

《大教堂和市集》第一次以大教堂模式和开放市集模式的比喻形象生动地将自由软件和商业封闭软件区分开来——“一种是封闭的、垂直的、集中式的开发模式,反映一种由权利关系所预先控制的极权制度;而另一种则是并行的、点对点的、动态的开发模式。”他在文中论证了自由软件不仅仅是一种乌托邦的理想,而是在开发模式上真正代表着“先进生产力”,代表着历史发展趋势的必然。
1998年2月3日,硅谷,“开放源代码(Open Source)”被正式提出,后来发展成为开源运动。雷蒙德成了领导这场运动的理论家和开放源代码促进会(Open Source Initiative)的主要创办人之一。

软件工程管理小结---Man看了会流泪_第1张图片

六种开源许可证:

LGPL,Mozilla,GPL,BSD,MIT,Apache

每个好的软件工作都开始于搔到了开发者本人的痒处。

好程序员知道该写什么,伟大的程序员知道该重写(和重用)什么。

“计划好抛弃,无论如何,你会的”你常常在第一次实现一个解决方案之后才能理解问题所在,第二次你也许才足够清楚怎样做好它,因此如果你想做好,准备好推翻重来至少一次。

如果你有正确的态度,有趣的问题会找上你的。

当你对一个程序失去兴趣时,你最后的责任就是把它传给一个能干的后继者。

把用户当做协作开发者是快速改进代码和高效调试的无可争辩的方式。

早发布、常发布、听取客户的建议。保持他的黑客用户经常受到激励和奖赏:被行动的自我满足的希望所激励,而奖赏则是经常(甚至每天)都看到工作在进步。

Linus定律:

•如果有一个足够大的beta测试人员和协作开发人员的基础,几乎所有的问题都可以被快速的找出并被一些人纠正。

​ -或者更不正式的讲:“如果有足够多的眼睛,所有的错误都是浅显的”(群众的眼睛是雪亮的),我把这称为“Linus定律”。

​ •Linus定律也可被表述为“排错可以并行”,尽管调试人员在排错时需要协调开发人员并与之交流,但调试人员之间并不怎么需要协调,也就是说,增加调试人员并不会带来增加开发人员那样的二次方复杂性和管理成本。

​ •理论上,并行排错会由于重复劳动导致效率损失,但从Linux世界的实践来看,这似乎从来不是一个问题。“早发布、常发布”策略的一个效果就是快速传播反馈回来的修复,从而使重复劳动最小化。

Delphi效应:

•社会学家在几年前已经发现一群相同专业的(或相同无知的)观察者的平均观点比在其中随机挑选一个来得更加可靠,他们称此为“Delhpi效应”,Linus所显示的证明在调试一个操作系统时它也适用——Delphi效应甚至可以战胜操作系统内核一级的复杂度。

Delphi估算法。

两种版本:Linux内核的版本在编号上做了些处理,让用户可以自己选择是运行上一个“稳定”的版本,还是冒遇到错误的险而得到新特征。

多少只眼睛才能驯服复杂性

•源码级bug报告

•理解这个问题的关键在于要弄清楚这个现象:如果报告bug的用户对源码不关心,则其报告通常不会很有用。对源码不关心的用户,往往报告的都是表面症状,他们把自己的运行环境当成是理所当然的,他们不仅省略了重要的背景数据,而且很少给出重现bug的可靠方法。

•只要能有一个对出错条件在源码级别上的提示性描述(即便不完整),大多数bug在大多数时间里就很容易被发现。

Brooks定律

在一个误了工期的软件项目中增加开发人员只会让它拖得更久,他声称项目的复杂度和通讯开销以开发人员的平方增长,而工作成绩只是以线性增长,这个说法被称为“Brooks定律”,被普遍当作真理,但如果Brooks定律就是全部,那Linux就不可能成功。(以及随之而来对开发团队规模的恐惧)建立在这样的假设上:项目的沟通结构是一个完全图,即人人之间都沟通。但在开源项目中,外围开发者实际工作在分散而并行的子任务上,他们之间几乎不交流;代码修改和bug报告都会流向核心团队,只有在那个小的核心团队里才会有Brooks开销。

•对于简单和容易重现的bug,重点要放在“半”而非“随机”上,此时,调试技能以及对代码和架构的熟悉程度会大显身手。

•对于复杂的bug,重点就要放在“随机”上了,这种情况下多人共同追踪bug远比少数几个人循序追踪要有效得多——即便这几个人的平均技能要高很多。

•聪明的数据结构和笨拙的代码要比相反的搭配工作的更好 (自己编程的认识)

•如果你象对待最宝贵的资源一样对待你的beta测试员,他们就会成为你最宝贵的资源。

• 想出好主意是好事,从你的用户那里发现好主意也是好事,有时候后者更好。

• 最重要和最有创新的解决方案常常来自于你认识到你对问题的概念是错误的。 (你在开发中碰壁了,头破血流,反省后才能得到最好的解决方案)

•“最好的设计不是再也没有什么东西可以添加了,而是再也没有什么东西可以去掉。”

•任何工具都应该能以预想的方式使用,但是一个伟大的工具提供你没料到的功能。

•当写任何种类的网关型程序时,多费点力,尽量少干扰数据流,永远不要抛弃信息,除非接收方强迫这么作!

•如果你的语言一点也不象是图灵完备的,严格的语法会有好处。 (rc file, control file syntax)

•一个安全系统只能和它的秘密一样安全,当心伪安全。

•不能以市集模式从头开发一个软件,我们可以以市集模式测试、调试和改进,但是以市集模式从头开始一个项目将是非常困难的 。

•我认为能够提出卓越的原始设计思想对协调人来说不是最关键的,但是对他/她来说绝对关键的是要能把从他人那里得到的好的设计重新组织起来。

•对市集项目来说,我认为还有另一种通常与软件开发无关的技能和设计能力同样重要——或者更加重要,市集项目的协调人或领导人必须有良好的人际和交流能力。

•要解决一个有趣的问题,请从发现让你感兴趣的问题开始。

集市模式,运用“无私编程”效果的充足能量,强有力地化解了Brooks定律的影响。Brooks定律背后的原理没有失效,但如果有一个大规模的开发群体和一个低成本的沟通机制,Brooks定律的效果将会被其他非线性因素带来的效果淹没,而后者是大教堂模式下看不到的。这很像是物理学上牛顿理论和爱因斯坦理论的关系——在低能量条件下,老的系统仍然有效,但如果把质量和速度推进到足够大的地步,你就会震惊于核爆炸或Linux。

•当编码在本质上仍然是个体行为时,真正了不起的作品来自于对整个社区注意力及脑力的有效利用。

•驱动力1.0:生存

•驱动力2.0:胡萝卜+大棒,简单重复性劳动

•驱动力3.0:自主、专精、目的,创造性劳动-(建立在基本收入得到保障的基础上)

•如果开发协调人员有至少和Internet一样好的媒介,而且知道怎样不通过强迫来领导,许多头脑将不可避免地比一个好。


开源软件经济学与互联网模式

很多高科技公司投入巨额资金发展开源软件,而通常开源软件本身免费。
Google: Android, Chrome, …
IBM: Eclipse
Intel: Linux
这些公司并不是放弃资本主义,而是认为这是个好的商业策略。

替代物品和互补物品

市场上所有的产品都有替代物品和互补物品。
替代物品是首选商品太贵时会改买的另一种东西。鸡肉就是牛肉的代替物品。如果你是鸡农而牛肉的价格上升,大家都要买更多鸡肉而你的销量就增加。
互补物品是通常会和其它产品一起购买的产品。车和汽油是互补物品。计算机硬件是典型的计算机操作系统互补物品。•当商品的价格下降时互补物品的需求就会增加。

•开放源码并不能免于经济法则。

•很多有责任尽量提升股东价值的大型上市公司,投入很多资金支 持开放源码软件(通常是负担大型程序团队的开发费用)。而这正可以用互补物的原理来解释。

当IBM设计PC架构时是用现成的零件而非订制零件,而且他们很小心地编写零件间的接口文件(革命性的作法)。为什么要这样做呢?因为这样子其它制造商就可以进来一起做。只要你遵循接口,就可以用在PC里。IBM的目标是要普及附加产品,而附加产品正是PC市场的互补物品。他们做得相当成功。在短时间内就涌现大量的公司提供内存卡、硬盘、显示卡、打印机等商品。便宜的附加产品意味更大的PC需求。

软件和硬件

软件是很容易让硬件普及化的(只要写个小小的硬件抽象层,比像Windows NT的HAL就只有很小一段程序),不过硬件想让软件普及化却是难上加难。

你可能感兴趣的:(研发管理,man看了会沉默,woman看了会流泪系列,面试,项目管理,软件工程师,软件过程)