软件工程概述¶
基本概念¶
软件¶
- 软件包含:程序、数据、文档
- 程序=数据结构+算法
- 软件=程序+软件构建
- 软件公司=软件+商业模式
- 软件工程的问题:
- 开发维护成本高,花费时间长
- 开发中不能排除所有错误
- 发展:程序-软件-软件产品
- 工作:源代码管理,质量保证(测试),维护
- 特点:
- 复杂性
- 不可见性
- 易变性
- 服从性
- 非连续性
- 分类:
- 功能:系统软件、引用软件、支撑软件(介于中间层)
- 规模:微型、小型、中型、大型、甚大型、极大型
- 软件开发:软件产品、软件项目
- 软件危机:
- 开发进度难以预料
- 成本难以控制
- 用户对产品不满意
- 质量无法保证
- 难以维护
- 缺少文档资料
- 是由于不正确的开发方式造成的:认为软件开发=程序编写,轻视软件测试和维护
软件工程开发历程¶
- 过程
- 软件需求
- 软件设计
- 软件构造
- 软件测试
- 软件维护
- 生命周期模型
- 瀑布模型:
- 每一步的结果都是可验证的减少风险
- 原型模型:
- 先构造小型软件系统进行测试,获得反馈
- 瀑布模型:
计算机发展历程¶
- 第一代:电子管 二进制 汇编 程序
- 第二代: 晶体管 高级编程语言 软件
- 第三代:集成电路 摩尔定律
- 第四代:大规模集成电路
- 数据库成熟广泛使用、第三四代编程语言出现
- 第一代软件技术(结构化程序设计)
- 第二代(软件测试技术、方法、原理)
- 第三代(处理需求的技术)
- *第五代计算机
- 其应用程序将达到知识表达级,具有听觉、视觉甚至味 觉功能,能够听懂人说话,自己也能说话,能认识不同 的物体,看懂图形和文字。
- 人们不再需要为它编写程序指令,只需要口述命令,它 自动推理并完成工作任务
问题定义与可行性研究¶
- 对于软件产品的开发,也应该明确该软件产品开发的任务以及完·成任务的价值,从而制定出完成任务的计划。
-
问题的定义和可行性研究就是制定软件系统计划的第一步。在软件工程中,把这一步称为计划时期
- 核心目标:3W
- Who为谁设计
- What解决什么问题
- Why为什么解决这些问题
步骤¶
现状调查和问题的定义¶
- 目的:弄清楚用户要求计算机解决什么问题
- 任务:编写系统目标与规范说明书
- 本阶段要确定研究对象,分析研究意义和价值、 当前的研究成果和程度、还存在的问题;研究 获得成果的条件是否具备;研究的方法和方案。
- what、why(目的、目标是什么,要做什么),即初步的问题(需求)分析和设计
- whether(是否可能成功),即风险分析 3、how(步骤、技术、条件)、when(时间计划
- who + which(人员职责),即问题的定义(软件)过程
可行性研究与论证¶
- 技术、经济两方面
- 目的:用最小的代价 在尽可能短的时间内确定该软件项目是 否能够开发,是否值得开发。
分类¶
- 技术可行性分析
- 围绕系统开发价值进行论证:
- 性能
- 可靠性
- 可维护性
- 生产率
- 分析方法
- 数学模型和优化技术
- 概率统计
- 排队论
- 控制论等
- 为新系统提交技术可 行性评估。以指明为完成系统的功能和性能需要什么 技术?需要哪些材料、方法、算法或者过程等
- 是最难决断和最关键的问题
- 技术可行性研究包括:
- 开发的风险:能否设计出系统,实现必需的功能和性能
- 资源的有效性:包括硬件、软件资源,现有技术 人员的技术水平与已有的工作基础
- 技术:相关技术的发展是否能支持这个系统
- 经济可行分析
- 进行成本效益分析,评估项目的开发成本。
- 成本组成:
- 购置软、硬件及有关设备费用
- 系统开发费用
- 系统安装和维护费用
- 人员培训费用
- 运行可行性分析
- 运行方案是否可行
- 不能与原来的任务相矛盾
- 法律可行性分析
- 侵犯他人、集体或国家的利益要承担相应的法律责任
开发方案的选择¶
- 一般将一个大而复杂的系统分解为若干个子 系统的办法来降低解的复杂性。可以采用折衷的方法,反复比较各个方案的 成本⁄效益,选择可行的方案。
- 因为用户无法准确知道自身的需求,所以必须由开发方理解用户的问题,并给出有效的 解决方案 。这是现代软件开发的重点。
- 好处:
- 求更容易明确,开发成本和维 护成本降低,质量提高,产品附加值提高,利 润增加。
- 方案会考虑用户的隐性需求,产品使用寿命延 长,同时可能带来一系列的后续项目。
可行性论证报告¶
内容¶
- 系统概述:主要是对当前系统及其存在的问题的简单描述; 对新系统的开发目的、目标、业务对象和范围;新系统和它各 个子系统的功能与特性等。
- 可行性分析:这是报告的主体。包括新系统在经济上、技术 上、运行上、法律上的可行性及对新系统主客观条件的分析。
- 拟定开发计划:包括工程进度、人员配备情况、资源配备情 况,估计出每个阶段的成本、约束条件。
- 结论意见:综合上述分析,说明新系统是否可行,结论可区 分为三类:立即进行、推迟进行、不能或不值得进行。
工具¶
- 表达信息在系统各部件之间的流动的情况
- 三种结构:顺序、选择、和循环
- 表示一个系统的层次分解以及调用关系
步骤¶
- 澄清系统规模和目标
- 改正含糊不清的叙述,确保解决问题的正确性
- 研究现有系统
- 总结优点和不足,得到新系统的雏形
- 导出新系统的高层逻辑模型
- 进一步确定系统规模和目标
- 导出供选择的解法
- 分析员至少提出3种类型的备选方案: 低成本、中成本、高成本系统
- 推荐最佳方案
- 草拟开发计划
- 编写文档,提交审查
个人软件流程与团队软件流程¶
- 个人贡献者:Individual Contributor (IC)
- 个人的工程质量极大地影响了软件的质量
- 要做什么:
- 了解当前的情况
- 找到解决方案
- 估计工作时间、依赖关系
- 和相关人士讨论解决方案,不断迭代
- 执行解决方案(代码复审、更新测试等)
- 和其他队友一起维护软件,对结果负责
- 衡量
- 任务的大小
- 需要多少努力(时间)
- 质量
- 日程
- 弱点
- 小型的创业团队,很难找到高质量的需求分析文档
- 导致后续的活动非常随机,开发活动可能随时变化
- 依赖与数据
- 要求开发人员手动记录所有活动,如何处理丢失数据或者不准确
- 利益冲突? 是否应该如实记录花了很多时间处理的简单问题?
- 记录工作大小
- 代码行数是唯一的衡量?
- 重用代码、用别人的类库vs. 自己从头写
- 开发者删除了2000行有问题的代码,他的绩效如何
- 衡量最终的结果吗?
- 目前衡量了工程师如何有效地实现软件需求
- 但是没有衡量用户是否对产品满意
- 衡量成长
- 积累软件开发相关的知识,提升技术技能
- 积累问题领域的知识和经验
- 对通用的软件设计思想和软件工程思想的理解
- 提升职业技能(区别于技术技能)
- 自我管理的能力、表达和交流的能力、与人合作的能力、按质按量完成任 务的执行力,这些能力在IT行业和其他行业都很重要
- 实际成果
- 团队对个人的期望
- 交流
- 说到做到
- 接受团队赋予的角色并按角色要求工作
- 全力投入团队的活动
- 按照团队流程的要求工作
- 准备
- 理性地工作
- 软件工程师的思维误区
- 分析麻痹过于保守,有100%的把握再出手
- 依赖链条过长
- 过早优化
- 过早泛化
- 职业发展阶段;
- 临时的寄托或工作
- 工作
- 职业
- 投身的事业
- 理想的呼唤
*敏捷过程¶
-
出现原因:用户需求加快,开发流程必须跟上快速变化的节奏。
-
极限编程:把好方法发挥到极致
-
迭代-递增模型的需求和分析工作流
- 成本-效益分析方法
- 测试驱动开发
- 结对编程
- 时光盒
-
站立会议
-
可靠性不高,应对快速变化,把顾客拉到开发团队当中,有特定的使用范围,适合小规模团队,需要高度的协作和沟通,以及频繁的反馈和改进。
-
原则;
-
我们最优先要做的是通过尽早和持续地交付有价值的软件来满足客户。
- 欢迎对需求进行改动,即使在开发的后期也一样。为了客户的竞争优势,敏捷过程掌控变化。
- 频繁地交付可工作的软件,周期从几周到几个月不等,以较短的周期为宜。
- 业务人员和开发人员必须在整个项目开发过程中每天都要进行合作。
- 围绕着被激励的个人来构建项目。给他们提供所需的环境和支持,并信任他们能够完成工作。
- 在一个开发团队内部,最有效果也最富有效率的传递信息的方法就是面对面的交谈。
- 可工作的软件是进度的首要度量标准。
- 敏捷过程倡导可持续开发。责任人、开发者和用户要能够共同维持其步调稳定延续。
- 坚持不懈地追求技术卓越和良好的设计,增强敏捷能力。
- 简单——最大化未做工作量的艺术——是至关重要的。
- 最好的架构、需求和设计出自自组织的团队。
- 团队定期地反思如何能够更有效地工作,并依此调整自己的行为。
极限编程¶
- 计划:从创建用户故事开始,用户故事是描述用户需求和价值的简短语句。敏捷团队评估每个故事并分配成本,将故事分组为可交付的增量,确定交付日期,并根据第一个增量的“项目速度”来定义后续增量的交付日期。
- 设计:遵循保持简单(KIS)的原则,鼓励使用CRC卡(类-责任-协作卡),用于描述对象之间的关系。对于难以设计的问题,建议创建“尖峰解决方案”——一种设计原型。鼓励“重构”——对内部程序设计进行迭代改进。
- 编码:建议在编码开始之前为每个故事构建一个单元测试。鼓励“结对编程”,即两个程序员共同完成一个任务。
- 测试:每天执行所有单元测试。“验收测试”由客户定义,并用于评估客户可见的功能。
scrum¶
- Scrum思想是一种敏捷软件开发的管理方法,用于迭代式增量软件开发过程¹。Scrum是一个包括了一系列实践和预定义角色的过程骨架,旨在帮助团队在面对复杂适应性问题时,高效创造出最有价值的产品²。Scrum的主要角色包括:Scrum Master,负责确保团队遵循Scrum的原则和实践,并帮助团队解决障碍;产品负责人,负责确定产品的方向和愿景,定义用户需求和优先级;开发团队,负责实现产品功能,并保证质量和可交付性¹³。Scrum的核心价值观包括:承诺、专注、开放、尊重和勇气³⁴。
- 每个迭代开始时选择一些优先级最高的条目,形成迭代任务,在迭代结束时会得到一个可运行的交付版本
软件生命周期¶
- 软件生命周期是软件的产生直到报废的生命周期
- 项目运行过程中需要维护,当你发现维护成本比较高,用户来 的需求已经没有办法在原系统上修改的时候,就是你放弃这个 版本的时候,由此开始下一个软件的生命周期
- 瀑布模型、原型模型、迭代式模型 、螺旋模型
软件体系结构¶
- 软件体系结构(Software Architecture)包括构成系统的设计元素的描述、设计元素之间的交互、设计元素的组合模式以及在这些模式中的约束。
- 五大组成部分;
- 一是构件,是一组基本的构成要素;
- 具有某种功能的可复用的软件结构单元,封装的实体
- 二是连接件,是这些要素之间的连接关系;
- 机制、协议:调用,中断,io,api,参数种类,数目,格式,进程等等
- 三是约束,是作用于这些要素或连接关系上的限制条件;
- 四是质量,是系统的质量属性,如性能、可扩展性、可修改 性、可重用性、安全性等
- 五是物理分布,是这些要素连接之后形成的拓扑结构,描述 了从软件到硬件的映射
软件需求分析¶
需求的定义¶
- 所谓软件需求,就是用户对系统提出的要求
任务¶
- 需求获取
- 需求优选
- 撰写需求规格说明书
过程¶
- 确定项目的大背景
- 了解项目的领域、客户对项目的期望值
- 对于企业项目,在确定项目目标后,还要进一步了解客户的企业框 架、当前项目在企业框架中位置、第三方接口定义等
- 核心需求的定义和确定
- 核心功能
- 找出当前需要实现的关键功能,并对高风险、技术风险大的功能或者 关键功能中相互冲突的功能进行前期取舍
- 确定关键功能是一个不停递归的过程
- 关键质量
- 根据项目的愿景,进行关键质量的筛选
- 相关约束
- 业务级约束:项目的组织结构和人员信息来源于企业人事系统
- 用户级约束:使用客户的一部分是残障人士,或包含藏语用户
- 开发级约束:开发人员的技术水平等
- 项目详细需求分析
- 对项目核心功能进行数据流需求调研分析、业务逻辑分析
- 在此基础上编写用户用例、数据流转图、业务逻辑图等
目的¶
- 在综合分析用户对系统提出的一组需求(基于功能、性能、 数据等方面)的基础上,构造一个从抽象到具体的逻辑模型来表达软件将要实现的需求
- 以“软件需求规格说明书”的形式作为本阶段工作的结果, 为下一阶段的软件设计提供基础
需求工程¶
特性¶
- 必要性:软件开发是“利用通用的计算机结构构造一 个有用的软件系统”的工程,需要处理新问题,给出 新解决方案,其中定义问题就是需求工程的任务
- 重要性:开发软件系统最为困难的是准确说明开发什 么,如果问题广为人知或者小而简单,都容易被忽略
- 复杂性:范围广泛、诸多参与方、内容多样、活动交 织、结果要求苛刻(正确性、完整性、一致性)
*过程¶
- 启动inception
- 初步了解用户的需求需求者与开发者建立联系
- 找到利益相关者
- 认识多种观点
- 努力实现合作
- 引导Elicitation
- 从利益相关者征集需求
- 召开会议,双方出席
- 提出解决方案的要素协商不同的方法,并指定一套初步的解决方案
- Quality Function Deployment(QFD):
- Function deployment determines the “value” of each function required of the system
- Information deployment identifies data objects and events
- Task deployment examines the behavior of the system
- Value analysis determines the relative priority of requirements
- Non-Functional Requirement (NFR):
- A two phase process is used to determine which NFR’s are compatible
- 细化Elaboration
- 创建分析模型,确定数据功能行为等要求
- 谈判Negotiation
- 开发者与客户谈判,获得一个可以实现、满意的系统
- 规范Specification
- 可以实是书面文件、原型、模型等
- 审核Validation
- 纠正错误,澄清,补充完善,不一致的问题,矛盾、无法实现的部分
- 管理Requirements management
*建立分析模型¶
-
家庭安全系统
-
需求获取¶
- 客户可能没有意识到自己的公司在做什么
- 询问通常不太起作用 。没有专业的软件开发小组的协助,客户很难了解到需要开发什 么的相关信息
目标¶
- 主动与干系人协同工作,找出他们的需求,识别潜在的 冲突,磋商解决矛盾,定义系统范围与边界
- 其实质是了解待解决的问题及其所属领域
- 关键是确保该问题的解决有商业价值
流程¶
- 理解应用域
- 目标产品应用的特定环境
- 可以是银行、空间探索、汽车制造或遥感勘测等
- 建造业务模型
- 用来确定客户的初始需求
- 需求启发(需求捕获):发现客户的需求
- 应用迭代法
- 需求分析:不断推敲和扩充
- 直到开发小组对需求真正满意
示例¶
- 需求捕捉:很多时候 用户并不知道自己确切的需 求,或者不愿意表达完整的需求 ,软件团队需要 设身处地,替用户着想,引导出需求。
- 分析技术的发展趋势以及产业的变化、社会发展 的大趋势,推测用户会产生哪些新需求。
- 来自监管部门
- 软件企业=软件+ 商业模式 企业所采用的商业模式会对软件提出需求 。(如何让这个服务带来收入)
- 来自技术团队本身
- 更好地了解用户的行为和需求
分类¶
- 对产品功能的需求
- 服务质量需求
- 对产品开发过程的需求
- 要求软件的开发流程必须满足某些约束条件,例如开发过程必须产生某种 类型的文档,必须在某个时间点达到某个状态,必须对源代码施以某种约 束(安全性核查、代码版权核查、代码规范和支持文档的核查)。
- 综合需求
- 有些需求不是单一个软件模块就能满足,例如,“购物网站必须在24小时 内把货物发送到用户手中”,这个需求牵涉到软件系统、货物派送系统、 送货部门、监控系统等不同部门的功能和执行能力。
获取方法¶
- 焦点小组
- 调查问卷
-
人类学调查
-
深入面谈
- 卡片分类
- 日志调研
- 对记录的日志信息进行分析处理和挖掘
- A/B测试
- 在真实的环境中实验新的功能,同时跟踪 数据,考察不同设计的效果
NABCD模型¶
- N (Need 需求)
- 你的创意解决了用户的什么需求?什么痛苦?他们对 已有软件、服务不满意的地方。但是用户往往也不知 道颠覆型的创新
- A (Approach 做法)
- 你有什么招数, 特别是独特的招数,来解决用户的痛苦。 这些招数不光是技术上的, 也可以是商业模式上的、 地域的、人脉的、行业的。
- 你不能说我会C++,所以我一定可以写好这个软件。 你得有独特的办法,例如有人脸识别技术、会做超大 规模的数据处理。
- B (Benefit 好处)
- 你这个产品/服务会给客户/用户带来什么好处呢? Benefit/Cost (成本) 的问题。
- C (Competitors竞争)
- 这个市场有多大, 目前有多少竞争者在瓜分? 你如果 不是最先进入某个市场的产品, 你还能赢吗? (用户“不消费”也是你的一个竞争对手。)
- D (Delivery 交付
- 你怎么让目标用户都知道你的产品? 并且让产品的用 户量快速提高? 你有什么数据来衡量改进的效果?
模板¶
影响项目的因素¶
- 三种策略
- 差异化
- 同质化:和别人兼容,足够好
-
优化:提高效率,在同类中最好
-
产品的因素
- 希望产品达到什么样的可靠性标准。
- 产品的数据量有多大。
- 产品的复杂程度。
- 对模块重用的要求。
- 文档的需求。
- 牵涉到硬件、供应链、软件、社区、运营的复杂产品,如何管 理各种依赖关系?
- 平台的因素
- 执行时间的约束。是一个实时系统吗?
- 存储的约束。数据如何保存,恢复的策略是怎样的?
- 平台变动的约束。
- 人员的因素
- 分析师和程序员的能力。
- 做此类应用的经验,使用开发平台、编程语言和工具的经验。
- 人员流动性。
需求分析与建模¶
困难¶
- 用户与开发人员很难进行交流
- 用户的需求是动态变化的
- 系统变更的代价呈非线性增长
基本思想¶
- 抽象:透过现象看本质
- 抓住事物的本质,捕获问题空间的“一般/特殊”关 系,这是认识、构造问题的一般途径
- 划分:分而治之
- 分离问题,捕获问题空间的“整体/部分”关系是降 低问题复杂性的基本途径。
- 投影:从不同视角看问
- 捕获并建立问题空间的多维视图,是描述问题的基本 手段
- 建模:规格严格、功夫到家
- 采用规范的描述方法,将模糊的、不确定的用户需求 表达为清晰的、严格的模型,作为后续设计与实现的 基础
任务¶
- 确定系统的综合需求
- 分析系统的数据需求
- 导出系统的逻辑模型
- 修正系统的开发计划
需求分析方法¶
结构化分析与设计方法¶
- 数据流图DFD
- 描绘数据在系统中各逻辑功能模块之间的流动和处理 过程,是功能模型
- 主要刻画“功能的输入和输出数据”、“数据的源头 和目的地”
- 数据字典DD
- 对于DFD中出现的所有被命名的图形元素(数据流、 数据项、数据存储、加工)在DD中作为一个词条加 以定义,使得每一个图形元素的名字都有一个确切的 解释
- 所有的定义是严密的、精确的,不可有含混、二义性1
- 数据建模-实体联系图(ER图)
- 把用户的数据要求清楚、准确地描述出来,建立 一个概念性的数据模型
- 包含数据实体、主要属性和关联关系
面向对象分析与设计方法¶
- 识别对象,包括其属性及外部服务
- 识别类及其结构,定义对象之间的消息传递
- 第一阶段:建立静态模型
- 从用例模型入手,寻找概念类
- 方法1:重用或修改现有的模型
- 方法2:使用分类列表
- 方法3:确定名词短语
- 细化概念类,识别边界类、控制类和实体类
- 添加关联和属性
- 第二阶段:建立动态模型
- 从用例和活动图入手,建立系统顺序图
- 建立分析对象的顺序图
- 确定分析类的操作
需求验证¶
软件需求规格说明书¶
- 具有一定法律效力的合同文档,并依据供需双方达成的共识,清楚 地描述软件在什么情况下需要做什么以及不能做什么,通过定义系 统的输入/输出、输入到输出之间的转换方式来描述系统的功能性需 求,也描述经过干系人磋商达到共识的非功能性需求,一般参考需 求定义模版完成,覆盖标准模版中定义的所有条目,并将需求作为 后续的软件评估依据和变更的基准。
组织结构¶
- 参照模板
- 按照系统能相应的外部环境情况阻止
- 按系统的功能特征组织
- 按系统的响应方式组织
- 按管理的外部数据对象组织
- 按用户类型来组织
- 按软件工作模式来组织
补充¶
- ppt3-2 p60开始介绍了
软件设计¶
软件概要设计¶
软件设计过程¶
- 解决怎么做的问题
- 软件设计是软件开发阶段的重要步骤,其主要任务是在 需求分析的基础上形成软件系统的设计方案。
- 系统总体设计:在需求分析的基础上定义系统的设计目标,将系统划分为子系统
- 模块设计与实现:细化和实现模块单元,设计数据结构、算法、数据库等。原则是高内聚、低耦合
- 软件交互设计:对软件的软件交互、操作逻辑和用户界面进行设计
- 系统设计目标:定义系统应重点考虑的质量要求
- 前提。软件需求分析阶段搞清楚了“要解决什么问题”,并输出 了《软件需求说明书》。 这时一切都是理想。
- 概要设计阶段。重点说清楚“总体实现方案”,确定软件系统的 总体布局,各个子模块功能和模块间关系,与外部系统的关系。有一 些研究与论证性的内容,并输出《软件概要设计说明书》。 这时一切都是概念。
- 详细设计阶段。重点说清楚“每个模块怎么做”,是“程序”的 蓝图,确定每个模块采用的算法、数据结构、接口的实现、属性、参 数,并输出《软件详细设计说明书》。 这时一切都是实现。
软件设计的任务和步骤¶
- 制定规范
- 阅读和理解软件规格说明书,在给定预算范围内和技术现状下,确认用户 的要求能否实现;根据目标确定合适的设计方法。
- 软件系统结构的总体设计
- 采用某种设计方法,将一个复杂系统按功能划分成模块的层次结构;确定 每个模块的功能,建立与已确定的软件需求的对应关系;确定模块间调用 关系;确定模块间的接口,即模块间传递的信息,设计接口的信息结构。
- 处理方式设计
- 确定为实现软件系统的功能需求所必须的算法;评估算法的性能;确定满 足软件系统的性能需求所必须的算法和模块间的控制方式。
- 确定算法满足功能;确定算法满足性能
- 如响应时间、吞吐量(即单位时间内能够处理的数据量)、精 度(在进行科学计算或工程计算时的运算精度的要求)等
- 数据结构设计
- 确定输入、输出文件的详细数据结构;结合算法设计,确定算法所必须的 逻辑数据结构及其操作等。
- 确定输入、输出文件的详细数据结构;
- 结合算法设计,确定算法所必须的逻辑数据结构及其 操作等。
- 可靠性设计
- 着重需要考虑异常处理、冗余备份等方面的设计工作。
- 着重需要考虑异常处理、冗余备份等方面的设计工作
软件设计方法¶
模块化¶
分解¶
信息隐藏¶
- 每个模块的实现细节对于其它模块来说是隐藏的。 也就是说,模块中所包含的信息是不允许其它不需要 这些信息的模块使用的。
模块的独立性¶
- 模块的独立性是指软件系统中每个模块只 涉及软件要求的具体子功能,而和软件系统 中其它模块的接口是简单的。
- 内聚性是程序结构中各个模块内部相互关联的度量, 它取决于模块内部各个元素之间联系的紧密程度。
- 偶然性内聚:模块内各部分之间没有联系,即使有也是松散的,如工具箱
- 逻辑性内聚:由若干逻辑功能相似的部分组成,由参数判断执行那一功能,每次执行的是若干功能中一种
- 信息性内聚:在同一数据结构上操作,如数据库维护模块
- 功能性内聚:模块内所有成分都用来完成一个功能
- 耦合性是程序结构中各个模块之间相互关联的度量, 它取决于各个模块之间接口的复杂程度、调用模块的方 式以及哪些信息通过接口。
- 非直接耦合:两个模块直接没有直接关系,通过主模块控制和调用实现
- 数据耦合:彼此交换数据信息
- 特征耦合:通过参数表传递记录信息
- 控制耦合:传递控制信息,控制选择零一模块的功能
- 外部耦合:访问同一全局变量
- 公共耦合:访问同一全局性数据结构
- 内容耦合:直接调用另一模块的数据,或直接转移
结构化sd¶
-
结构化设计方法(SD,Structured Design)是基于模块化、 自顶向下细化、结构化程序设计等程序设计技术基础发 展起来的
-
属于面向数据流的设计方法
- 在软件的需求分析阶段,数据流图DFD是软件开发人员考虑问 题的出发点和基础;在需求分析的基础上,将DFD图映射(Mapping)为软件系统的结 构图SC,提供了一种结构图SC的描述工具,专门用来描述软件 的总体结构
系统结构图sc¶
-
表示调用模块与被调用模块之间的关系用方框表示模块,箭头表示调用关系
-
系统结构图模块类型
- 传入模块:传送的数据流称为逻辑输入数据流
- 传出模块:传送的数据流称为逻辑输出数据流
- 变换模块:所加工的数据流叫做变换数据流
- 协调模块:对所有下属模块进行协调和管理
- 典型的系统结构形式
- 变换型:取得数据、变换数据和给出数据
- 事务型:当外部信息沿接受路径进入系统后,经过事 务中心的识别和分析获得某一特定值,根据这个特定 的值来启动与该特定值相应的动作路径,如菜单。各个事物处理模块是并列的,分别完成不同的事务工作
- 将需求阶段所得的DFD图转化为设计阶段的结构图 SC
- 首先需要细化规格说明书中的DFD图
- 然后判断DFD图的结构类型,若为变换型,则进行变换分析, 否则进行事务分析;
- 进而完善SC图,并对最终的SC图进行评审。
- 改进SC图
- 模块功能的完善化:不仅能够完成指定的功能,而且还应当能 够告诉使用者完成任务的状态以及不能完成的原因
- 软件结构的改善:审查分析这个结构图,如果发现几个模块的 功能有相似之处,就要加以改进
- 作用范围<=控制范围:使判定的作用范围和判定所在模块的控 制范围尽可能吻合
- 减少高扇出:较好的软件模块结构,其平均扇出是3-4
- 模块大小要适中:通常一个模块中语句的行数应在50-100行左 右,最多不得超过500行
- 其它:功能应该可预测的模块;避免过分受限制的模块
面向对象¶
-
识别对象类是最关键的,需要定义每个类的职责并确定类的关系。
-
类图(class diagram) 展现一个类的静 态结构
用例ucd¶
- 格式:
- CRC卡片分拣法:
- 使用CRC分析法寻找类
- 根据用例描述中的名词确定类的后续者,根据边界类、控制类、实体类的划分等信息来寻找类;
uml¶
- 目的
- 便于管理复杂系统
- 精确地记录和表达用户需求
- 帮助理解设计和设计的决定
- 组织管理各类设计的元素
- 更方便地探索更多的解决方案
- 包含语义、表现、场景三部分
- 即模型讲述什么内容、用什么方式表达、在什么上下文中出现。
构成¶
- 构造块
- 基本uml元素、关系和图
- 三种基本构造快:
- 事物:建模元素本身
- 结构事物:(名词)类、接口、用例...
- 行为事物:(动词)交互、状态机...
- 分组事物:把语义上相关的建模元素分组为内聚的单元...
- 注释事物:注解
- 关系:把事物联系到一起
- 依赖:对象之间的一组链接
- 关联:事物的改变引起依赖物件的语义改变
- 泛化:一个元素是另一个元素的特化,而且可以取代更一般的元素
- 实现一个类说明一份契约,另一个类保证实现
- 图:uml模型的视图,可视化系统将做什么或者如何做
- 静态模型:类图、对象图、构件图...
- 动态模型:顺序图、协作图、用例图、活动图...
- 公共机制
- 达到特定目标的uml方法
- 框架
- 系统框架的uml视图
其他设计方法¶
软件详细设计¶
目的与任务¶
- 详细设计的目的: 为软件结构图 (SC) 中的每一个模块确定采用的算法和模块内 数据结构,用某种选定的表达工具给出清 晰的描述。
- 编写纤细设计说明书
- 原则:
- 将保证程序的结构清晰度 放在首位。
- 设计过程中应采用逐步细化 的实现方法。
- 选择适当的表达工具 。
- 如再模块的算法确定下来之后,需要用适当的表达工具将其精确明了的表达出来
- 任务
- 为每一模块确定算法
- 确定每一模块使用的数据结构及数据库的物理结构
- 为系统中的所有模块确定并构造算法实现所需的内部数据结构
- 根据前一阶段确定的数据库的逻辑结构,对数据库的存储结构、存取方法等物理结构进行设计
- 确定模块的外部接口和用户界面
- 按照模块的功能要求,确定模块接口的详细信息,包括模块之间的接口 信息、模块与系统外部的接口信息及用户界面等。
- 为每一模块设计一组测试用例
- 由于负责详细设计的软件人员对模块的实现细节十分清楚,由他们在完 成详细设计后提出模块的测试要求是非常恰当和有效的
- 编写文档,参加复审
- 详细设计阶段的成果主要以详细设计说明书的形式保留下来,通过复审 对其进行改进和完善,作为编码阶段进行程序设计的主要依据
描述工具¶
程序流程图¶
-
程序流程
-
符号
-
例
-
优缺点;
-
优点:是对 控制流程的描绘很直观,便于初学者掌握
- 缺点:
- 不是逐步求精的好工具:诱使程序员过早考虑程序的 具体控制流程,忽略了程序的全局结构;
- 用箭头代表控制流,使得程序员不受任何约束,可以 完全不顾结构程序设计的精神、随意转移控制;
- 在表示数据结构方面存在不足。
NS图¶
- 在流程图 中完全去掉流程线,全部算法写在一个矩形框内
- 依从上到下的设计,待处理的问题会分解成一些较小的副程序, 最后只有简单的叙述及控制流程结构,N-S图对应了上述思维, 利用嵌套的方块来表示副程序。
- N-S图几乎是流程图的同构,只有像Goto指令或是C语言中针对循 环的break及continue指令无法用N-S图表示
- N-S图的抽象层次接近结构化的代码,若程序重写,N-S图就需重 新绘制,不过N-S图在简述程序及高级设计时相当方便。
- 例:
- N-S图不允许违背结构程序设计精神,有以下特点:
- 功能域(一个特定控制结构的作用域)明确;
- 复杂度接近代码本身,修改需要重画整个图,不可能任意转移控制;
- 很容易确定局部和全程数据的作用域
- 很容易表现嵌套关系,也可以表示模块的层次结构。
PAD图¶
- 采用二维树形结构图表示程序的控制流
- 用二维树形结构 的图来表示程序 的控制流,将这 种图翻译成程序 代码比较容易
- PAD图既克服了 传统的流程图不 能清晰表现程序 结构的缺点,又 不像N-S图那样受到把全部程序 约束在一个方框内的限制
- 例:
- 优点:
- 使用表示结构化控制结构的PAD符号所设计出来的程 序必然是结构化程序
- PAD图描述的程序结构十分清晰,图中竖线的总条数 就是程序的层次数
- 用PAD图表现程序逻辑易读、易懂,程序从最左竖线 上端的结点开始执行,按照自上而下、从左到右顺序 执行,遍历所有结点
- 容易将PAD图转换成高级语言源程序
- 既可用于表示程序逻辑,也可用于描绘数据结构
- 支持逐步求精方法
PDL伪代码(语言工具)¶
- PDL 是一种用于描述功能模块的算法设计和加 工细节的语言。称为设计程序用语言。它是一种 伪代码(Pseudo code)
- 外层:具有严格的关键词语法,用于定义控制结构 和数据结构,包括简单陈述句、判定和重复结构等 三种。
- 内层:采用自然语言短语表示实际操作和条件。使 用数据词典中定义的名字和有限的自定义词,还可 使用一些简单的算术运算和逻辑运算符号。
-
用它来描述程序的结构,工作量要比画图小,又比较容易转换成 真正的代码。
-
语法:
- 类似于大括号
- 例子:
- 优点:
- PDL描述可直接作为注释插在源程序中,有助于保持 文档和程序的一致性
- 用PDL写成的程序,可抽象、可具体,易实现自顶向 下逐步求精的设计原则
- 同自然语言很接近,易于理解,可使用普通的文字处 理系统完成书写和编辑
- PDL描述与程序结构相似,可自动由PDL生成程序的 代码
- 缺点:不如图形描述形象直观
基于UML的分析与设计过程(ATM机的例子)¶
用例图建模¶
- 用户界面设计。。。
- 用例图。。。
- 活动图。。。
-
包图。。。
-
具体见ppt(略)
数据库选择策略¶
- 数据库是对数据的管理,其业务包含了对数据的 增、删、改、查等操作。数据管理中包括用户访 问权限、持久化、分布式等不同的方案选择
- 常用数据库
用户界面设计¶
界面设计的概念¶
- UI界面是人与机器进行交互的操作平台,即用户 与机器相互传递信息的媒介。
- 界面设计是指对软件的人机交互、操作逻辑、界面美观的整体设计。
- 5w1h
- 黄金原则
- Place the user in control(置用户于控制之下):用户界面 能够对用户的操作作出恰当的反应,并帮助用户完成需要的工作。
- 易用性是界面设计的核心,不给用户犯错误的机会
- 不要强制用户进行不必要或不希望的操作。交互模式应该尽可能地自然和直观,不应该让用户感到困惑或被迫进行某些操作。
- 提供灵活的交互方式。用户应该能够以各种方式与应用程序或系统进行交互,例如通过鼠标、键盘、触摸屏等方式。
- 允许用户交互可以被中断和撤消。这样,用户可以在需要时随时停止或撤销他们的操作,而不必担心损失数据或进度。
- 随着用户技能水平的提高,简化交互方式并允许用户对交互进行自定义。这样,用户可以根据自己的需求和偏好来定制他们的交互方式。
- 隐藏技术内部细节,使得非专业用户也能够轻松使用应用程序或系统。用户不应该被迫了解复杂的技术细节,而应该能够专注于他们想要完成的任务。
- 设计直接交互的对象出现在屏幕上。这样,用户可以直接与对象进行交互,而不必通过复杂的命令或菜单来完成任务。
- Reduce the user’s memory load(减少用户记忆负担):系 统应该“记住”有关的信息,通过缺省项、快捷方式或界面 视觉减少用户的记忆负担。
- 界面提供帮助
- 减少对短期记忆的要求。这意味着在设计交互方式时应尽可能减少用户需要记忆的信息量。可以通过使用图形、图标、标签、提示等方式来帮助用户轻松地理解和记忆信息。
- 建立有意义的默认值。这意味着在设计应用程序或系统时应该考虑到用户的需求和习惯,并提供适当的默认设置,以便用户可以立即开始使用应用程序或系统,而无需进行额外的配置。
- 定义直观的快捷键。这意味着在设计交互方式时应该考虑到用户的使用习惯和期望,并提供简单且易于记忆的快捷键,以便用户可以更快速、更高效地完成任务。
- 界面的视觉布局应该基于现实世界的隐喻。这意味着在设计界面时应该考虑到用户对现实世界的理解和经验,并提供具有直观意义的元素和布局,以便用户可以更轻松地理解和使用应用程序或系统。
- 逐步披露信息。这意味着在设计应用程序或系统时应该将信息分为小块,并逐步地向用户披露。这可以帮助用户逐步理解和掌握应用程序或系统的功能,同时避免信息过载和混淆。
-
Make the interface consistent(保持界面的一致):用户应 该以一致的方式展示和获取信息。
- 最忌讳每换一个屏幕,用户就要换一套操作命令与操作方法
- 允许用户将当前任务放入有意义的上下文中。这意味着在设计交互方式时,应该提供足够的上下文信息,以便用户可以理解当前任务的目的、意义和影响。同时,应该提供一致的图标设计和标签,以便用户可以快速找到需要的功能。
- 在应用程序家族中保持一致性。这意味着在设计交互方式时应该考虑到整个应用程序家族的一致性,以确保用户可以在不同的应用程序之间轻松切换,并且可以快速掌握新的应用程序。
- 如果以前的交互模式已经创造了用户的期望,除非有强烈的理由,否则不要进行更改。这意味着在设计交互方式时,应该考虑到用户的使用习惯和期望,并尽量保持以前的交互模式,除非有足够的理由来进行更改。这样可以避免用户的困惑和不适。
-
设计步骤
- 概要设计
- 行为(交互)设计
-
界面设计
- 做减法:把那些无关紧要的 功能藏起来
- 替用户着想但不低估用户水平
- 替用户着想以便越用越好用
- 准备好不同的短期/长期方案(用户连续使用时间)
- 不让用户犯错误
-
用户界面的功能性
- 界面最基本的要求是具有功能性与使用性
- 通过界面设计,让用户明白功能操作,并将产品本身的信息更加顺畅地传递给使用者,是功能界面存在的基础与价值
-
用户界面一定要有基本的功能,设计者不能片面追求界面外观漂亮而导致华而不实
-
六大注意事项
- 尽快提供可感触的反馈
- 现在程序发生了什么,应该在某一个统一的地方清晰 地标示出来
- 一个目标用户能够只靠软件的主要反馈来完成基本的 操作
- 系统界面符合用户的现实惯例
- 软件系统要用用户语言而不是开发者语言来和用户沟通
- 目标用户的实际生活体验
- 软件反馈要避免带给用户惊奇
- 用户有自由控制权
- 操作失误可回退,要让用户可以退出软件
- 用户可定制显示信息的多少,还可定制常用的设置
- 在界面使用上要设计方便退出,提供不同可能性
- 一致性和标准化
- 软件中对同一事物和同类操作的表示用语,各处要保 持一致
- 又如在一个系列的软件中,风格须一致,表现为统一的字体 字号、统一的色调、统一的提示用词、窗口在统一的位置、 按钮在窗口的相同的位置等,其目的是能够减少记忆量、减 少出错概率而且能迅速积累操作经验。
- 适合各种类型的用户
- 要为新手和专家提供可定制化的设计
- 帮助系统可以帮助用户更快捷、更好地学习界面如何使 用
- 把常用功能用图标按钮形式放在工具条上或用快捷键, 并且一些操作方式、快捷操作可调整。
- 为某些障碍的用户提供一定程度的便利
- 软件应该能适应用户的使用习惯,让用户越用越顺手
- 帮助用户识别、诊断并修复错误
- 软件的关键操作需要有确认提示,以便帮助用户尽早 消除误操作
- 使用朴素的语言来表述错误信息。
- 要给出下一步操作提示
- 必要时提供详细的帮助信息
- 提示和帮助文档
- 无需文档就能流畅应用当然更好,如果必要的话,可提 供一个在线帮助。
- 如果软件和用户的工作相关(而不是简单的游戏),那 么基本的提示和帮助文档还是很有必要的,而且也要提 供便利的检索功能
-
文档要从用户角度出发描述具体步骤,且不要太冗长。
-
界面设计是一种结合美学、计算机科学、心理学、行 为学、人机工程学、信息学以及市场学等的综合性学科,强 调人-机-环境三者作为一个系统进行总体设计。
-
研究界面,即图形设计师、美工、软件产品的产品外形设计 师。其中大部分是有美术设计教育背 景
-
研究人与界面的关系,即交互设计师。设计软件操作流程、 树状结构、软件的结构与操作规范等。交 互设计师一般都是软件工程师背景居多
-
研究人,即用户测试/研究工程师。这个测试和编码没有任何 关系,主要是测试交互设计的合理性以及图形设计的美观性。。用户研究工程师一般是心理学、人文学背景比较合适。
用户界面设计分析¶
- 与需求分析同步进行,分为用户特性分析和用户工作分析两个部分
- 用户特性分析
- 外行型:不熟悉计算机操作,对系统几乎没有认知
- 初学型:对计算机有一定的经验但对新系统不熟悉,需要相当多的支持
- 熟练型:对一个系统有相当多的经验,需要较少的支持,但不了解系统的内部结构,不能纠正以外的错误。
- 专家型:了解系统的内部构造,具有维护修改基本系统的能力,需要提供能修改、扩充系统能力的复杂界面
- 但用户类型不是不变的,一个用户群体也可能存在不同类型的用户。
- 用户工作分析
- 用户工作分析,也称为任务分析,它是系统内部活动的 分解。用户工作分析与需求分析中结构化分析的方法类 似,是采用自顶向下、逐步进行的方式进行功能分解。
- 系统的功能分解,可以用数据流图和数据词典来描述。其 中,每一个加工相当于一个功能,也就是一个任务。任务可以 由一组动作构成,它规定了为实现该任务所必须的一系列活动。 任务的细节,可以使用结构化语言来表达。它描述了动 作完成的序列以及在完成动作时的所有例外情况。
界面设计的基本类型¶
- 如果从用户与计算机交互的角度来看,用户 界面设计的类型主要有菜单、图形与图表、对话 以及窗口等。
- 选择时的考虑
- 使用的难易程度
- 学习的难度
- 操作速度
- 复杂程度
- 控制
- 开发的难易程度
菜单¶
-
系统预先设置好的显示于屏幕上的一组或几组可供用户选择的命令
-
分类
- 按照显示的形象或样式来分类
- 正文菜单,简称菜单,实质上是系统命令或者是其简写形式
- 选取方式:首字符匹配、序号匹配、亮条匹配
- 图标菜单,简称图标或图符,是安置在一个小方框之中的一 幅图形
- 按屏幕位置和操作风格来分类
- 固定位置菜单,每次总是在屏幕的相对固定的位置出现
- 浮动位置菜单,也叫弹出式菜单
- 下拉式菜单,糅合了固定菜单与浮动菜单
- 嵌入式菜单,该菜单通常并不成行成列地出现在屏幕上,而 是混在应用之中
图像¶
- 在用户界面中加入丰富多彩的图像,将能更形象地 为用户提供有用的信息,达到可视化的目的。
- 主要的处理有图像的隐蔽和再现、屏幕滚动等。
- 图像的隐蔽和再现:在实际的应用系统中常常频繁地要 求把屏幕上的某一块矩形区域内的图像隐蔽起来,然后 再以适当的时间,再重新显示出来
- 屏幕滚动:将用户显示内容在物理屏幕上做平行移动。
对话¶
- 对话也称为对话框,在系统必要时显示于屏幕上 一个矩形区域内的图形和正文信息。通过对话可 以实现用户和系统之间的通信
- 分类
- 必须回答式
- 无须问答式
- 警告式
窗口¶
- 窗口是指屏幕上的一个矩形区域,在图形学中叫 做视图区(Viewport)。
- 用户可以通过窗口显示、观察其工作领域内的全部或 一部分内容,并可以对所显示的内容进行各种系统预 先定好的正文和图形操作。
- 习惯上我们把窗口视为虚拟屏幕。相对地,显示器就 称为物理屏幕。采用滚动条技术,通过窗口能够看到 的用户空间,比物理屏幕显示的内容要多得多。
- 另一方面,在同一物理屏幕上又可以设置多个窗口。 各个窗口可以由不同的系统或系统成分分别使用。如 果在同一个屏幕上有若干个窗口,这些窗口可以重叠 在一起,也可以在水平方向并列排列。
界面设计风格¶
- 分类
- 扁平化:风格简单,无特效;排版简洁;色彩绚丽;二维效果
- 拟物化:3D特效;逼真
- 卡通化:夸张;变形
- 图标logo设计的意义
- 设计的流程
- 图标创意阶段:看懂界面需求,对每个图标的定义要准确清楚
- 草图绘制阶段:统一图标风格,统一透视
- 草图渲染阶段:使用PS等软件
数据输入界面的设计¶
- 数据输入是指所有供计算机处理的数据输入。 数据输入界面是系统的一个重要的组成部分,它 占用用户的极大部分使用时间。
- 在软件设计的范围内,可 以通过以下方法来减少用 户输入的工作量。
- 使用代码或缩写
- 对共同的输入内容设置 默认值 (缺省值)
- 自动填入已输入过的内容 或需要重复输入的内容
- 如果输入内容是来自一个 有限的备选集,则可以采 用列表选择
- 原则
- 确认输入:只有用户按下确认才确认输入
- 交互动作:tab或其他键控制光标在表项之间的移动
- 确认删除:特别确认之后再删除
- 提供反馈:
- 提示输入范围:显示有效回答的集合的范围
- 输入方式:
- 表格形式
- 用户进行填表格的操作
- 菜单形式
- 用户输入代码进行选择
- 其他
数据输出界面的设计¶
- 数据输出界面包括屏幕查询、文件浏览、图形 显示和报告等。
- 信息量要适当,不能过多/过少
- 规则
- 只显示必需的数据,与用户需求无直接关 系的一律省略
- 显示出的数据,应与用户所执行的任务有关
- 同一时刻使用的数据应显示在一起
- 每一屏所显示数据的数量,包括标题栏等, 最好不要超过整个屏幕面积的30%
程序编码¶
- 任务
- 根据详细设计说明书编写程序,使用选定的程序设计语言,把模块的过程性描述(不可执行)翻译为用该语言书写的源程序或源代码(可执行)
- 要求程序员熟悉所用语言的功能和程序开发环境,弄清 楚要编码模块的外部接口与内部过程
- 目标:保证软件的质量和可维护性
- 程序设计语言的特性,程序员必须深刻理解、熟练掌握并正确 运用程序设计语言的特性
- 程序设计风格,要求源程序具有良好的结构性和良好的程序设 计风格
程序设计语言的基本概念¶
- 三要素
- 语法:
for(表达式1;表达式2;表达式3)语句
这样的固定格式 - 语义:语法的含义(如:表达式1表示循环初值;表达式2表示循环条件;表达式3表 示循环的增量;语句为循环体)
- 语用:表示构成语言的各个记号和使用者的关系、实现的简易性、应用的效率和编程方法论
基本成分¶
- 数据成分:指明该语言能接受的数据,用来描述程序中的数据
- 名称、类型和作用域
- 运算成分:指明该语言允许执行的运算
- 如+ 、-、* 、/ 等
- 控制成分:指明该语言允许的控制结构,人们可利用 这些控制成分来构造程序中的控制逻辑
- 基本的控制成分包括:顺序结构、条件选择结构和重复结构
- 传输成分:指明该语言允许的数据传输方式, 在程序中可用它进行数据传输。
- printf ( )函数用来向标准输出设备(屏幕)写数据
- scanf ( ) 函数用来从标准输入设备(键盘)上读数据
特性¶
- 心理特性
- 一致性:指语言采用的标记法(使用的符号)协调一致 的程度(避免一符多用)
- 二义性:对语句不同理解所产生的二义性将导致程序员 对程序理解的混乱。
- 紧致性:指程序员必须记忆的与编码 有关的信息总量。
- 其指标有:对结构化部件的支持程度;可用关键字和缩写的种 类;算术及逻辑操作符的数目;预定义函数的个数等。
- 局部性:程序由模块组成,应采用高内聚低耦合、模块 独立、局部化等原则。
- 线性:人们习惯于按逻辑上线性的次序理解程序,程序 中大量的分支和循环、随意的GOTO语句会破坏程序的 线性,提倡结构化程序设计。
- 传统性:容易影响人们学习新语种的积极性。
- 工程特性
- 将设计翻译成代码的便利程度
- 编译器的效率
- 源代码的可移植性(语言的标准化)
- 配套的开发工具(减少编码时间,提高代码质量)
- 可复用性(编程语言能否提供可复用的软件成分)
- 可维护性(包括可理解性、可测试性、可修改性),源程序的可读性和文档化特性是影响可维护性的重要因素
- 应用特性
- 不同的程序设计语言满足不同的技术特性,可以对应于 不同的应用
- 要根据不同项目的特性选择相应特性的语言。
- 支持结构化构造的语言有利于减少程序环路的复杂性, 使程序易测试、易维护。
发展和分类¶
- 发展
- 第一代语言:机器语言和汇编语言 (低级语言 )
- 优点:质量高、执行速度快、占存储空间小。
- 缺点:类似机器语言,通用性、可移植性差, 与人的自然语言相差悬殊。
- 第二代语言:早期高级语言,如BASIC,FORTRAN, COBOL等
- 第三代语言:具有很强的数据结构和过程描述能力,支 持结构化编程,如Pascal,Modula,C,Ada等
- 第四代语言(4GL):这类语言出现于七十年代,其目 的是为了提高程序开发速度以及让非专业用户能直接编 制计算机程序
- 高级语言所编写的程序同样不能直接在计算机 上执行,要转换成机器指令代码。
- 编译方式 通过编译程序(编译、链接)将整个程序转换为机 器语言。
- 解释方式 通过解释程序,逐行转换为机器语言,转换一行运 行一行。
- 面向过程的高级语言特点:接近人们习惯用的自然语言和数学语言,通用性 强,可移植性好。
- 程序=(算法)+(数据结构)
- 面向对象的高级语言面向对象的程序设计方法:围绕真实世界的概念来组织模型。
- 对象=(算法+数据结构) 程序=(对象+对象+ …… )
- 优点: 问题求解更容易 程序的编制、调试和维护更容易
- 程序设计语言的分类
- 按语言级别:低级语言和高级语言;
- 按应用范围:通用语言和专用语言;
- 按用户要求:过程式语言和非过程式语言;
-
按语言所含的成分:顺序语言、并发语言和分布式语言
-
选择
- 应用领域(首要)
- 算法和计算复杂性
- 软件运行环境
- 用户需求,特别是性能需求
- 数据结构的复杂性
- 软件开发人员的知识水平
- 可用的编译器与交叉编译器
程序设计风格和代码规范¶
- 程序的质量主 要取决于设计,但编程的质量也在很大程度上影响 着程序的质量
- 编码的风格:编码产生的源程序应该正确可靠、简 明清晰而且具有较高的效率。这是好程序的一个主 要标准
- 编码风格
- 精确性、一致性、无二义性
- 缩进
- 行宽度
- 括号
- 命名
- 注释
- 设计指南
- 功能
- 异常处理
- 线程
- 性能
- 安全
源程序的内部文档¶
- 在源程序中可包含一些内部文档,以帮助开发人员阅读和理解源程序,包含适当的标识符、适当的注解和程序的视觉组织等
- 标识符的命名
- 选择含义明确的名字,使其能正确提示标识符所代表的 实体
- 名字不要太长,太长会增加打字量且易出错,必要时可 使用缩写
- 不用相似的名字,相似的名字容易混淆,不易发现错误
- 不用关键字作标识符
- 同一个名字不要有多个含义
- 名字中避免使用易混淆的字符
- 程序的注释
- 一些正规的程序文本中,注释行的数量约占整个源程 序的1/3到1/2,甚至更多
- 序言性注释
- 功能性注释
- 视觉组织
- 通过在程序中添加一些空格、空行和缩进等技巧,帮 助人们从视觉上看清程序的结构
- 自然的程序段之间可用空行隔开
- 可通过添加空格使语句成分清晰
- 也可以通过添加括号突出运算的优先级,避免发生 运算的错误
数据说明¶
- 数据说明的次序应当规范化
- 使数据属性容易查找,也有利于测试、排错和维护
- 原则上,数据说明的次序与语法无关,其次序是任意的;但出于阅读、 理解和维护的需要,最好使其规范化,使说明的先后次序固定
- 说明语句中变量安排有序化
- 当多个变量名在一个说明语句中说明时,可以将这些变量按字母的顺序 排列,以便于查找
- 使用注释说明复杂数据结构
- 如果设计了一个复杂的数据结构,应当使用注释来说明在程序实现时这 个数据结构的固有特点。
语句构造¶
- 常用的规则
- 不要为节省空间将多个语句写在一行
- 避免大量使用循环嵌套和条件嵌套
- 利用括号使逻辑表达式或算术表达式的运算次序清晰直观
- 程序编写首先应当考虑清晰性,不要刻意追求技巧性,使 程序编写得过于紧凑。
- 程序要能直截了当地说明程序员的用意
- 让编译程序做简单的优化。
- 尽可能使用库函数
- 避免不必要的转移
- 尽量只采用三种基本的控制结构来编写程序。除 顺序结构外,使用if-then-else来实现选择结构; 使用do-until或do-while来实现循环结构
输入输出¶
- 对所有的输入数据都要进行检验,识别错误的输 入,以保证每个数据的有效性;
- 检查输入项的各种重要组合的合理性,必要时报 告输入状态信息;
- 使得输入的步骤和操作尽可能简单,并保持简单 的输入格式
- 输入数据时,应允许使用自由格式输入;
- 应允许缺省值
- 输入一批数据时,最好使用输入结束标志,而不要由用 户指定输入数据数目;
- 在交互式输入时,要在屏幕上使用提示符明确提示交互 输入的请求,指明可使用选择项的种类和取值范围。 同时,在数据输入的过程中和输入结束时,也要在屏 幕上给出状态信息;
- 当程序设计语言对输入/输出格式有严格要求时,应保 持输入格式与输入语句的要求的一致性;
- 给所有的输出加注解,并设计良好的输出报表。
结构化编程¶
- 结构化程序设计是一种 编程典范。它采用子程序、程序码区块、for循环以及while循环等结构,来取代 传统的goto语句(严格控制GOTO语句)
- 结构化编程是一种设计、实现程序的技术,它采用 自顶向下、逐步细化的设计方法和单入口单出口的控制结构。
原则¶
- 自顶向下,逐步细化;
- 清晰第一,效率第二;
- 书写规范,缩进格式;
-
基本结构(顺序、选择、重复),组合而成。
-
这类循环结构出现了两个循环出口。一个是for 循环的正常出口; 当循环控制变量i 超出了循环终值n时,则退出循环; 另一个是for 循环的非正常出口:当某种条件满足时,从循环中间某处转出, 执行循环后面的语句。它不满足结构化的要求
程序复杂度度量¶
- 程序复杂性主要是指模块内部程序的复杂性。它直接关系到软件开发费用的多少、开发周期的长短和 软件内部潜伏错误的多少。同时它也是软件可理解性 的另一种度量。
- 代码行度量法:统计程序中的源代码的行数
- McCabe 度量法 :利用程序的控制流来度量程序的复杂性
- 该方法是利用程序模块的程序图(是一种退化了的程序流程图。即把 程序流程图中每个处理符号都退化成一 个结点,而原来流程图中的流程线,则 变成连接不同结点的有向弧。)中环路的个数,来计算程序的复杂性。
- 环路复杂度取决于程序控制结构的复杂度。当程序的分支数目或循 环数目增加时,其复杂度也增加。环路复杂度与程序中覆盖的路径 条数有关。
- 环路复杂度是可加的。例如,模块A的复杂度为3,模块B的复杂度 为4,则模块A与模块B的复杂度是7。
- McCabe建议,对于复杂度超过10的程序,应分成几个小程序,以 减少程序中的错误。Walsh用实例证实了这个建议的正确性。在 McCabe复杂度为10的附近,存在出错率的间断跃变。
- McCabe环路复杂度隐含的前提是:错误与程序的加上例行子 程序的调用数目成正比。加工复杂性、数据结构、录入与打乱输入 卡片的错误可以忽略不计。
-
Halstead 度量
- 程序长度(预测的Halstead长度)
- 实际的Halstead长度
- 程序的潜在错误
- Halstead度量的缺点
程序效率¶
- 程序效率是指程序的执行速度及程序占用的 存储空间。程序编码是最后提高运行速度和节省 存储的机会,因此在此阶段不能不考虑程序的 效率。
- 源程序的效率与详细设计阶段确定的算法的效率 有着直接的关系。当我们把详细设计翻译并转换 成源代码之后,算法效率就会反映为程序的执行 速度和存储容量的要求
- 转化原则
- 在编程序前,尽可能化简有关的算术表达式和逻辑表达式
- 仔细检查算法中的嵌套的循环,尽可能将某些语句或表达式移到循环外面
- 应该把变化范围较大的放在外层循环
- 并且预处理需要多次计算的值,如修改后
j+2
被多次重复计算
- 尽量避免使用多维数组
- 尽量避免使用指针和复杂的表
- 不要混淆数据类型,避免在表达式中出现类型混杂
- 尽量采用整数算术表达式和布尔表达式
- 选用等效的高效率算法
面向对象编程¶
-
封装、继承和多态。
-
OOP把对象作为程序的基本单元,一个对象包含了数据 和操作数据的方法。
- 面向对象分析技术关注应用领域中的实体,并将其建模 为对象。
- 面向对象分析技术主要基于分类、泛化、聚合关系在对 象集合之间建立结构,对象的行为是执行预定的动作(服 务/活动),对象通过执行动作来完成状态变迁。
- 类:用来描述具有相同属性和方法的对象的集合,它定义了该集 合中每个对象所共有的属性和方法,其中的对象被称作类的实例。
- 类变量:类变量是所有实例公有的变量。定义在类中,在方法体之外。
- 数据成员:统称类变量、实例变量、方法、类方法、静态方法和属性。
- 类方法:类方法是将类本身作为对象进行操作的方法
- 方法:类中定义的函数
- 静态方法:不需要实例化就可以由类执行的方法。
- 方法重写:如果从父类继承的方法不能满足子类的需求,可以对父类的 方法进行改写,这个过程也称override。
- 实例:也称对象。通过类定义的初始化方法,赋予具体的值,
- 实例化:创建类的实例的过程或操作
- 实例变量:定义在实例中的变量,只作用于当前实例。
软件的质量¶
- 定义
- 软件产品在特定条件下满足明示和暗示需 求的能力
- 软件产品满足既定需求的程度,但质 量取决于那些既定的需求准确地代表利益相关者的需求、欲望和期望 的程度
- 软件质量=程序质量+软件工程质量
程序的质量¶
- 程序的质量体现在软件外在功能的质量。
- 衡量软件的功能
- 功能测试,基本的判断可以用“是| 否”来判定
- 多维度特性的综合指标
- 服务质量
- 程序的质量还有其它方面,例如用户体验的质量、国际化 的质量和安全性的质量
软件工程的质量¶
- 体现
- 开发过程的可见性
- 开发过程的风险控制
- 内部模块的交付质量
- 开发成本的控制
- 内部质量指标的完成情况
- 风险控制
- 有个模块由其它公司提供,但是没有交付,我们也无 能为力;
- 这个平台的开发难度远超预期,我们也没有办法,只 有延长开发时间;
- 程序重新选择架构后,突然出现了许多问题,我们只 好延长开发时间;
- 项目组有个成员离职了,他负责的模块别人都不懂, 只好重新招人培养,并推迟交付日期;
- 服务器突发故障,所有源代码都丢失了,也找不到完 整的备份,只好大大推迟交付日期。
- 交付质量
- 内部模块经常崩溃,延误开发;
- 项目内部的里程碑实现质量太差,导致最终产品未能 达到预期质量标准;
- 项目管理工具太难用、太繁琐、速度慢
- 工具体现的软件工程流程与团队实际运作不符合;导 致工具显示的状态并不是团队实际进度;
- 并不是所有人都使用项目管理工具(例如很多人不想 用规定的工具来跟踪Bug)。
- 开发成本
- 成本包括时间和金钱等
- 内部指标
- 测试用例的数量
- 测试自动化的程度
- 每日构建的速度
- 自动部署系统的效率
- 代码覆盖率
- 文档的质量等
CMMI¶
-
评价软件团队的能力
-
CMMI一级,完成级
- 在完成级水平上,企业对项目的目标与要做的努 力很清晰,项目的目标得以实现。但是由于任务 的完成带有很大的偶然性,企业无法保证在实施同类项目的时候仍然能够完成任务
- 企业在一级上的项目实施对实施人员有很大的依 赖性
- CMMI二级,管理级
- 在管理级水平上,企业在项目实施上能够遵守既 定的计划与流程,有资源准备,权责到人,对相 关的项目实施人员有相应的培训,对整个流程有 监测与控制,并联合上级单位对项目与流程进行 审查。
- 企业在二级水平上体现了对项目的一系列管理程 序。这一系列的管理手段排除了企业在CMM1 时完成任务的随机性,保证了企业的所有项目实 施都会得到成功,可以保证完成同类任务
- CMMI三级,明确(定义)级
- 在定义级水平上,企业不仅能够对项目的实施有 一整套的管理措施,并保障项目的完成;
- 而且企业能够根据自身的特殊情况以及自己的标 准流程,将这套管理体系与流程予以制度化。
- 这样企业不仅能够在同类的项目上成功地实施 CMMI,在不同类项目上一样能够成功地实施。
- CMMI四级,量化管理级
- 在量化管理级水平上,企业的项目管理不仅形成 了一种制度,而且要实现数字化的管理。
- 通过量化技术来实现流程的稳定性,实现管理的 精度,降低项目实施在质量上的波动
- CMMI五级,优化级
- 在优化级水平上,企业的项目管理达到了最高的 境界。
- 企业不仅能通过信息手段与数字化手段来实现对 项目的管理,而且能充分利用信息资料,对企业 在项目实施的过程中可能出现的次品予以预防。
- 能够主动地改善流程,运用新技术,实现流程的 优化。
衡量软件工程质量¶
- 依靠用户的反馈:太晚
- 依靠团队成员:他们太忙,利益相关
- 依靠项目管理软件:那要保证收集到足够全面的、真实的数据,最好是自然真实发生的数据
质量保证¶
- 软件测试(Test):运用一定的流程和工具,验证软件能实现预先设计的功能 和特性,工作的流程和结果通常是可量化的。例如,测试用例、Bug、代码覆 盖率、MTTF、软件效能的参数等。正因为流程和结果是明确定义的、可量化 的,所以很多测试工作可以自动化。
- 软件质量保障工作(Quality Assurance):软件团队为了让软件达到事先定义 的质量标准而进行的所有活动,包括测试工作
代码复审和结对编程¶
代码复审¶
核查内容¶
- 概要部分
- 代码符合需求和规格说明么?
- 代码设计是否考虑周全?
- 代码可读性如何?
- 代码容易维护么?
- 代码的每一行都执行并检查过了吗?
- 设计规范部分
- 设计是否遵从已知的设计模式或项目中常用的模式?
- 有没有硬编码或字符串/ 数字等存在?
- 代码有没有依赖于某一平台,是否会影响将来的移植
- 开发者新写的代码能否用已有的Library/SDK/Framework中的功能实现?在本项 目中是否存在类似的功能可以调用而不用全部重新实现?
- 有没有无用的代码可以清除?
- 具体代码部分
- 有没有对错误进行处理?对于调用的外部函数,是否检查了返回值或 处理了异常?
- 参数传递有无错误,字符串的长度是字节的长度还是字符(可能是单/ 双字节)的长度,是以0 开始计数还是以1 开始计数?
- 边界条件是如何处理的?switch语句的default分支是如何处理的?循环 有没有可能出现死循环?
- 有没有使用断言(Assert)来保证我们认为不变的条件真的得到满足?
- 对资源的利用,是在哪里申请,在哪里释放的?有无可能存在资源泄 漏(内存、文件、各种GUI资源、数据库访问的连接,等等)?有没有优 化的空间
- 数据结构中有没有用不到的元素?
- 效能
- 代码的效能(Performance)如何?最坏的情况是怎样的?
- 代码中,特别是循环中是否有明显可优化的部分
- 对于系统和网络的调用是否会超时?如何处理?
- 可读性
- 代码可读性如何?有没有足够的注释?
- 代码是否需要更新或创建新的单元测试?针对特定领域的开发 (如数据库、网页、多线程等),可以整理专门的核查表。
结对编程¶
- 好处
- 坏处
软件测试¶
软件测试的概述¶
- 软件测试是指在一些特定条件下观察、执行应用 程序,以发现其中的错误
- 测试有助于保护应用程序,避免潜在的、可能会 对应用程序和将来的组织造成危害的危险因素。
- 软件测试关键在于测试用例的设计生成和执行。
- 软件测试是软件开发时期的最后一个阶段,也是软件质量保障中最重要的一个环节
原则¶
- 一是测试显示缺陷存在,但不能证明系统不存在缺陷;
- 二是穷尽测试是不可能的,应设定及时终止的条件;
- 三是软件测试应该尽早进行;
- 四是缺陷具备群集特性,与开发人员的编程水平、习惯 有密切关系;
- 五是测试的杀虫剂悖论,要不断修改测试用例;
- 六是测试的“二八原则”,把80%的资源、精力放在 20%的重点模块上;
- 七是测试活动依赖于测试背景,比如金融行业对软件安全性的要求会更高,需要进行有针对性的测试。
Bug¶
- 从产品内部看,缺陷是软件产品开发或维护过程中存在的错误、毛病 等各种问题;从产品外部看,缺陷是系统所需要实现的某种功能的失效或违背。
- 分类
- Failure(失败):指系统展示出的不可接受的行为。当系统无法按照预期工作或达到所需的功能时,就会发生失败。
- Frequency of failures(故障频率):用于衡量可靠性的故障发生次数。低故障率和高可靠性是一个重要的设计目标。
- Defect(缺陷):指系统中任何方面的缺陷,可能导致一个或多个失败的发生。缺陷可能存在于需求、设计和代码等方面,通常需要多个缺陷才能导致特定的失败。
-
Error(错误):是软件开发人员犯的一个错误或不适当的决策,导致引入一个缺陷。编码中的错误被称为错误,由测试人员发现的错误被称为缺陷,如果开发团队接受了该缺陷,则被称为 bug。
-
Bug包含三个方面
- 症状(Symptom)
- 从用户的角度看,软件出了什么问题
- 程序错误(Fault)
- 从代码的角度看,代码的什么错误导致了软件的 问题
- 根本原因(Root cause)
- 错误根源,即导致代码错误的根本原因。
- 报告
- 一是bug的标题,要简明地说明问题;
- 二是bug的内容,要写在Description中,包括测试的 环境和准备工作、测试的步骤(需清楚地列出每一步 做了什么)、实际发生的结果、(根据规格说明和用户 的期望)应该发生的结果;
- 三是补充材料,例如相关联的bug、输出文件、日志 文件、调用堆栈的列表、截屏等,保存在bug相应的 附件或链接中;
- 四是设置bug的严重程度(Severity)、功能区域等,这 些都可在不同的字段中记录。
- 严重程度
- 生命周期
- 报告症状
- 理解问题,决定如何、何时进行修复(设定优先级)
- 修复bug
- 代码检查,确保质量
-
测试,确定bug已经被解决
-
测试者
-
一是检查与规格说明书的一致性(现实中很多测试新 手就止步于此了);
-
二是处理反向案例/错误,查看被测系统有无crash/有 无log/能否恢复,并检查出错信息是否有用,相关案 例有:网络变慢、接口超时、资源被阻塞、对象引用 失效或对象无法初始化、XML与schema不一致、用 户不是管理员等;
-
三是进行用户体验,从用户角度出发,检查是否给用 户传递了好的体验。
软件质量¶
- 软件质量重要性
- 低质量的软件更难于维护和支持
- 需要更多的客服、打补丁、安排额外版本发布
- 法律问题(被告)
- 降低公司的声誉
- 什么是软件质量
- 质量的一些方面是客观的,比如要求具有稳定性/无缺陷,或者 和规格说明保持一致
- 质量的一些方面又是主观的,比如对客户的整体价值/满足客户 的需求,或者愉快的终端用户体验、情感价值,使得客户产生 更多的需求。
- 但无缺陷并不等同于高质量。
- 在激烈的竞争市场上,质量是用于区分你和你的竞争对手的。
软件测试的流程和类别¶
- 可以从正反两个方向来考虑:正向是验证软件正常工作;反向是假定软件有缺陷,通过试图破坏或摧毁系统的方式来查找软件中的问题。
- 定义
- 软件测试是对程序能够按预期运行建立起的一种信心,这是 Bill Hetzel 1973年给出的早期定义 。
- 测试是为发现错误而执行程序的过程,这是Myers1979年给 出的经典定义 。
- 使用人工或自动手段来运行或测量软件系统的过程,其目的 在于检验它是否满足规定的需求,并弄清预期结果与实际结果之间 的差别,
- 软件测试是根据软件开发各阶段的规格说明和程序的内部结 构而精心设计一批测试用例,并利用这些测试用例去执行程序,以 发现软件故障的过程。该定义强调寻找故障是测试的目的 。
- 软件测试是一种软件质量保证活动,其动机 是通过一些经济 有效的方法,发现软件中存在的缺陷,从而保证软件质量。
- 目的
- 测试
- 目的是发现程序错误;任务是通过在计算机上执行程 序,暴露程序中潜在的错误。
- 纠错
- 目的是定位和纠正错误;任务是消除软件故障, 保证程序的可靠运行。
- 特点
- 开销大。按照Boehm的统计,软件测试开销大约占总成本的30%到50%。
- 不能进行穷举测试。只有将所有可能情况到测试到才有可能检查出所有错误,但这是不可能的。
- 难度大。由于不能执行穷举测试,只能选择高效的测试用例。
- 特性
- 挑剔性:测试是对质量的监督与保证,所以“挑短”和“揭 短”很自然成为测试人员奉行的信条。
- 复杂性:设计测试用例是一项需要细致和高度技巧的工作。
- 不彻底性:程序测试只能证明错误存在,但不能证明错误不存在
- 经济性:选择一些典型的、有代表性的测试用例,进行有限测试。
流程¶
- 首先需要构造输入
- 一是软件配置,包括软件需求规格说明、软件设计规格说明、 源代码等;
- 二是测试配置,包括测试计划、测试用例、测试驱动程序等, 从整个软件工程过程看,测试配置是软件配置的一个子集;
- 三是测试工具,为了提高软件测试效率,测试配置需要有测试 工具的支持,它们的工作是为测试的实施提供某种服务,以减 轻人们完成测试任务中的手工劳动
- 测试之后,要对所有结果进行分析,即将测试的结果与 预期的结果进行比较。
- 如果发现出错的数据,就意味着软件有错误,然后就需要开始 排错
- 修正后的程序和文档都要经过再次测试,直到通过测试为止。
- 通过收集和分析测试结果数据,开始对软件建立可靠性 模型。
- 如果经常出现需要修改设计的严重错误,那么软件质量和可靠 性就值得怀疑,同时也表明需要进一步测试。
- 最后,如果测试发现不了错误,那么错误最终不得不由 用户在使用中发现,并在维护时由开发者去改正。
类别¶
- 功能测试
- 非功能测试
模型¶
- v模型
- 软件开发过程是一个自顶向下、逐步细化的过程,而测 试则是依相反的顺序安排的,自底向上、逐步集成,低 一级为上一级测试准备条件。
- x模型
- 主要用于解决交接和频繁集成的周期问题。
软件测试工具¶
-
软件测试不是只在项目的最后进行就可以,当你在项目后期发现了问题,问题的根源往往是项目的 早期的一些决定和设计,这时候再要对进行修改就比较困难了。这要求测 试人员从项目开始就要积极介入,从源头防止问题的发生。
-
手工测试由专门的测试人员从用户视角来验证软件是否 满足设计要求的行为,更适用于针对深度的测试和强调主观判断的测试,一般在众包测试、探索式测试中使用
- 手工测试容易发现缺陷、容易实施,创造性、灵活性高,但覆盖量化较为困难,要重复测试,效率较低,另外前后测试会存在不一致性,可靠性低,对人力资源依赖程度高,主要取决于测试者的能力和水平。
- 自动化测试需要使用单独的测试工具软件控制测试的自 动化执行以及对预期和结果进行自动检查,一般在单元 测试、接口测试和性能测试方面使用得较多。
- 自动化测试效率高、速度快,用例可反复执行,复用程度高, 覆盖率容易度量,较为准确、可靠且不知疲劳,但非常机械, 没有创造性,不够灵活,发现缺陷的数量较低,而且一次性的投入非常大。
- 静态测试工具(通常集成程序理解功能):主要集中在需求文档、设计文档及程序结构上,可以进行类型分析、 接口分析、输入输出规格说明分析等。
- 动态测试工具:功能确认与接口测试、覆盖率分析、性能分析、内存分析等。
- 测试设计工具:说明测试被测软件特征或特征组合的方法,确定并选择相关测试用例的过程。
- 测试开发工具:将测试设计转换成具体的测试用例的过程
- 测试管理工具:帮助完成测试计划,跟踪测试运行结果等。用途:测试用例管理、缺陷跟踪管理、配置管理。
测试方法¶
白盒测试¶
- 在设计测试的过程中,设计者可以“看到”软件系统的内部结构,并且使用软件的内部知识来指导测试数据及方法的选择。 “白箱”并不是一个精确的说法,因为把箱子涂成白色,同样 也看不见箱子里的东西。有人建议用“玻璃箱”来表示。
覆盖测试法¶
- 语句覆盖
- 语句覆盖”是一个比较弱的测试标准,它的含义 是:选择足够的测试用例,使得程序中每个语句 至少都能被执行一次。
- 分支覆盖(分支覆盖)
- 比“语句覆盖”稍强的覆盖标准是“分支覆盖 ”(或称判定覆盖)。含义是:执行足够的测试用 例,使程序中的每一个分支至少都通过一次。
- 条件覆盖
- 使每个条件可能的结果都出现
- “条件覆盖”通常比“分支覆盖”强,因为它使 一个判定中的每一个条件都取到了两个不同的结果,而判定覆盖则不保证这一点。(但不是一定的)
- “条件覆盖”并不包含“分支覆盖”,如对语句 IF(A AND B)THEN S 设计测试用例使其满足“ 条件覆盖”,即使A为真并使B为假,以及使A 为假而且B为真,但它们都未能使语句S得以执 行
- 分支/条件覆盖
- 执行足够的测试 用例,使得分支中每个条件取到各种可能的值, 并使每个分支取到各种可能的结果。
- 条件组合覆盖
- 执行足够的例子,使得每 个判定中条件的各种可能组合都至少出现一次。
- “条件组合覆盖”的测试用例是一定满 足“分支覆盖”、“条件覆盖”和“分支/条件覆 盖”的。
- 上面四个例子虽然满足条 件组合覆盖,但并不能覆盖程 序中的每一条路径,例如路径 acd就没有执行,因此,条件组 合覆盖标准仍然是不彻底。
路径测试法¶
-
路径测试就是设计足够的测试用例覆盖程序中每一 条可能的程序执行路径至少测试一次,如果程序中含有 循环(在程序图中表现为环),则每个循环至少执行一次
-
程序图
-
语句覆盖可以看作点覆盖;判定覆盖可以看作边覆盖,而路径覆盖显然包括了这两项
-
循环的测试
-
单循环结构的测试:
- 零次循环,即不执⾏循环体,直接从循环⼊⼝跳到出⼝;
- ⼀次循环,循环体仅执⾏⼀次,主要检查在循环初始化中可 能存在错误;
- 典型次数的循环;
- 最⼤值次循环,如果循环次数存在最⼤值,应按次最⼤值进 ⾏循环,需要时还可以增加比最⼤次数少⼀次或多⼀次的循环 测试
-
多重嵌套循环:
- 可以对某⼀指定的循环层遍历单循环测试, ⽽在其它各循环层取最小或典型次数进⾏循环测试
-
选择测试路径的原则
-
选择具有功能含义的路径;
- 尽量用短路径代替长路径;
- 从上⼀条测试路径到下⼀条测试路径,应尽量减少变动 的部分(包括变动的边和节点);
- 由简⼊繁,如果可能,应先考虑不含循环的测试路径, 然后补充对循环的测试;
- 除非不得已(如为了要覆盖某条边),不要选取没有明显 功能含义的复杂路径。
黑盒测试¶
- 在设计测试的过程中,把软件系统当作一个“黑箱”,无法了解或使用系统的内部结构及知识。一个更准确的说法是 “Behavioral Test Design”,从软件的行为,而不是内部结 构出发来设计测试
- 黑盒测试方法是在程序接口上进行测 试,主要是为了发现以下错误:
- 是否有不正确或遗漏了的功能?
- 在接口上,输入能否被正确地接受? 能 否输出正确的结果?
- 是否有数据结构错误或外部信息(例如数 据文件)访问错误?
- 性能上是否能够满足要求?
- 是否有初始化或终止性错误?
- 黑盒测试法是根据被测程序功能来进行测试,所以通常也称为功能测试。用黑盒测试法设计测试用例,有4种常用 技术。
- 等价分类法
- 边界值分析
- 决策树法
- 因果图法
等价分类法¶
- 把输入数据的可能值划分为若干个等价类,使每类中的任何一个测试用例,都能代表同一等价类中的其它测试用例。
- 等价类是指某个输入域的子集合。在该集合中,各个 输入数据对于揭露程序中的错误都是等价的
- 每⼀⽆效等价类⾄少要用⼀个测试用例,不然可能漏掉某⼀ 类错误,但允许若⼲个有效等价类合用⼀个测试用例,以便 进⼀步减少测试的次数。
- 有效等价类
- 是指对于程序的规格说明来说,是合理的有意义的输入数据构成的集合。利用它可以检 验程序是否实现预先规定的功能和性能。
- 无效等价类
- 是指对于程序的规格说明来说,是不合理的无意义的输入数据构成的集合。程序员主要 利用这一类测试用例来检查程序中功能和性能 的实现是否不符合规格说明要求。
- 划分标准
- 完备测试、避免冗余;
- 划分等价类重要的是:集合的划分,划分为 互不相交的一组子集,而子集的并是整个集合;
- 并是整个集合:完备性
- 子集互不相交:保证一种形式的无冗余性;
- 同一类中标识(选择)一个测试用例,同一 等价类中,往往处理相同,相同处理映射到"相 同的执行路径"。
- 确定等价类的原则
- 如果输入条件规定了取值范围,或者是值 的个数,则可以确立一个有效等价类和两个无效 等价类。(左溢出和有溢出)
- 如果输入条件规定了输入值的集合,或 者是规定了“必须如何”的条件,这时可确立一 个有效等价类和一个无效等价类。(在不在集合中)
- 如果输入条件是一个布尔量,则可以确定 一个有效等价类和一个无效等价类。
- 如果规定了输入数据是一组值,而且程 序要对每个输入值分别进行处理。这时可为每一 个输入值确立一个有效等价类,此外再针对这组确 立一个无效等价类,它应是所有不允许输入值的 集合。
- 、如果确知,已划分的等价类中各元素 在程序中的处理方式不同,则应将此等价类 进一步划分成更小的等价类。
- 例
边界值分析¶
- 实践表明,程序员在处理边界情况时,很容易因忽略或考虑 不周发生编码错误。例如,数组容量、循环次数以及输入数据 与输出数据在边界值附近时,程序出错概率往往较大。
- 采用边界值分析法就是要这样来选择测试用例,使得被测试程序能在边界值及其附近运行,从而更有效地暴露程序中潜在 的错误
- 划分:最小值、 略高于最小值、 正常值、 略低于最大值、 最大值。(以及超出范围的值)
- 原则
- 如果输入条件规定了值的范围,则应取刚达到这个范围的边界的值以及刚刚超越这个范围边界的值作为测试输入数据。
- 如果输入条件规定了值的个数,则用最大个数、最小个数 、比最小个数少1、比最大个数多1的数作为测试数据
- 如果程序的规格说明给出的输入域或输出域是有序集合,则应选取集合的第一个元素和最后一个元素作为测试用例
- 如果程序中使用了一个内部数据结构,则应当选择这个内 部数据结构的边界上的值作为测试用例。
决策树法¶
- 基本概念
- 条件桩:列出各种可能的单个条件
- 条件条目:针对各种条目给出组合的情况
- 行动桩:列出可能的单个动作
- 行动条目:列出条件组合下应该采取的动作
- 有限条目决策表:所有条件都是二叉条件的决策表。
- 扩展条目决策表:条件有多个值的对应的决策表。
因果图法¶
- 因果图是借助图形来设计测试用例的一种系 统方法。它适用于被测程序具有多种输入条件, 程序的输出又依赖于输入条件的各种组合的情况。
-
因果图是一种简化的逻辑图,它能直观地 表明程序输入条件(原因)和输出动作(结果) 之间的相互关系
- 转化为判定表
错误猜测法¶
- 猜错就是猜测被测程序放在哪些地方容易出错,然后 针对可能的薄弱环节来设计测试用例。
- 比前几种方法更多地依靠测试人员的直觉与经验。
- 一般先用等价分类法和边界值分析法设计测试用例, 然后用猜错法补充一些例子作为辅助的手段。