【软件工程】

2021-08-18 16:05:33 浏览数 (1)

1.初识软件工程

1.1 软件的本质特性

定义 软件  =  程序   数据   文档  程序:计算机可以接受的一系列指令,运行时可以提供所要求的功能和性能。    数据:使得程序能够适当地操作信息的数据结构。  文档:描述程序的研制过程、方法和使用的图文资料

软件文档非常的重要,然而初学者往往不重视。

本质特性

  1. 复杂性
  2. 一致性
  3. 可变性
  4. 不可见性
  • 复杂性
  • 一致性
    1. 软件必须依附一定的运行环境
    2. 软件必须遵循一定的惯例并适应已有的技术和系统
    3. 软件需要随接口不同而改变,随时间推移而变化
  • 可变性
    1. 软件能够随着版本更新不断变化
    2. 然而,不断地修改可能导致软件的退化,从而结束其生命周期
  • 不可见性
    1. 软件是看不见摸不着的逻辑实体
    2. 源代码并不是软件本身
    3. 软件以机器码运行,但开发人员看不见机器码执行过程

软件所具有的复杂性、一致性、可变性、不可见性等特性,使得软件开发 过程变得难以控制,开发团队如同在焦油坑中挣扎的巨兽

1.2 软件工程历史

软件开发面临的挑战

软件工程发展历史概括如下: 史前时代 --> 瀑布流 --> 面向对象 --> 敏捷开发

1.3 软件工程基本概念

  • 工程
    1. 大规模的设计与建造
    2. 复杂问题与目标分解
    3. 团队协作与过程控制
  • 软件工程
    1. 系统性的、规范化的、可定量的方法应用于软件的开发、运行和维护, 即工程化应用到软件上
    2. 对1中所述方法的研究
    3. 要素
  • 软件工程过程:从用户需求 --> 软件开发活动 —> 用户满意的产品
    1. 软件开发活动
    1. 软件开发管理 软件项目管理计划、软件配置管理计划、软件质量保证计划、评审记录……
  • 软件工程方法(从大到小)
    1. 面向服务:在应用表现层次上将软件构件化,即应用业务过程由服务组成,而服务由构件组装而成。 
    2. 面向构件:寻求比类的粒度更大的且易于复用的构件, 期望实现软件的再工程。
    3. 面向对象:以类为基本程序单元,对象是类的实例化, 对象之间以消息传递为基本手段。
    4. 面向过程:以算法作为基本构造单元,强调自顶向下 的功能分解,将功能和数据进行一定程度的分离。

SASD:SA结构化分析,SA结构化设计,(SP结构化编程)(自顶向下,逐步求精,图形化建模,) OOD:Object-Oriented Design,面向对象设计时的一个中间环节,目标是解决程序内部各部分的依赖关系。 UML:面向对象统一建模语言 OMT:对象建模技术 J2EE:企业级分布式应用解决方案 DCOM:分布式组件对象模型,分布式组件对象模式,是一系列微软的概念和应用接口,通过这些接口,客户端程序对象能够请求来自网络中另一台计算机上的服务器程序对象 CORBA:Common ObjectRequest Broker Architecture公共对象请求代理体系结构;为解决分布式处理环境(DCE)中,硬件和软件系统的互连而提出的一种解决方案。 HTTP:是一个简单的请求-响应协议,它通常运行在TCP之上。 XML:结构化的、可扩展标记语言 OWL:网络本体语言(Web ontology language,OWL)是语义网技术的一个重要组成部分,适合于对复杂的数据进行语义描述和建模.在软件系统的开发过程中通常会产生大量结构复杂、语义丰富的数据,而建立一个灵活的语义模型是对各类软件工程数据进行统一管理的基础。 webServer三要素:

  1. UDDI:是一种用于描述、发现、集成Web Service的技术(规范),它是Web Service协议栈的一个重要部分。通过UDDI,企业可以根据自己的需要动态查找并使用Web服务,也可以将自己的Web服务动态地发布到UDDI注册中心,供其他用户使用。
  2. SOAP:简单对象访问协议是交换数据的一种协议规范,是一种轻量的、简单的、基于XML(标准通用标记语言下的一个子集)的协议,它被设计成在WEB上交换结构化的和固化的信息。
  3. WSDL:Web服务描述语言,Web Services Description Language,是为描述Web服务发布的XML格式。
  • 软件工程工具
  • 软件开发基本策略
    1. 软件复用 构造一个新的系统不必从零做起,直接复用已有的构件进行组装 构件是经过反复使用验证的,由其组成的新系统具有较高的质量  复用库函数、库类、模板、设计模式、组件、框架等。
    2. 分而治之 将一个复杂的问题分解成若干个简单的问题,然后逐个解决 来源于人们生活与工作的经验,完全适合于技术领域
    3. 逐步演进 软件开发是自底向上逐步有序的生长过程 小步快跑:每走完一步再调整并为下一步确定方向,直到终点  软件开发应该遵循软件的 客观规律,不断进行迭代式增量开发,最终交付符合客户价值的产品。 
    4. 优化折中 优化:优化软件的各个质量特性,如运行速度、资源利用、用户体验 折中:通过协调各个质量特性,实现整体质量的最优 
  • 软件工程学科发展

1.4 软件质量实现

软件质量可分为功能质量结构质量过程质量

正确的软件:为用户创建利润、减少成本 软件运行正确:没有或很少缺陷、可扩展、高性能、高易用

软件质量模型(ISO9126)

软件质量不是被测量出来的,而是在开发过程中逐步构建出来的; 但未经测试的也不可能开发出高质量软件; 质量是开发过程的问题测试是开发过程不可或缺的环节

软件的质量并非越高越好,绝大部分都是商用,应当平衡好成本质量效率之间的关系。

1.5 软件开发方法

结构化方法: 自顶向下、逐步求精;模块化;图形化;结构化分析;面向过程,专注结构;

面向对象方法: 一切皆对象,将数据和数据操作封装为对象,整个系统是一个对象的集合。 使用UML建模

函数式程序设计: 命令式编程:根据计算机的执行步骤来编写“命令” 声明式编程:告诉计算机应该做什么,但不指明如何去做。(如SQL) 函数式编程:

  • 不可变量:变量只是容器,x=x 1这种操作就是错误的(从数学的角度去看)
  • 纯函数:跟数学的函数一样,函数值(结果)只依赖于参数,而不被外部变量影响(不存在全局变量的说法,只能使用输入的参数),只要输入参数固定,无论外部如何变化,输出总是固定的。
  • 惰性计算
  • 无状态(宗旨)

面向构件的程序设计: 就是面向组件,以组件为单位的编程  面向服务的程序设计: 以“功能”(服务)为单元,使用统一的规范接口访问服务。以服务为单位进行编程。

2. 编写高质量代码

2.1 编码过程与规范

软件编程是一个复杂而迭代的过程,它不仅仅是编写代码,还应该包括代码审查单元测试代码优化集成调试等一系列工作。 

软件编码规范是与特定语言相关的描写如何编写代码的规则集合。 

  • 现实
    • 软件全生命周期的  70%  成本是维护
    • 软件在其生命周期中很少由原编写人员进行维护
  • 目的
    • 提高编码质量,避免不必要的程序错误
    • 增强程序代码的可读性、可重用性和可移植性

大家都遵循同一个代码规范,能够提高协同开发效率,降低维护成本。 此外,有很多规范能够减少前期开发给后期挖的坑。

2.2 良好的编程实践

可以通过,逐渐提高实践能力。 软件开发的工程思维:分析问题,分解大问题为小问题;解决小问题,合成过程,直至得到解决方案(分而治之);

高质量的设计:

  • 模块化设计
  • 面向对象编程
  • 错误和异常处理

模块化设计

常见的模块包括:函数、类、模块、包 模块化常见的问题就是:循环依赖,A依赖B,B依赖C,C依赖A;一定要避免这种问题。

2.3 代码静态检查

代码审查(Code Review)是一种用来确认方案设计和代码实现的质量保证机制,它通过阅读代码来检查源代码与编码规范的符合性以及代码的质量。 

代码审查的作用

  • 检查设计的合理性
  • 互为  Backup (备份)
  • 分享知识、设计、技术
  • 增加代码可读性
  • 处理代码中的“地雷区” 

缺陷检查表

2.4 代码性能分析

一些准则:

  1. 满足正确性、可靠性、健壮性、可读性
  2. 全局效率为主,局部效率为辅
  3. 优化效率时,应当先找出限制效率的瓶颈
  4. 时间和空间效率往往对立,先明确优化目标
  5. 从一开始就应该考虑程序性能,而不是等到开发结束后进行调整
  6. 认真选择测试数据
  7. 永远不要再没有进行前后性能评估的时候就尝试优化
  8. 掌握不同内置结构的迭代操作速度
  9. 从算法入手

常见算法时间复杂度: O(1) ==> O(lg n) ==> O(n lg n) ==> O(n^2) ==> O(n^3) ==> O(n^k) ==> O(k^n) ==> O(n!) 

2.5 结对编程

结对编程是由两名程序员在同一台电脑上结对编写解决同一问题的代码

结对编程不仅意味着编程活动,也包括分析、设计、测试等全程活动。 结对编程有助于按时完成项目,并且保证高质量的代码。

类似模型:

代码语言:javascript复制
驾驶员:负责用键盘编写程序 领航员:起到领航、提醒的作用 
 
两个人轮流驾驶,角色互换

结对编程的基础是会话和讨论, 不是一个人自得其乐。 口渴指数是核实伙伴交流程度的 一个考核标准。

  • 不要连续工作超过1个小时,每1个小时休息10分钟
  • 给同伴一点时间去发现和找到错误,别让他觉得你很烦
  • 常用的资料和规范(可以打印出来)以及书籍等应该放在手边
  • 结对开始之前要协调沟通,彼此互相通告希望对方关注些什么, 自己喜欢做什么
  • 主动参与,任何一个任务都是共同的责任,只有“我们的代码 
  • 坚持代码标准和流程规范 •  注意听取伙伴的意见

下面的一些情况不适合结对编程:

  • 处于探索阶段的项目
  • 后期维护的技术含量不高
  • 验证测试需要运行很长时间
  • 团队的人员要在多个项目中工作
  • 领航的用处不大

另外,也不是所有的人都适合结对编程。

3. 单元测试

3.1 单元测试概述

现实的开发问题: 经常把单元测试任务堆积到系统测试阶段,导致:

  • 大量故障堆积在项目中后期,项目后10% 的工作占用了项目 90%的时间。
  • 故障难以定位,而且 飘忽不定,开发和测 试人员疲于奔命。

单元测试(Unit Testing,UT)是对软件中的最小可测试单元进行检查和验证。

单元测试内容

单元测试原则

单元测试过程

单元测试质量

测试覆盖率可以查看本文章

单元测试方法 静态测试:人工分析 动态测试:程序调试 黑盒测试(功能测试):将测试对象看做一个黑盒子, 完全不考虑程序内部的逻辑结构和内部特性,只依据程序的需求规格说明书,检查程序的功能是否符合它的功能说明。 白盒测试(结构测试):把测试对象看做一个透明的盒子,允许测试人员利用程序内部的逻辑结构及有关信息,设计或选择测试用例, 对程序所有逻辑路径进行测试。

保证单元测试的独立性 一般来说,被测单元都不是独立的,其上有调用模块调用该单元,其下有依赖模块被该单元调用。 如下图:

因此,为保证单元测试的独立性,我们需要替换上层和下层的模块

举个例子,驱动模块用于输入测试用例,接收bool测试结果。 下层模块(桩模块),用一些可能的模拟数据,提供给被测模块。

xUnit(x表示不同语言) xUnit 通常适用于以下场景的测试

  • 单个函数、一个类或者几个功能相关类的测试
  • 尤其适用于纯函数测试或者接口级别的测试

xUnit 无法适用于复杂场景的测试

  • 被测对象依赖关系复杂,甚至无法简单创建出这个对象
  • 对于一些失败场景的测试
  • 被测对象中涉及多线程合作
  • 被测对象通过消息与外界交互的场景
  • 分布式

Mock测试 Mock测试是在测试过程中对于某些不容易构造或者不容易获取的对象,用一个 虚拟的对象(即Mock对象)来创建以便测试的方法。

  • 真实对象具有不可确定的行为(产生不可预测的结果)
  • 真实对象很难被创建(如具体的Web容器)
  • 真实对象的某些行为很难触发(如网络错误)
  • 真实情况令程序的运行速度很慢
  • 真实对象有用户界面
  • 测试需要询问真实对象它是如何被调用的
  • 真实对象实际上并不存在

关键:需要应用针对接口的编程技术,即被测试的代码通过接口来引用对象, 再使用Mock对象模拟所引用的对象及其行为,因此被测试模块并不知道它所引 用的究竟是真实对象还是Mock对象。 例一:现有程序是 classA调用classB实现功能,现在要测试classB,可以将classB抽象成接口,同时写一个实现该接口的Mock对象。此时通过接口调用,classA并不知道自己调用的是classB还是MOck对象。

例二:现有程序需要调用系统函数获得当前时间,如果使用普通测试,可能需要苦苦等到设定好的时间。通过mock对象,替换时间获取的方法,能够随心所欲的更改测试时间。

3.2 黑盒测试方法

良好的测试用例能够降低软件测试成本,保证测试工作质量,评估和检验测试效果。

测试用例的概念

测试用例的设计

  • 具有代表性和典型性
  • 寻求系统设计和功能设计的弱点
  • 既有正确输入也有错误或异常输入
  • 考虑用户实际的诸多使用场景

具体的实现方法请自己百度。

3.3 白盒测试方法

测试覆盖标准

  • 测试需求:测试的对象,是软件制品的一个特定元素,如源代码的一条语句、需求文档等
  • 覆盖标准:将测试需求施加在一个测试集上的一组规则,如:源代码的每条语句都要测试,这就是一个覆盖标准
  • 测试覆盖:对于每个测试需求,至少有一个测试用例,满足这个需求
  • 覆盖程度(覆盖率):完全测试是不现实的,一个测试集能够满足测试需求的比例。

覆盖标准的选择 软心糖豆:6 种口味和 4 种颜色 柠檬味(黄色)、开心果味(绿色)、梨子味(白色) 哈密瓜味(橙色)、橘子味(橙色)、杏味(黄色)

测试需求:口味、颜色 覆盖标准:

代码语言:javascript复制
颜色作为标准,即便颜色覆盖率为100%,也会有两种口味没有覆盖到
口味作为标准,口味和颜色都能满足覆盖率100%

即:口味这个标准,包含颜色这个标准。

实际开发中复杂的多,通常考虑以下因素:

  1. 处理测试需求的难易程度
  2. 生成测试的难以程度
  3. 用测试发现缺陷的能力

案例 有一台面包机,输入面粉和水,输出面包。 如果该面包机废弃多年,重新拿来使用需要进行测试。 黑盒测试(功能测试):放入面粉和水,看能不能生成面包。 这种办法显然不全面,不能知道面包机里面是否生锈、面包是否真的能吃。 白盒测试(结构测试):把面包机拆开,清洗锈迹,修理细节,然后再放入面粉和水,生成面包(黑盒测试)。

显然白 黑更好。

控制流图 控制流图(CFG, Control Flow Graph)是一个过程或程序的抽象表示。

控制流图的基本符号:

控制流图就是简化版的流程图,他的每一个节点,都是一段过程,简化方法:将顺序计算的所有语句合并为一个矩阵、将判断语句放入棱形,并引出真假分支、将判断结束后的汇聚点作为合并节点。

如下:

基于控制流的测试流程

基本路径测试 基本路径测试是在程序控制流图基础上,通过 分析控制构造的环路复杂性,导出基本可执行 路径集合,从而设计测试用例的方法。

计算环路复杂度的三种方法:

  1. 一个环为一个区域,加上最外层整体区域
  2. 边数-节点数 2
  3. 判断节点数 1

如:

确定独立路径 一条独立路径与其他独立路径相比,至少有一条新的边。 环路复杂度=独立路径数 独立路径选择方法:以每个分支节点为标准,向分支节点左右遍历 如:

基本路径测试

4. 软件开发过程

4.1 软件过程

过程:是一组将输入转化为输出的相互关联或相互作用的活动。

过程方法:系统地识别和管理组织内所使用的过程,保证更有效地获得期望的结果。

软件过程:

  • 问题定义:人们通过开展技术探索和市场调查等活动,研究系统的可行性和可能的解决方案,确定待开发系统的总体目标和范围。  问题提出 ⇒ 可行性研究 ⇒ 可行性分析报告
  • 需求开发:在可行性研究之后,分析、整理和提炼所收集到的用户需求,建立完整的 需求分析模型,编写软件需求规格说明。 
  • 软件设计:根据需求规格说明,确定软件体系结构,进一步设计每个系统部件的实现 算法、数据结构及其接口等。 
  • 软件构造:概括地说是将软件设计转换成程序代码,这是一个复杂而迭代的过程,要求 根据设计模型进行程序设计以及正确而高效地编写和测试代码。 
  • 软件测试:检查和验证所开发的系统是否符合客户期望,主要包括单元测试、子系统 测试、集成测试和验收测试等活动。 
  • 软件维护:系统投入使用后对其进行改进,以适应不断变化的需求。完全从头开发的 系统很少,将软件系统的开发和维护看成是一个连续过程更有意义。 

软件生命周期 计划阶段—产品构思、可行性分析、立项、组织计划 分析阶段—需求分析 设计阶段 设计阶段—总体设计和详细设计 开发阶段—编码集成测试 运行维护阶段–部署、发布、运维

软件开发管理

  • 软件项目管理是为了使软件项目能够按照预定的成本、进度、质量顺利完成,而对成本、 人员、进度、质量和风险进行控制和管理的活动。 
  • 软件配置管理是通过执行版本控制、变更控制的规程,并且使用合适的配置管理软件, 来保证所有产品配置项的完整性和可跟踪性。 

4.2 软件过程模型

软件过程模型是对软件过程的抽象描述 。

瀑布模型

开发阶段严格按照线性方式进行,每一个阶段具有相关的里程碑和交付产品,且需要确认和验证。 

•  以预测性为原则 •  以文档驱动开发过程 •  以过程控制为核心 

每个阶段的正确结果,作为下一个阶段的输入。

缺点

  • 软件的行为,只有在运行过程中,才能够显现出来。因此瀑布模型,只有到测试阶段,才能真正的验证和确认软件的功能和性能,然而此时所有的代码都已经编码完毕,因此很难返回去纠正需求的问题和设计的缺陷。尽管对各个阶段进行了严格的控制,但却缺少了对变化的控制;
  • 各个阶段的大量文档,增加了开发成本;
  • 整个过程是线性的,开发过程中间,很难响应客户的需求。
  • 早期的错误,也要等到后期测试才能发现。

软件开发作为一个问题求解过程,具有迭代性。需要不断地反复尝试,通过比较 和选择不同的设计,最终确定令人满意的问题解决方案。  显然,瀑布开发模式违背了这个性质。

原型化模型

解决需求不确定; 通过迅速构建一个软件原型(可理解为提供部分功能的、给用户的操作界面),通过原型的“模拟使用”,迅速确定需求或设计。 原型可以是可运行软件(慢),也可以是图纸(快,更易修改)

迭代式开发

•  更快速地发布产品 •  追求产品创新 •  需求不确定性高 •  需要快速响应用户的变化 •  关注用户行为 

迭代式开发有两种模型:

增量模型:一张图片分为三部分,每次完成一部分 迭代模型:先把轮廓画出来,然后修改细节,最后完成上色。

可转换模型

需要构建准确的数学方法,因此目前只用于有限状态的嵌入式系统。

4.3 敏捷开发过程

软件开发是一个逐步认知和明晰的活动;  软件开发中的变化是实际存在和必然的; 

软件开发应更关注于交付的价值 高质量的交付物是最重要的 系统不是一次构建而成,而是迭代演进的  基于完整的场景构建计划,并按优先级执行 

如今的互联网时代: •  快鱼吃慢鱼 •  版本发布成本很低 •  追求创新 •  需要快速响应用户的变化 •  需求不确定性高 •  关注用户行为

敏捷开发是一种基于更紧密的团队协作、能够有效 应对快速变化需求、快速交付高质量软件的迭代和 增量的新型软件开发方法。 

•  更关注协作  •  更关注质量  •  更关注可工作的产品  •  更关注全才化的专才  •  基于实践而非基于理论

由于需求是不可预测的,软件开发应是一个自适应的跟踪过程,而敏捷开发的特点,就是适应而非预测

敏捷宣言:

传统开发方法VS敏捷方法:

敏捷开发方法:

敏捷开发方法是一组轻量级开发方法的总称,包含很多具体的开发过程和方法, 最有影响的两个方法是极限编程(XP)Scrum开发方法。 

XP和Scrum:

Scrum框架

product backlog:产品订单,根据用户需要,市场需求,所有利益相关者排序给出需求列表、 挑选出冲刺计划、 一个冲刺周期内,每天进行会议,检查进展情况 一个周期结束后,就能产生一个可运行的交付版本

Scrum迭代开发

迭代开发的关键要点:  •  每一次迭代都建立在稳定的质量基础上,并做为下一轮迭代的基线,整个系统的功能随着迭代稳定地增长和不断完善。  •  每次迭代要邀请用户代表验收,提供需求是否满足的反馈。  •  在一次迭代中,一旦团队作出承诺,就不允许变更交付件和交付日期;如果发生重大变化,产品负责人可以中止当次迭代。  •  在迭代中可能会出现“分解”和“澄清”,但是不允许添加新工作或者对现有的 工作进行“实质变更”。  •  对于“分解”和“澄清”,如果存在争议,那么将其认定为变更,放到产品订单 中下一次迭代再考虑

其他方法或框架 kanban

5. 团队开发管理

5.1 团队组织与管理

开发团队组织模式

  • 民主式结构:团队成员完全平等,享有充分民主,成员之间通过协商做出决策。
    • 小组成员完全平等,名义上的组长 与其他成员没有任何区别。
    • 项目工作由全体讨论协商决定,并 根据每个人的能力和经验进行分配。
    • 特别适合于规模小、能力强、习惯 于共同工作的软件开发组。
  • 主程序员式结构:以主程序员为核心,主程序员既是项目管理者也是技术负责人, 团队其他人员的职能进行专业化分工。
  • 矩阵式结构:将技术与管理工作进行分离,技术负责人负责技术上的决策,管理 负责人负责非技术性事务的管理决策和绩效评价。

组织建设团队

  • 召开项目会议
  • 确立团队身份
  • 创建共同的目标
  • 管理决策制定
  • 建立奖励体系
  • 管理冲突
  • 激发项目团队活动

团队建设活动:

5.2 项目沟通管理

“智慧、专业技术、 经验三者只占成功因素的25%,其余75%决定 于良好的人际沟通。”

沟通是你被理解了什么,⽽不是你说了什么

Brooks法则:向一个进度延迟的软件项目中增加人员可能会使其进度更加推迟。 沟通人数在3~7,理论上是最合适的。

项目沟通管理:

•  和谁进行沟通?为什么? •  需要什么类型的信息? •  详尽程度和频率如何? •  沟通的目标是什么? •  采用何种方式沟通比较好?

项目会议: •  项目启动会议 (至关重要)

  • 目标
    • 项目概况:范围与目标、总体进度、方法和程序
    • 确定项目人员的角色和任务
    • 确立团队的工作模式
  • 形式
    • 重大项目:精心准备、集中1-2 天;前期介绍与建立基本规则
    • 一般项目:简单有效;回顾项目范围与成员互相自我介绍
  • 建立基本规则 -  计划决策、追踪决策、管理变动决策、关系决策

• 项目计划会议(通常在每一阶段开始时)

  • 制定当前阶段的项目计划
  • 将工作任务明确分配给项目成员

项目组工作例会(每日或每周一次)

  • 通报项目组成员的工作进展
  • 了解成员在工作中遇到的困难,并寻找资源解决
  • 确定后续的工作计划

项目阶段进展会议(每月或每季度一次)

  • 向项目干系人和高层管理者汇报项目进展
  • 解决需要高层管理者支持的问题

5.3 软件项目计划

软件项目计划是对软件项目实施所涉及的活动、资源、任务、进度等进行规划。 按时交付是软件项目的最大挑战,合理地安排进度是软件项目计划的关键内容。

必须做什么? 如何做? 谁去做? 什么时候做? 成本是多少? 达到什么质量?

软件项目计划流程:

  • 开发问题描述
    • 问题描述是描述系统应该说明的问题、目标 环境、客户交付和验收标准的简短文档。 问题描述是对系统所表述问题的共同认识, 通常是由项目团队和客户共同开发形成的, 它定义了问题提出的背景、需要支持的功能 和性能以及系统运行的目标环境等。
  • 定义顶层设计
    • 顶层设计描述了最初从系统到子系统的分解,它描述了系统的软件体系结构。
    • 子系统分解应该是高层的,专注于功能,并且要保持稳定。
    • 每一个子系统可以被分配给一个团队或一个人,由他负责其定义和实现。
  • 定义工作分解结构
    • 项目工作分解是将项目整体分解成较小的、易于管理和控制的若干子项目 或工作单元,直到可交付成果定义的足够详细,足以支持项目将来的活动。
  • 建立初始时间表
    • 在项目工作分解的基础上,进一步估算活动所需的时间和资源,并按照一定 的顺序将这些活动进行组织和调度,从而创建项目的进度计划表。
    • 制定进度计划需要在资源、时间和实现功能之间不断平衡,并需要定期更新。

5.4 软件项目估算

项目估算是对完成项目交付物的时间和成本进行预算和估计的过程。

软件规模越大,复杂性越高,不确定性就越大 需求的不确定性会对项目估算产生很大影响 没有可靠的历史数据使项目估算缺少参照物

软件项目估算的首要原则:对结果进行估计,而不是活动。 不论用什么⽅法,所有估计 从定义上来说都只是概率。

基本估计方法:

  • 专家判断
  • 参数估计:通过对大量的项目历史数据进行统计分析,使用项目特性参数建立 经验估算模型,估算诸如成本、预算和持续时间等活动参数。 包括功能点方法,COCOMO模型,用例点,机器学习

功能点方法 依据软件信息域的基本特征和对软件复杂性的估计,估算出软件规模。 这种方法适合于在开发初期进行估算,并以功能点为单位度量软件规模。

功能点:软件规模的度量单位

分为五种信息域:

  • 外部输入,如:界面输入、插入、更新
  • 外部输出,如:导出、报表、打印
  • 外部查询,如:输入查询目标,计算后输出查询结果
  • 内部逻辑文件,如:业务对象,有可能对应多个数据表
  • 外部接口文件,如:其他应用提供的接口数据

功能点方法计算步骤:

  1. 确定功能点计算的范围和应用程序边界,估算出所有数据功能及其复杂性,也即是内部逻辑文件和外部接口文件
  2. 估计所有事务功能及其复杂性,即外部输出、外部输出和外部查询
  3. 根据信息域加权因子,计算得出未调整功能点UFC
  4. 根据所开发系统的特点,系统复杂度调整值F1~F14
  5. 公式求出功能点

COCOMO模型 结构性成本模型 COCOMO(COnstructive COst MOdel)是一种利用经验模型进行工作量和成本估算的方法。

分为基本、中间、详细三个层次,分别对应软件开发的三个不同阶段,系统开发初期、各子系统的设计、子系统内部各个模块的设计。

上述公式只是经验模型,不可能长期适用,只能作为大概参考。

用例点 用例点估算是在面向对象软件开发项目中用于估计规模和工作量的方法,它比功能点方法要简单一些

机器学习 神经网络是采用一种学习方法导出一种预测模型,这种方法使用历史项目数据 训练网络,通过不断学习找出数据中的规律,再用其估算新项目的工作量。

基于案例的推理方法可以用于基于类推的估算,即识别出与新项目类似的案例, 再调整这些案例,使其适合新项目的参数。

6. Scrum

6.1 Scrum概述

角色

自组织团队是敏捷软件开发的基本观念,即团队被授权自己管理他们的工作过程 和进度,并且团队决定如何完成工作。

制品

后面会有单独讲解用户故事

可视化管理 任务白板(墙上的实体)是团队开发的晴雨表,它将团队的任务和进度可视化地展现出来。而引入电子白板可能会削减团队之间的沟通,降低团队的透明度,违背了敏捷重视人和团队的原则。

燃尽图可看这个,挺有意思

活动

迭代计划会议: 迭代计划会议在每次迭代(或冲刺)开始时召开,一般是2~4小时,目的是选择和估算本次迭代的工作项。 •  第一部分:以需求分析为主,选择和排序本次迭代需要实现的订单条目 •  第二部分:以设计为主,确定系统设计方案和工作内容

每日站立会: 会议目的: •  团队在会议中做计划,协调其每日活动,还可以报告和讨论遇到的障碍。 •  任务板帮助团队聚焦于每日活动上,应在这个时候更新任务板和燃尽图。 每个团队成员需要回答三个问题: •  上次例会后完成了什么? •  遇到了什么困难(或障碍)? •  下次例会前计划做什么?

迭代评审会议: 会议目的: •  Scrum团队在会议中向最终用户展示迭代的工作成果,团队成员希望得到反馈, 并以之创建或变更 Backlog 条目。 基本要求: •  由团队展示有可能发布的产品增量 •  允许所有参与者尝试由团队展示的新功能 •  用户对团队演示的产品功能进行反馈

迭代回顾会议: 每一次迭代完成后,都会举行一次迭代总结会,会上所有团队成员都要反思这个 迭代。举行迭代总结会议是为了进行持续过程改进,时间限制在1小时左右。 迭代回顾会议的关键要点: •  会议气氛:团队全员参加,气氛宽松自由,畅所欲言,发现问题和分析原因; •  关注重点:每次仅就1-3个关键问题做出可行的解决方案; •  跟踪闭环:可以放入下一次迭代订单中执行改进

6.2 用户故事与估算

用户故事

格式:作为一个<角色>,可以<活动>,以便于<价值>。

  • 独立性:尽可能避免故事之间存在依赖关系,否则会产生优先级和规划问题。
  • 可协商:故事是可协商的,不是必须实现的书面合同或者需求。
  • 有价值:确保每个故事对客户或者用户有价值的,最好是让用户编写故事。
  • 可估算:开发者应该能够预测故事的规模,以及编码实现所需要的时间。
  • 短小的:故事尽量短小,最好不超过10个理想人天,至少在一个迭代中完成。
  • 可测试:所编写的故事必须是可测试的。

实例: 卡片正面(描述):

  • 顾客可以使用信用卡购买购物车中的商品。 注释:接受Visa、 Master和American Express信用卡。

卡片背面(测试项):

  • 用 Visa、MasterCard和American Express进行测试 (通过)
  • 用 Visa借记卡测试(通过)
  • 用 Diner‘s Club(大莱卡)测试(失败)
  • 用正确的、错误的和空的卡号测试
  • 用过期的卡测试
  • 用不同限额的卡测试(包括超出银行卡的限额)

用户故事,应当面向价值: 错误的用户故事:作为一个玩家,可以通过显示排名, 让自己在服务器中的地位获得认可。 价值目标:激发玩家“斗志”,鼓励购买道具 错误原因:实现有技术问题:实时查看不现实; 小玩家对自己的排名不太关心,不会为了提升排 名去购买道具,只有少数顶级大佬才会受此蛊惑。

修改后的用户故事:作为一个排名靠前的付费玩家,可 以通过显示排名,让自己在服务器 中的地位获得认可(以刺激消费)。 (系统每周重新排名一次,而且只显示前XXX名玩家。 )

敏捷估算

  1. 对订单条目进行工作量估算,然后依照历史速率求出迭代数量
  2. 故事点(难度点数):将一个简单故事作为基准点(比如将注册设为1),然后给其他故事估算故事点
  3. 敏捷估算扑克 估算扑克牌的数值范围,由团队决定,有些牌是自然数排列 ,有些是斐波纳契数, 有些则是不连续自然数,例如2的幂
    • 分牌:每位成员手中的点数牌都一样(如果是四位成员,则每位成员一种花色,大小王不参与)
    • 讲解订单故事:产品负责人从Backlog中选择一个条目,为大家详细讲解该条目; 团队成员进行讨论并提问,产品负责人逐一解答大家的问题。
    • 估算:当团队成员确认已经对该条目完全了解且无任何重大问题后,大家开始进 行估算,同时选出代表自己估算值的纸牌,在所有成员选牌完毕后大家同时亮牌。
    • 争论与讨论:若每张牌估算值差距明显,代表大家 对该条目没有获得共识,需要对评估结果进行讨论。
    • 共识:对该条目重新进行估算,直到团队的评估 数值达成一致。

一般情况下,最多三轮争论就可以得出一个比较 统一的意见;如果三轮之后依然没有得到统 一的意见,那么Scrum主管应立即中断估算, 取平均值或其他大家接受的值作为估算结果。

6.3 团队协作工具Tower

自行百度学习

7. 需求获取

7.1 需求工程师

确保描述的一致性 提升标准和规范的依从性

7.2 需求定义

需求是对外可见的系统特征。

“需求管理” 有三项任务: •  学习 ——需求获取 •  剪枝 ——需求优选 •  文档化 ——撰写需求规格说明书

需求, 是人们要解决的某个问题或达到某种目的的需要。是系统或其组成部分为满足某种书面规定(合同,标准,规范等)所要具备的能力。需求将作为系统开发,测试,验收,提交的正式文档依据。

需求是每一个“人造物”都是一个内部环境外部环境的 “接口”。这里内部环境指人造物本身的设计组成。外部环境指人造物的周遭及其作用环境。对这个接口的描述既是需求。

个人理解:人造物——软件制品;内部环境——计算机层面;外部环境——软件应用层面,即现实世界

需求的内容 •  需求是系统为满足客户期望的目标而完成的行为 •  需求要体现出对问题领域的清晰理解 •  给出系统的使用场景和上下文

需求定义涵盖如下内容 为什么要设计该系统 系统由谁使⽤用 系统要做什么 系统涉及哪些信息 对解决⽅方案有何额外限制 如何使用该系统 质量需达到何种程度

问题划分(重点)

对于“禁止学生意外的人员参与校内活动抢票”这个需求,划分为三个层面:应用领域、机器领域、人机共享领域

根据对象的意义进行划分。比如,“学生”这个概念在机器领域不存在。学号、密码,这个在现实世界和机器领域都共有。

但是有时候,也会出现边界迁移

“乘客等待”这个对象机器领域显然不存在,但是如果我们增加了传感器记录乘客等待的状态,那么这个对象就成了人机共享对象。

领域性质:固有的性质 需求:因系统的存在而存在的性质 规约描述:满足需求应该做的事(比如登录qq必须先打开qq)

实例:

上述实例领域性质第二条错误:雨天打滑轮胎可能不转动、飞机不在跑到上时,论坛也可能转动。 因此领域模型错误。

出错信息超过一行时,也会显示在屏幕的第25行。

需求规约 好的需求是可以度量的,能给出项目成功的必要条件 单个需求项的质量 • 准确(Concise) • 正确(Correct) • 明确(Non-ambiguous) • 可行(Feasible) • 可证(Verifiable) 整个需求集合的质量 • 现实(Realistic) • 精确(Concise) • 全面(Complete) • 一致(Consistent)

7.3 需求的类型

分类:

产品/过程 • 产品需求 • 过程需求 产品需求 • 功能性需求(行为需求):满足系统需求之前,需要先实现的需求 •非功能性需求:满足系统功能需求的“约束条件”(抽象的约束) 抽象层次详细程度 • 业务需求:公司层面,人们一想到公司名字,就知道公司是干嘛的 • 用户需求:用户想要的功能 • 系统需求:当前系统的预期功能 • 软件需求:部分软件的需求,相对系统层面来说较小 • 质量需求:提供的服务应当好到哪种程度 • 依从性需求:着重描述软件对国家法律、国际公约、社交法则、文化与政治习 惯、标准等环境约束的满足要求 • 体系结构设计需求:定义系统环境对待设计系统在结构上的约束。如分布式约束、安装环境约束(如必须是win10系统) • 设计开发约束:是对软件系统设计过程的约束。包括:开发成本、开发周期、产品特征的变化性、可维护性、可重用性、可 移植性等。 • 软件设计规约

需求之间可能存在一定的重叠。

如何使用需求分类? • 关注特殊的需求特征 • 关注需求的语义特征 • 明确指出系统必须支持的行为 • 排除那些不可接受的系统行为 • 明确指出系统的最好支持的行为 • 对那些适用范围受限的关注点和横切关注点区别对待 • 需求的分类主要用于为需求的抽取提供启发式的规则 • 避免忽略某些关键的需求类型 • 通过已知矛盾的需求类型发现具体需求间的矛盾和冲突

7.4 需求工程过程

•  需求抽取(Elicitation)  •  需求分析(Analysis)  •  需求规约(Specification)  •  需求管理(Management)  •  需求验证(Validation)  需求抽取 目标: 主动与干系人协同工作,找出他们的需求, 识别潜在的冲突,磋商解决矛盾,定义系统范围 与边界  实质:了解待解决的问题及其所属领域  关键:确保该问题的解决是有商业价值的

抽取技术  •  协同工作(Collaborative sessions)  •  面谈 (Interviewing techniques)  •  问卷调查(Questionnaires)  •  观察法 (Ethnography)  •  原型法 (Prototyping)  •  文档分析(Documentation)  •  建模 (Modeling)  •  角色扮演(Roleplaying)  •  非功能性需求列表(Checklists of NFRs) 冲突识别与磋商 (Conflict Identification and Negotiation)

需求分析 目标:对产品及其与环境的交互进行更深入的了解,识别系统需求,设计软 件体系结构,建立需求与体系结构组件间的关联,在体系结构设计实现过程 中进一步识别矛盾冲突,并通过干系人之间的协调磋商解决问题。  实质:概念建模———选择常用的建模语言,进行功能建模和信息建模  关键:体系结构设计与需求分配  通过评估需求的满足度来评价体系结构设计的质量

需求建模方法:

  需求管理 贯穿从需求获取到软件系统下线的全过程。需求管理涉及软件配置管理、需 求跟踪、影响分析和版本控制  •  需求跟踪 (Requirements traceability)  描述和追踪一条需求的来龙去脉的能力,包括向前追踪到软件制品,向后 追踪到需求来源  •  变更请求管理 (Change Requests)  系统化的变更管理  •  需求属性管理 (Requirements attributes) 

需求验证 对其他需求工程活动的质量的保证。通过数学的形式化工具或工程化的测试 过程来确保系统满足干系人的要求。  验证方法  •  评审(Review)  •  原型化(Prototyping)  •  模型验证(Model validation)  •  确认测试(Acceptance Tests)

 

7.5 需求的主要来源

四世界模型:

主题世界:从当前系统的功能主题出发 系统世界:考虑系统本身的需求 开发世界:考虑开发过程本身的需求 应用世界:关注人以及应用流程

确定干系人  •  这里需要强调与客户之间的联络关系  •  系统的设计到底与谁的利益息息相关 定义边界  •  怎样界定问题的范围?  •  定义目标与情景实例  •  目标与情景实例是组织原始需求信息的有效手段 分析可行性  •  如何进行可行性研究  •  如何选择好的项目 分析风险  •  风险管理应长期、持续进行,而非阶段性、一次性的任务  •  进行灾难及事故分析,以确定风险

干系人分析  •  找出所有干系人  •  分析其隶属于哪个世界 干系人举例  •  用户—关心新系统特征和功能  •  设计师—想要构造完美的系统,尽量重用已有的代码  •  系统分析师—想要获取正确的需求  •  培训与用户支持人员—确保系统可用和可管理  •  业务分析师—想确保“我们做得比竞争对手好”  •  技术文档作者— 为系统准备用户手册及其他相关文档  •  项目经理—希望按时、按预算、按目标完成项目  •  客户—为新系统买单的人 



7.6 需求获取技术

7.7 撰写需求文档

软件需求规格说明 (So#ware Requirements Specifica4on, SRS) • 是具有一定法律效力的合同文档 • 清楚地描述软件在什么情况下,需要做什么,以及不能做什么 • 以输入/输出、输入到输出之间的转换方式来描述功能性需求 • 描述经过干系人磋商达成共识的非功能性需求 • 一般参考需求定义模板,覆盖标准模板中定义的所有条目 • 作为后续的软件评估依据和变更的基准

文档需要有逻辑组织结构 •  例如:参照IEEE的模板 典型的组织形式包括 •  按系统能够响应的各种外部环境情况来组织 •  按系统特征来组织 •  按系统的响应方式来组织 •  按所管理的外部数据对象来组织 •  按用户类型来组织 •  按软件的工作模式来组织 •  按子系统的划分来组织

高质量需求规格说明的评价标准: • 正确性 = 经过验证的 • 无歧义 • 完整的 • 可测试 = 可以证明的 • 可修改的 • 可跟踪的 • 易理解 • 一致的 • 有序的 • 项目或产品特定的其他特征

简洁 定义:需求描述尽可能简洁 •  描述了系统的一个独立特征 •  除了必需的信息外没有包含其他信息 •  用清晰、简单、可理解的词表述 •  避免“应该”、“可以”、“可能”之类的用词 举例: •  “急救电话的响应应本着先到先响应的原则” 相对 •  “急救电话应按照其拨入的次序存入一个先入先出的等待队列当中,并且按照进入队列的 次序逐一应答” 是简洁的

经验理论

代码是否容易修改(可读性)可能是最重要的,性能结构等其他方面可以不断完善,但是一个软件的代码难以阅读,那就谈不上迭代。

多读别人的代码,遇到读不懂的,找出自己为什么读不懂; 多让别人读自己的代码,遇到读不懂的, 找出别人为什么读不懂。

如果程序是一篇论文,接口就是论点,实现是论证,测试是论据。

环境搭建对于读代码(使用代码)的人来说,往往是最难的开始;测试用例一定要简单、可靠。

好的软件应当是迭代出来的。

软件缺陷具有空间聚集性,80%的缺陷常常存在于 20%的代码中。因此,应当记住常常光临代码的高 危多发“地段”,这样发现缺陷的可能性会大得多。

询问用户比资讯专家往往更有效。

积极应对需求变动。

  • 生产力决定生产关系,经济基础决定上建筑
  • 要抓住社会发展的主要矛盾----业务痛点
  • 内容为王、流量为王、移动为王、变现能力为王
  • 垂直细分、下沉是趋势----社会分工越来越精细
  • 技术没有好坏之分—三十年河东,三十年河西
  • 开源意味着开放,非开放无以求发展;非团结无以求生存
  • 由点到线,再到面—建立普遍联系是事物发展的必然趋势
  • 无论是人还是软件,链接能力决定一切
  • AIOT时代,软件必将再次与硬件耦合—分久必合合久必分
  • 工具->产品->服务;软件之道,在亲民,在止于至善
  • 平衡、折中;追求全局最优,而非局部最优
  • 不能入乡随俗,就会水土不服;土生土长、原汁原味的最好
  • 时势造英雄,生不逢时,再好的产品也会时运不济;酒香也怕巷子深;天下武功,唯快不破

UML建模路线

8. 用例建模

8.1 情境需求的需求方法——用例建模

为什么需要⽤用例建模——描述系统的功能性需求 • 关联干系人需要以及软件需求 • 确认与系统交互的人或对象(参与者) • 定义系统的边界 • 捕捉和传达系统的理想行为(用例) • 验证或确认需求 • 规划工具

系统框中填写可能的功能(用例),然后外面用箭头连接对应的参与者。

有箭头的关联指出是谁发起的交互,没有箭头则表明双方都可以发起交互

用例:定义系统的一系列行为 通过此可为 参与者 提供 有价值可观测 的结果。

拓展阅读笔记

1. 用例

来自《这个圈圈不简单——潘加宇》

  1. 用例就是:给定一个研究对象,它的执行者乐意“买”,该研究对象又能“卖”的一个价值。
  2. 研究对象改变,用例随之改变 请假用例:

如果将研究对象打包成“人事部”

3. 数据库思维不可取 常常将用例简单概括为CRUD,非常不可取。

正确做法:

4. 用例不应当怕多

为不同执行者提供不同用例

5. 需求不应当复用

0 人点赞