软件的本质
软件的本质
现在的软件具有产品和产品交付载体的双重作用。
- 作为产品,软件显示了由计算机硬件体现的计算能力,或者说显示的是由一个可被本地硬件设备访问的计算机网络体现的计算潜力。软件扮演着信息转换的角色;产生、管理、获取、修改、显示或者传输各种不同的信息
- 作为产品生产的载体,软件提供了计算机控制(操作系统)、信息通信(网络)、以及应用程序开发和控制(软件工作和环境)的基础平台
软件提供了我们这个时代最重要的产品——信息。
软件的定义
来自教科书的关于软件的定义也许是:
软件是
- 指令的集合(计算机程序),通过执行这些指令可以满足预期的特性、功能和性能需求
- 数据结构,使得程序可以合理利用信息
- 软件描述信息,它以硬拷贝和虚拟形式存在,用来描述程序的操作和使用
==软件=程序+数据+文档==
软件不会磨损,但是软件退化的确存在。
在完整生命周期里,软件将会面临变更,每次变更都可能引入新的错误。可以说,不断的变更是软件退化的根本原因。
软件应用领域
今天,计算机软件可分为七大类
- 系统软件——整套服务于其他程序的程序
- 应用软件——解决特定非业务需要的独立应用程序
- 工程/科学软件——“数值计算”类程序涵盖了广泛的应用领域
- 嵌入式软件——存在于某个产品或者系统中,可实现和控制面向最终用户和系统本身的特性和功能
- 产品线软件——为多个不同用户的使用提供特定功能
- Web/移动APP——以网络为中心,其概念涵盖了宽泛的应用软件产品
- 人工智能软件——利用非数值计算算法解决计算和直接分析无法解决的复杂问题
现在人们认为:在信息产业中,微电子是基础,计算机和网络是载体,软件是核心。
软件的变更本质
四大类软件不断演化,在行业中占有主导地位。这四类软件在十几年前还处于初级阶段
- WebApp——基于Web的系统和应用软件
- 移动App——通常包括用户接口、用户接口利用移动平台所提供的独特交互机制,基于Web资源的互操作性提供方与App相关的大量信息的访问,并具有本地处理能力,以最适合移动平台的方式收集、分析和格式化信息
- 云计算——包括基础设施或”生态系统”,能使得任何用户在任何地点都可以使用计算设备来共享广泛的计算资源。
- 产品线软件——一系列软件密集型系统可以,可以共享一组公共的可管理的特性,这些特性可以满足特定市场或任务的特定需求,并以预定的方法从一组公共的核心资源开发出来。
软件工程
软件危机
软件危机是:在计算机软件的开发和维护过程中所遇到的一系列严重问题(效率和质量下降)。
- 项目超出预算
- 项目超过计划完成时间
- 软件运行效率很低
- 软件质量差
- 软件通常不符合要求
- 项目难以管理并且代码难以维护
- 软件不能交付
产生原因
- 客观:软件本身特点
- 逻辑部件规模庞大
- 主观:不正确的开发方式
- 忽略需求分析
- 错误认为:软件开发=程序编写
- 轻视软件维护
消除软件危机的途径:软件工程!
软件工程
软件工程定义
软件工程概念的提出:目的是倡导以工程的原理、原则和方法进行软件开发,以解决软件危机。
计算机百科全书上的软件工程定义:
应用计算机科学、数学及管理科学等原理,以工程化方法制作软件的工程。它借鉴传统工程的原则、方法,创建软件以达到提高质量,降低成本的目的。
其中,计算机科学、数学用于构建模型与算法,工程科学用于指定规范、设计范型、评估成本及确定权衡,管理科学用于计划、资源质量、成本等管理。
软件工程是一门指导计算机软件开发和维护的工程学科。软件工程是一门交叉性学科。
首次NATO会议上的软件工程定义:
软件工程是用来建立和使用合理的工程原则,以经济地获取可靠的、且在真实机器上可高效工作的软件。
IEEE[IEE93]中的软件工程定义:
(1) 将系统化的、规范的、可量化的方法应用于软件的开发、运行和维护,即 将工程化方法应用于软件;
(2) 对 (1) 中所述方法的研究。
目标是在给定的预算内,按照用户的需求,开发易修改、高效、可靠、可维护、适应力强、可移动、可重用的软件。
软件工程框架
软件工程可定义为三元组:<目标,原则,活动>
- 给出了软件所涉及软件工程的工程要素
- 给出了各要素之间的关系
- 给出了软件工程学科所研究的主要内容
软件工程目标
目标:生产具有正确性、可用性以及开销合益的产品。
- 正确性:意指软件产品达到预期功能的程度
- 可用性:意指软件基本结构、实现及文档为用户可用的程度
- 开销合益:指软件开发、运行的整个开销满足用户要求的程度
软件工程的活动
活动:生产一个最终满足要求且达到工程目标的软件产品所需要的步骤
- 主要包括:==需求、设计、实现、确认和支持==等活动。
需求
定义问题:即建立系统模型
主要任务包括:
需求获取
需求定义(即定义问题)系统功能的一个正确的陈述
需求规约:系统需求规格说明 》主要成分:系统模型系统功能的一个精确、系统的描述。
需求验证:验证需求陈述和需求规约之间的一致性、完整性和可跟踪性。
设计
在需求分析的基础上,给出系统的软件设计方案。
设计包括:总体设计(也称为概要设计)和详细设计
- 总体设计:建立整个软件体系结构
- 包括子系统、模块(或构件)以及相关层次的说明、每一模块(或构件)的接口定义。
- 体系结构类型可分为:层次模块体系结构、C/S体系结构、以数据库为中心的体系结构、管道结构和面向对象的结构等
- 详细设计:针对总体设计的结果,给出体系结构中每一模块或构件的详细描述
- 即给出它们的数据结构说明和实现算法
实现
把设计结果转换为可执行的程序代码
具体做法分为两种:
- 选择可用的模块或构件或以一种选定的语言,对每一模块或构件进行编码
确认
确认活动贯穿于整个开发过程
实现完成后的确认,确保最终产品满足用户的需求。
确认活动主要包含:需求复审、设计复审以及程序测试。主要任务是:软件测试。
支持
支持活动包括修改和完善
它为系统的运行提供完善性维护、纠错性维护和适应性维护。
软件过程
软件生命周期
定义:软件产品或软件系统从设计、投入使用到被淘汰的全过程。
软件过程
软件过程是在工作产品构建过程中,为创建高质量软件所需完成的工作活动、动作和任务的集合(框架)。
==活动==主要实现宽泛的目标,与应用领域、项目大小、结果复杂性或者实施软件工程的重要程度没有直接关系
==动作==包含了主要工作产品生产过程中的一系列任务
==任务==关注小而明确的目标,能够产生实际产品。
软件过程模型
最早提出过程模型是为了改变软件开发的混乱状态,使软件开发更加有序。历史证明,这些模型为软件过程提出了大量有用的结构,并为软件团队提供了有效的路线图。
在一篇探讨软件世界中有序和混乱之间奇怪关系的论文中指出:
混乱的边缘可定义为”有序和混乱之间的一种自然状态,结构化和反常之间的重大妥协。“混乱的边缘可以被视为一种不稳定和部分结构化的状态······它的不稳定是因为它不停的受到混乱或者完全有序的影响
我们通常认为有序是自然的完美状态。这可能是个误区······研究证实,打破平衡的活动会产生创造力、自我组织的过程和更高的回报。完全的有序意味着缺乏可变性而可变性在某些不可预测的环境下往往是一种优势。变更通常发生在某些结构中,这些结构使得变更可以被有效组织,但还不是死板得使得变更无法发生。另一方面,太多的混乱会使协调和一致成为不可能。缺少结构并不意味着无序。
本章所描述的每一个过程模型都**==试图在找出混乱世界中的秩序和适应不断发生的变化这两种要求之间寻求平衡。==**
定义
是软件开发全部过程、活动和任务的结构框架。它能直观表达软件开发全过程,明确规定要完成的主要活动、任务和开发策略。
也被称为:
- 软件开发模型
- 软件生存周期模型
- 软件工程范型
能力成熟度模型 CMM
惯用过程模型
惯用过程模型力求达到软件开发的结构和秩序,其活动和任务都是按照过程的特定指引顺序进行的。
接下来讨论的软件过程模型支持之前提到的软件过程通用框架活动,但是每一个模型都对框架活动有所侧重,并且定义了不同的过程流以不同的方式执行每一个框架活动(以及软件工程动作和任务)
瀑布模型(Waterfall model)
- 可行性研究
- 需求分析
- 总体设计
- 详细设计
- 编码
- 单元测试
- 系统测试
- 验收测试
- 运行与维护
- 验收测试
- 系统测试
- 单元测试
- 编码
- 详细设计
- 总体设计
- 需求分析
特点
- 第一个软件过程模型。是一种使用广泛,以文档为驱动的模型
- 软件开发过程与软件生命周期一致:也称为经典生命周期模型
- 规定了各项软件工程活动,以及它们自上而下,相互衔接的固定次序,如同瀑布流水,逐级下落
- 线性模型:阶段具有顺序性和依赖性。推迟实现的观点
- 每个阶段都有与其相关联的里程碑和可交付产品
- 每个阶段结束前完成文档审查,及早改正错误
待反馈的瀑布模型
缺点
==增加工作量==
各个阶段的划分完全固定,阶段之间产生大量的文档,极大增加了工作量
==开发风险大==
由于开发模型是线性的,用户只有等到整个过程的末期才能见到开发成果,从而增加了开发的风险
==早期错误发现晚==
早期的错误可能要等到开发后期的测试阶段才能发现,进而带来严重的后果
==不适应需求变化==
不能反应实际的开发方式,软件开发需要迭代;无法适应需求不明确的需求的变化
使用场合
- 系统需求明确且稳定
- 技术成熟
- 工程管理较严格的场合如军工、航天、医疗
V-模型(V-model)
瀑布模型的变种:描述了质量保证动作同沟通。建模相关动作以及早期构建相关的动作之间的关系。提供了一种将验证和确认动作应用于早期软件工程工作中的直观方法。
原型模型
也称为:原型化模型、快速原型模型
==原型(prototype)==
- 一个部分开发的产品,使客户和开发人员能够对计划开发的系统的相关方面进行检查。
==原型化目的==
- 明确并完善需求,如演示原型
- 研究技术选择方案,如技术验收原型
==原型结果==
- 抛弃原型
- 把原型发展成最终产品
==举例==
- 图书借阅系统:主要界面
- 智能家居系统:少量的室内信息监视和电器控制
优点
减少需求不明确带来的风险
缺点
- 构造原型采用的技术和工具不一定主流
- 快速建立起来的系统加上连续的修改可能导致原型质量低下
- 设计者在质量和原型中进行折中
- 客户意识不到一些质量问题
使用场景
- 客户定义一个总体目标集,但是它们并不清楚系统的具体输入输出;或开发者不确定算法的效率、软件与操作系统是否兼容以及客户与计算机交互的方式
- 此时,原型模型是很好的选择
增量模型
增量:满足用户需求的一个子集,能够完成一定功能、小而可用的软件
举例
文字处理软件:创建文本、组织文本、格式化文本
第一个增量,创建文本->第一个发布:创建文本;->第二个增量,组织文本->第二个发布:创建文本、组织文本。->第三个增量······
特点
- 增量模型是一种非整体开发的模型,是一种进化式的开发过程
- 增量模型从部分需求触发,先建立一个不完整的系统,通过测试运行这个系统取得经验和反馈,进一步使系统扩充和完善
- 如此反复,直到软件人员和用户对软件系统满意
- 增量模型结合了原型模型的基本要素和迭代的特征,采用了基于时间的线性序列,每个线性序列都会输出该软件的一个”增量”
- 每个增量的开发可用瀑布或快速原型模型
优点
- 增量概念的引入,不需要提供完整的需求,只要有一个增量出现,开发就可以进行
- 软件能更早投入市场
- 开放式体系结构,便于维护
- 在项目的初始阶段不需要投入太多的人力资源
- 产品逐步交付,软件开发能够较好地适应需求的变化
- 能都看到软件中间产品,提出改进意见,减少返工,降低开发风险
缺点
- 每个增量必须提供一些系统功能,这是的开发者很难根据客户需求给出大小合适的增量
- 软件必须具备开放式体系结构(困难)
- 易退化成边做边改的方式,使软件过程控制失去整体性
使用场合
适用于软件开发中需求可能发生变化、具有较大风险、或者希望尽早进入市场的项目
螺旋模型
问题
- 软件开发普遍存在风险
- 交付的产品用户不满意
- 产品不能按时交付
- 开发成本超过预算
- 产品开发期间关键开发人员离职
- 产品投入市场前竞争对手发布功能相近价格更低产品
- ···
把开发活动和风险管理结合起来控制风险
螺旋模型
开发过程分为若干次迭代,每次迭代代表开发的一个阶段,对应模型中一条环线
每次迭代分成四个方面的活动,对应四个象限
- 确定本阶段目标,选定实施方案,弄清项目开发的限制条件
- 评估所选方案,通过构造原型和风险分析识别和消除风险
- 实施软件开发和验证
- 评价本阶段的工作成果,提出修正建议,并计划下一阶段工作。
模型结合了瀑布模型和原型模型的特点
优点
- 强调原型的可扩充性和可修改性,原型的进化贯穿整个软件生命周期,这将有助于目标软件的适应能力,支持用户需求的动态变化
- 原型可看做可执行的需求规格说明,易于为用户和开发人员共同理解,还可以作为继续开发的基础,并为用户参与所有关键决策提供了方便
- 螺旋模型为项目管理人员及时调整管理决策提供了方便,进而可降低开发风险
缺点
- 如果每次迭代的效率不高,将导致迭代次数过多,将会增加成本并推迟交付时间
- 需要有相当丰富的风险评估经验和专门知识,要求开发队伍水平较高,否则会到来更大风险。
适用场合
需求不明确可能发生变化的大型复杂的软件系统
支持面向过程、面向对象等多种软件开发方法,是一种具有广阔前景的模型
喷泉模型
是一种以用户需求为动力,以对象为驱动的模型,主要用于描述面向对象的软件开发过程
软件开发早期定义对象,整个开发过程充实和扩充对象
各个阶段使用统一的概念和表示方法,生命周期各阶段无缝连接
各个开发步骤多次反复迭代
优点
各个阶段有明显的界限,开发人员可以同步进行开发,可以提高软件项目开发效率,节省开发时间,适用于面向对象的软件开发过程
缺点
喷泉模型在各个开发阶段是重叠的,在开发过程总需要大量的开发人员,因此不利于项目的管理
喷泉模型要求严格管理文档,使得审核的难度加大,尤其死面对可能随时加入的各种信息、需求与资料的情况
适用场合
面向对象开发
软件过程模型的选择
专用过程模型
专用过程模型具有前面提到的传统过程模型的一些特点,但是,专用过程模型往往应用较窄且专一,只适用于某些特定的软件工程方法
基于构件的开发模型
Component-bases development model,近年来得到广泛关注,改变大型软件开发方式。
考虑的焦点是集成,而非实现
- 构件/组件(Component)
- 系统中模块化的、可更换的部分
- 实现特定的功能
- 对实现进行封装,暴露一组接口
- 例如:动态链接库(.dll),浏览器插件
过程
==需求分析==
与其他过程模型相同
==构件分析==
根据需求搜索构件,如果没有完全匹配的构件,则需要修改构件或者修改需求
==系统设计==
与其他过程模型不同,考虑重用和集成,如果没有可重用的构件,则设计新软件
==开发集成==
将构件集成到系统中
开发新软件
优点
- 软件复用思想
- 降低开发成本和风险,加快开发速度,提高软件质量
缺点
- 模型复杂
- 商业构件不能修改,会导致修改需求,进而导致系统不能完全符合客户需求
- 无法完全控制所开发系统的演化
- 项目划分的好坏直接影响项目结果的好坏
适用场景
适用于系统之间有共性的情况
统一过程
某种程度上,统一过程尝试着从传统的软件过程中挖掘最好的特征和性质,但是以敏捷软件开发中许多最好的原则来实现。
统一过程认识到与客户沟通以及从用户的角度描述系统(即用例)并保持该描述的一致性的重要性。它强调软件体系结构的重要作用,并“帮助架构师专注于正确的目标,例如可理解性、对未来变更的可适应性以及复用”。
Rational 统一过程模型
Rational Unified Process -RUP
由Rational公司(现已被IBM收购)退出的完整且完美的软件工程方法,获得广泛使用
- 基于面向对象方法学
- 使用统一建模语言UML(Unified Modeling Language)
过程
从三个视角描述软件开发过程
- 动态视角:随时间变化的各个阶段
- 静态视角:所进行的活动
- 实践视角:可采用的良好实践建议
适合大团队,大项目
最佳实践
==1.迭代式开发==
- 需求变更不可避免
- 每次迭代产生一个可交付版本,用户反馈,减少风险
- 根据客户的轻重缓急来规划增量,先开发和交付优先级最高的增量
==2.管理需求==
- 采用用例分析来不会需求,由用例驱动设计和实现
- 对需求及变更进行管理
==3.基于构件体系结构==
- 采用基于构件的体系结构
- 提高软件复用率
==4.可视化建模==
- 使用统一建模语言(UML)对系统进行可视化建模
==5.验证软件质量==
- 软件质量评估贯穿整个开发过程的所有活动
- 全体成员参与
==6.控制软件变更==
- 描述如何控制和跟踪软件的变更
敏捷开发
敏捷软件工程师哲学理念和一系列开发指南的综合。这种哲学理念推崇:让客户满意且尽早的增量发布;小而高度自主的项目团队;非正式的方法;最小化软件工程工作产品以及整体精简开发。
开发的指导方针强调超越分析和设计(尽管并不排斥这类活动)的发布,以及开发人员和客户之间主动和持续的沟通。
敏捷软件开发宣言
==个体交互==
个体和交互胜过过程和工具
==可工作软件==
可以工作的软件胜过面面俱到的文档
==客户合作==
客户合作胜过合同谈判
==响应变化==
响应变化胜过遵循计划(对变更的良好响应胜过了按部就班地遵循计划)
什么是敏捷
敏捷已经成为当今描述现代软件过程的时髦用词。每个人都是敏捷的。敏捷团队是能够适当响应变更的灵活团队。变更就是软件开发本身,软件构建有变更、团队成员有变更,各种变更会对项目造成影响。我们必须接收”支持变更”的思想。
敏捷团队意识到软件是团队中所有人共同开发完成的,这些人的个人技能和合作能力是项目成功的关键所在。
敏捷不仅仅是==有效地响应变更==,它还包含开头的宣言中提及的哲学观念的信奉。鼓励能够使沟通更便利的团队结构和协作态度。强调可运行软件的快速交付而不那么看中中间产品。
敏捷软件过程
敏捷软件过程是==基本原理==和==开发准则==的结合
==基本原理强调==
- 客户满意度和较早的软件增量交付
- 小但又激情的团队
- 非正式的方法
- 最小的软件工程产品
- 简化整体开发
==开发准则强调==
- 分析和设计的交付
- 开发者和客户之间积极持续的交流
极限编程
extreme programming - Xp
它是敏捷软件开发中使用最广泛的一种方法,目标是在大型组织内部使用敏捷过程。
把好的开发实践运用到极致
敏捷开发优点
- 快速响应变化和不确定性
- 可持续开发速度
- 适应商业竞争环境下的有限资源和有限时间
敏捷开发缺点
- 测试驱动开发可能导致通过测试但非用户期望
- 重构而不降低质量困难
需求分析
定义
确定系统必须具有的功能和性能,系统要求的运行环境,并且预测系统发展的前景。
换句话说需求就是以一种清晰、简洁、一致且无二义性的方式,对一个待开发系统中各个有意义方面的陈述的一个集合。
过程
需求确认
需求获取
需求提炼
需求描述
需求验证
需求变更
需求确认
需求获取
定义
软件需求获取指的是
- 软件需求的来源
- 软件工程师收集这些软件需求的方法
它也被称为需求抓取、需求发现和需求获得
类型
==功能性需求==
描述系统应该做什么,即为用户和其他系统完成的功能、提供的服务
==非功能需求==
必须遵循的标准,外部界面的细节,实现的约束条件,质量属性等等
需求提炼(需求分析)
定义
对应用问题及环境的理解和分析,为问题涉及的信息、功能及系统行为建立模型。将用户需求精确化、完全化,最终形成下一步的需求规格说明书。
- 需求提炼(需求分析)的核心在于建立分析模型
- 需求提炼(需求分析)采用多种形式描述需求,通过建立需求的多种视图,揭示出一些更深的问题。
- 需求提炼(需求分析)还包括与客户的交流以澄清某些易混淆的问题,并明确哪些需求更为重要,其目的是确保所有风险承担着尽早地对项目达成共识并对将来的产品有个相同而清晰的认识。
需求分析模型
需求规格说明书(需求描述)
定义
软件需求规格说明书(SRS)——软件系统的需求规格说明,是对待开发系统的行为的完整描述。它包含了功能性需求和非功能性需求。
- 需求分析工作完成的一个基本标志是形成了一份完整的、规范的需求规格说明书
- 需求规格说明书的编制是为了使用户和软件开发者双方对该软件的初始规定有一个共同的理解,使之成为整个开发工作的基础。
需求验证
重要性
如果在后续的开发或当系统投入使用时才发现需求文档中的错误,就会导致更大代价的返工。由需求问题而对系统做变更的成本比修改设计或代码错误的成本要大得多。假设需求阶段引入1个错误的需求,设计时对这个需求需要5-10条设计实现,1条设计需要5-10条程序,1条程序需要3-5种测试组合测试。
需求验证的工作
对需求文档需执行以下类型的检查:
- ==有效性检查==:检查不同用户使用不同功能的有效性
- ==一致性检查==:在文档中,需求之间不应该冲突
- ==完备性检查==:需求文档应该包括所有用户想要的功能和约束
- ==现实性检查==:检查保证能利用现有技术实现需求
需求验证技术
- 需求评审
- 利用原型检验系统是否符合用户的真正需要
- 对每个需求编写概念性的测试用例
- 编写用户手册。用浅显易懂的语言描述用户可见的功能
- 自动的一致性分析。可用CASE工具检验需求模型的一致性
需求变更
需求分析任务
- ==建立分析模型==:准确地定义未来系统的目标,确定为了满足用户的需求系统必须做什么
- ==编写需求说明==:用《需求规格说明书》规范的形式准确地表达用户的需求
软件需求规格文档
原则
- 从现实中分离功能,即描述要“做什么”而不是“怎样实现”
- 要求使用面向处理的规格说明语言(或称系统定义语言)
- 如果被开发软件只是一个大系统中的一个元素,那么整个大系统也包括在规格说明的描述之中
- 规格说明必须包括系统运行环境
- 规格说明必须是一个认识模型
- 规格说明必须是可操作的
- 规格说明必须容许不完备性并允许扩充
- 规格说明必须局部化和松散耦合
结构
- 引言
- 综合描述
- 需求描述
- 附录(词汇表、分析模型、特定问题列表)
- 索引
需求分析模型概述
==面向过程分析模型==
基本思想是用系统工程的思想和工程化的方法,根据用户至上的原则,自始至终按照”结构化、模块化、自顶向下“地对系统进行分析与设计
==面向对象分析模型==
由五个层次
- 主题层
- 对象类层
- 结构层
- 属性层
- 服务层
和五个活动
- 标识对象类
- 标识结构
- 定义主题
- 定义属性
- 定义服务
分析模型描述工具
面向过程的分析方法
分析建模工具
分析方法
- 面向数据流进行需求分析的方法
- 结构化分析方法适合于数据处理类型软件的需求分析
- 具体来说,结构化分析方法就是用抽象模型的概念,按照软件内部数据传递,变换的关系,自顶向下逐层分解,直到找到满足功能要求的所有可实现软件为止
数据模型-实体关系图
行为模型-状态转换图
**状态转换图(状态图)**通过描绘系统的状态及引起系统状态转换的事件,来表示系统的行为。
状态
一个状态代表系统的一种行为模式。
在状态图中定义的状态主要有:初态,终态和中间状态。一张状态图里面只有一个初态,可以有0至多个终态。
事件
事件是在某个特定时刻发生的事情,它是对引起系统做动作或(和)从一个状态转换到另一个状态的外界事件的抽象。例如,内部时钟表明某个规定的时间段已经过去,用户移动鼠标、点击鼠标等都是事件。
简而言之,事件就是引起系统做动作或(和)转换状态的控制信息。
符号
在状态图中,初态用实心圆表示,终态用一对同心圆(内圆为实心圆)表示。中间状态用圆角矩形表示,可以用两条水平横线把它分成上、中、下3个部分。上面部分为状态的名称,这部分是必须有的;中间部分为状态变量的名字和值,这部分是可选的;下面部分是活动表,这部分也是可选的。
结构化分析过程
==①建立系统的功能模型==
使用的工具为数据流图DFD
- 简历系统环境图(顶层数据流图)确定系统边界
- 自顶向下,逐步求精,建立系统的层次数据流图
==②建立数据字典==
使用的工具为结构符:“+、|、{ }“等
定义数据流
定义数据存储
定义数据项
==③给出加工小说明==
使用的工具可以是结构化自然语言、判定表、判定树
集中描述一个加工“做什么”,即加工逻辑,也保罗其他一些与加工有关的信息,如执行条件、优先级、执行频率、出错处理等
功能模型-数据流图
数据流图中的主要图形元素
数据流图实例
数据流图层次结构
加工
- 表示对数据进行的操作,如“处理选课单”,“产生发票”等
- 加工的编号,说明这个加工在层次分解中的位置
外部实体(数据源点/终点)
- 位于系统之外的信息提供者或使用者,称为外部实体。即存在于系统之外的人员或组织。如“学务科”等
- 说明数据输入的源点(数据源)或数据输出的终点(数据终点)
- 起到更好的理解作用,但不是系统中的事物
数据流
- 表示数据和数据流向, 由一组固定成分的数据组成。如“选课单”由“学号、姓名、课程编号、课程名”等成分组成
- 数据流可从加工流向加工,也可在加工与数据存储或外部项之间流动;两个加工之间可有多股数据流
数据流与数据加工之间关系
画分层数据流图的步骤
第一步:画系统的输入和输出(画出顶层图)
第二步:画系统内部
第三步:画加工内部
第四步:重复第3步,直至每个尚未分解的加工都足够简单(即不必再分解)
面向对象的分析方法
——一特定的软件开发方法学
面向对象方法是一种以对象、对象关系等来构造软件系统模型的系统化方法。
面向对象方法的世界观:一切系统都是由对象构成。
- 面向对象的分析(OOA)
- 面向对象的设计(OOD)
- 面向对象的程序设计(OOP)
著名面向对象方法
- Booch 方法( 1991 )
- Coad 一 Yourdon 方法( 1991 )
- Rumbaugh 方法(简称 OMT ) ( object Modeling Technology 1991 )
- Jacobson 方法(简称 OOSE , 1992 )
- 由 Rumbaugh 、 Booch 、 Jacobson 提出的统一建模语言 ( 简称UML ) ( Unify Modeling Language ,1994 )
UML
特点
- 统一标准:已成为面向对象的标准化的统一的建模语言
- 面向对象
- 可视化,表示能力强大
- 独立于过程
- 概念明确,建模表示简洁,容易掌握使用
支持
软件开发模型
==数据模型(对象模型)==
描述系统数据结构的对象模型;
==行为模型(动态模型)==
描述系统控制结构
==功能模型==
描述系统功能
一个典型的软件系统使用数据结构(数据模型),执行操作(行为模型),并且完成数据值的变化(功能模型)
功能模型——用例图
基本图形符号
用例建模用于描述系统需求,把系统当作黑盒,从用户的角度,描述系统的场景。主要图形元素有以下几个
- ==参与者==:是指外部用户或外部实体在系统中扮演的角色。可以是一个人、一个计算机子系统、硬件设备或者时间等角色
- ==用例==:对一组动作序列的描述,系统通过执行这一组动作序列为参与者产生一个可观察的结果。用例名往往用动宾结构命名。
- ==执行关联==:参与者(Actor )执行用例(Use Case)之间的关系
参与者(Actor)
- 参与者(actor)指系统以外的、需要使用系统或与系统交互的东西,包括人、设备、外部系统等
表示形式:
确定参与者
如饮料自动售货系统:参与者有顾客,供应商和收银员
用例(Use Case)
- 对一组动作序列的描述,系统通过执行这一组动作序列为参与者产生一个可观察的结果
- 用椭圆形表示
==特征==
- 说明了系统具有的一种行为模式
- 说明了一个参与者与系统执行的一个相关的事件序列
- 提供了一种获取系统需求的方法
- 提供了一种与最终的用户和领域专家进行沟通的方法
- 提供了一种测试系统的方法
获取用例
系统和关联
==系统==:用于界定系统功能范围,描述该功能的用例都置于其中,而描述外部实体的参与者都置于其外
==关联==:连接参与者与用例,表示参与者所代表的系统外部实体与该用例所描述的系统需求有关
初步实现
建立用例模型的顺序是:
- 确定谁会直接使用该系统。这些都是参与者(Actor)。选取其中一个参与者。
- 定义该参与者希望系统做什么,参与者希望系统做的每件事成为一个用例。
- 对每件事来说,何时参与者会使用系统,通常会发生什么,这就是用例的基本过程。描述该用例的基本过程。
用例扩展
- 考虑一些可变情况,把他们创建为扩展用例
- 复审不同用例的描述,找出其中的相同点,抽出相同点作为共同的用例
用例之间的关系
==泛化== (Inheritance)
就是通常理解的继承关系,子用例和父用例相似,但表现出更特别的行为;子用例将继承父用例的所有结构、行为和关系。子用例可以使用父用例的一段行为,也可以重载它。父用例通常是抽象的。
(子用例->父用例)
==包含== (Include)
包含关系用来把一个较复杂用例所表示的功能分解成较小的步骤。一个用例可以包含另外一个用例
(复杂功能用例->分解出来的功能用例)
==关联== (Association)
表示参与者与用例之间的通信,任何一方都可以发送或者接收消息。
(发送方->接收方)
注:参与者可以参与多个用例,由此形成子系统
==扩展== (Extend)
扩展关系是指用例功能的延伸,相当于为基础用例提供一个附加功能。由一个用例的扩展点可以扩展出另外一个用例。
(扩展用例->基础用例)
扩展和包含
- 在扩展关系中,一个基本用例执行时,可以执行、也可以不执行扩展用例部分
- 在包含关系中,在执行基本用例时,一定会执行包含用例部分
总结
成绩管理系统用例图
行为模型——活动图
活动模型
- 能够图形化显示用例的事件流
- 也能用于
- 在用例创建之前,在高层抽象上理解业务过程
- 在更低层抽象上,设计复杂的顺序算法或设计多线程应用中的并发
展示计算的步骤
- 每一步都是做某事的一个状态
- 执行步骤称为动作
- 描述哪些步骤被顺序执行、哪些可被并发地执行
- 控制流-控制从一个动作到下一个动作的流
开始与结束
==开始==
实心圆
==结束==
用“牛眼(bull’s eye)”符号表示
控制结点
- 控制节点是一种特殊的活动节点,用于在动作节点或对象之间协调流,包括分支与合并、分叉与汇合等。
- 分支及合并(钻石框) – 可选计算线程
分支与合并
分叉及汇合
泳道划分活动图
软件设计
软件设计概述
软件设计的概念
==定义==
软件设计定义为软件系统或组件的架构、构件、接口和其他特性的定义过程及该过程的结果。
软件设计是:
- 软件生命周期中的一个活动
- 进行软件编码的基础
- 软件需求分析被转化为软件的内部结构
- 是连接用户需求和软件技术的桥梁
软件工程中的设计
- 模型输入
- 软件需求的数据模型、功能模型和行为模型
- 分类
- 数据设计
- 架构设计
- 接口设计
- 组件设计
设计相关概念
- 抽象:是“忽略具体的信息将不同事物看成相同事物的过程“
- 体系结构:软件的整体结构和这种结构为系统提供概念上完整性的方式
- 设计模式:在给定上下文环境中一类共同问题的共同解决方案
- 模块化:软件被划分为命名和功能相对独立的多个组件(通常称为模块),通过这些组件的集成来满足问题的需求
- 信息隐藏:模块定义和设计时应当保证模块内的信息(过程和数据)不可以被不需要这些信息的其他模块访问
- 功能独立:每个模块只负责需求中特定的子功能,并且从程序结构的其他部分看,该模块具有简单的接口
- 精化:逐步求精的过程
- 重构:不改变组件功能和行为条件下,简化组件设计(或代码)的一种重组技术
面向对象设计
架构设计
架构设计的目的是要勾画出系统出总体结构,这项工作由经验丰富的架构设计师主持完成。
构造系统的物理模型
- 首先用UML的配置图(部署图)描述系统的物理结构
- 将需求分析阶段捕获的系统功能分配到这些物理结点上
- 配置图上可以显示计算节点的拓扑结构、硬件设备匹配、通信路径、各个节点上运行的系统软件配置、应用软件配置
例图:
设计子系统
- 对于一个复杂的软件系统来说,将其分解成若干个子系统,子系统内还可以继续划分系统或包,这种自顶向下、逐步细化的组织结构非常符合人类分析问题的思路
- 每个子系统与其他子系统之间应该定义接口,在接口上说明交互信息,注意这时还不要描述子系统的内部实现
- 可用UNL组件图表示
例图:
非功能需求设计
- 分析阶段定义了整个系统的非功能需求,在水果盒几阶段要研究这些需求,设计出可行的方案
- 非功能需求包括:
- 系统的安全性
- 错误检测和故障恢复
- 可移植性和通用性等
用例设计与类设计
- 根据分析阶段产生的高层类图和交互图,由用例设计师研究已有的类,将它们分配到相应的用例中
- 检查每个用例功能,依靠当前的类能否实现,同时检查每个用例的特殊需求是否有合适的类来实现
- 细化每个用例的类图,描述实现用例的类及其类之间的相互关系,其中的通用列和关键类可用粗线框区分,这些类将作为项目经历检查项目时的重点