浅学软件工程
三、软件过程模型
什么是软件过程模型?
软件过程模型是一种软件过程的抽象表示法。
软件过程模型是对软件开发的复杂过程的抽象描述,是从一个特定的角度表现一个过程一般使用直观的图形来表示软件开发的复杂过程。
传统的软件过程模型
瀑布模型
应用最广泛的过程模型。
瀑布模型是将软件生存周期的各项活动规定为按固定顺序(线性)而连接的若干阶段工作,最终得到软件产品。
因过程形如瀑布,因此得名瀑布模型。
特点:
- 顺序性和依赖性
- 推迟实现
- 质量保证
增量模型
**增量模型(incremental mode)**也称为渐增模型,是在项目的开发过程中以一系列的增量方式开发系统。
把待开发的软件系统模块化,将每个模块作为一个增量组件,从而分批次地分析、设计、编码和测试这些增量组件。
运用增量模型的软件开发过程是递增式的过程。
相对于瀑布模型,采用增量模型进行开发,开发人员不需要一次性地把整个软件产品提交给用户,而是分批次地进行提交。
螺旋模型
**螺旋模型(spiral model)**是由Barry Boehm正式提出的模型,它将瀑布模型和快速原型模型结合起来,不仅体现了两个模型的优点,而且还强调了其他模型均忽略的风险分析,特别适合于大型复杂的系统。
螺旋模型采用一种周期性的方法来进行系统开发。这会导致开发出众多的中间版本。项目经理在早期就能够为客户证实某些概念。该模型是快速原型法,以进化的开发方式为中心,在每个项目阶段使用瀑布模型。
这种模型的每一个周期都包括需求定义、风险分析、工程实现和评审4个阶段,由这4个阶段进行迭代。
面向对象模型
构件集成模型
构件集成模型利用模块化方法将整个系统模块化,并在一定构建模型的支持下重用构件库中的软件构件,通过组合手段提高应用软件系统过程的效率和质量。
构件集成模型融合螺旋模型的许多特征,本质上是演化型的,开发过程是迭代的。
统一过程模型
统一过程模型(Unified Process,UP)是风险驱动的、基于用例技术的、以架构为中心的、迭代的、可配置的软件开发流程。
UP是一个面向对象且基于网络的程序开发方法论。它可以为所有方面和层次的程序开发提供指导方针、模板以及用例支持。
统一过程模型是在重复一系列组成系统生存周期的循环。每一次循环包括4个阶段:初始、细化、构造和移交,每个阶段又进一步细分为多次迭代的过程,每次循环迭代会产生一个新的版本,每个版本都是一个准备交付的产品。
四、敏捷软件开发方法
Agile Software Development(敏捷软件开发)
什么是敏捷(Agile)?
敏捷是一种通过创造变化和响应变化在不确定和混乱的环境中取得成功的能力。
敏捷开发是一种应对快速变化的需求的一种软件开发能力。
敏捷是一个描述软件开发方法的术语,它强调增量交付、团队协作、持续规划和持续学习。
敏捷这个术语是2001年在敏捷宣言中提出的。
敏捷宣言
我们应重视:
- 个体和交互胜过流程和工具。
- 有效用的软件胜过全面的文档。
- 客户协作胜过合同协商。
- 响应变化胜过遵循计划。
在发表《敏捷宣言》之前,很多敏捷实践已经存在并使用了,例如:Scrum、XP、KanBan等。
发表《敏捷宣言》之后,有了统一的指导方针,形成了联合体的形式。
什么是敏捷软件开发(Agile Software Development)?
敏捷软件开发是基于敏捷宣言定义的价值观和原则的一系列方法和实践的总称。自组织、跨职能团队运用适合他们自身环境的实践进行演进得出解决方案。
敏捷不是指某一种具体的方法论、过程或框架,而是一组价值观和原则。
符合敏捷价值观和原则的开发方法包括:
- 极限编程(XP)
- Scrum
- 精益软件开发(Lean Software Development)
- 动态系统开发方法(DSDM)
- 特征驱动开发(Feature Driver Development)
- 水晶开发(Crystal Clear)
敏捷软件开发过程
- 需求计划:确定项目目标和需求
- 迭代规划:小步快跑的实现过程
- 计划冲刺:确定冲刺目标和任务
- 日常站会:保持沟通与协作
- 迭代审查:展示交付成果并获得反馈
- 迭代回顾:持续改进的机会
Scrum开发过程
定义与目的
Scrum本指橄榄球运动中的“争球”的动作——团队通力合作,在场地内传球。
以Scrum命名,目的是让开发人员像打橄榄球一样迅猛并充满激情,通过团队合作,提高工作效率。
Scrum就是以交付
和迭代
为核心的方法。
每过一小段时间就停下工作,检查一下已经完成了哪些任务,这些任务是不是应该自己做的,思考有没有更好的方法。
三个角色
Scrum中的人员分为3个角色:产品所有者(Product Owner), Scrum Master,开发团队(Team)。
- 产品所有者:定义所有产品功能,决定产品发布的内容以及日期,对产品的投入产出负责,根据市场变化对需要开发的功能排列优先顺序,合理地调整产品功能和迭代顺序,认同或者拒绝迭代的交付。
- ScrumMaster :ScrumMaster不是项目经理,他没有分配任务的权力,没有考核的权力,没有下命令的权力,他指导项目组的成员按照Scrum的原则、方法做事情,领导团队完成Scrum的实践以及体现其价值,排除团队遇到的困难,确保团队胜任其工作,并保持高效的生产率,使得团队紧密合作,使得团队个人具有多方面职能的工作能力,保护团队不受到外来无端影响。
- 开发团队:经典团队拥有 5-9 人,团队成员包含程序员、测试员、用户体验设计等等,团队关系在一个迭代中应该是固定的,个人的职能可以在新迭代开始时发生调整,团队自我组织和管理(自组织,自驱动),团队成员都全职工作。
五个会议
Scrum 整个开发过程分为五个会议:
- 待办事项整理会议(Backlog Grooming Meeting)
迭代计划会议开始之前3天召开,Product Owner与Scrum Master必须参加,关键开发者或架构师需要参加;时间控制在30分钟到1小时。
- 迭代计划会议(Sprint Planning Meeting)
产品负责人建立产品功能列表(Product Backlog)。产品功能列表是一组条目化需求,它必须从客户价值角度描述,并按优先级排序。
Scrum Master召集相关人员召开迭代计划会,迭代计划会在每个迭代第一天召开,目的是选择本次迭代的Backlog和估算本次迭代的工作量。
- 每日站会(Standup Meeting)
团队内部利用每日立会来沟通进度,15分钟结束,开发团队利用燃尽图来展示整体进度;如无特殊原因,迭代期内无变更,在每日站会上团队成员需要回答以下3个问题:
- 昨天你做了什么?
- 今天你将要做什么?
- 你有需要帮助的地方吗?
这些都是团队成员的彼此承诺。
- 评审会(Retrospective Meeting)
小组向产品负责人展示迭代工作结果,产品负责人给出评价和反馈。以用户故事是否能成功交付来评价任务完成情况。整个团队都需要参加,ScrumMaster、产品所有者、团队,可能还有客户,时间控制在1-2小时内。
- 反思会(Retrospective Meeting)
在每个迭代后召开简短的反思会,总结哪些事情做得好,哪些事情做得不好。做得好的保留,不好的摒弃。会议得出这样的结论:开始做什么、继续做什么、停止做什么,一般控制在15-30分钟。
十二原则
这十二原则作为敏捷开发对于软件开发流程的指导性纲领,也是对敏捷宣言进行了具有实际操作意义的解释。
我们遵循以下准则:
- 我们的最高目标是,通过尽早和持续地交付有价值的软件来满足客户。
- 欢迎对需求提出变更——即使是在项目开发后期。要善于利用需求变更,帮助客户获得竞争优势。
- 要不断交付可用的软件,周期从几周到几个月不等,且越短越好。
- 项目过程中,业务人员与开发人员必须在一起工作。
- 要善于激励项目人员,给他们以所需要的环境和支持,并相信他们能够完成任务。
- 无论是团队内还是团队间,最有效的沟通方法是面对面的交谈。
- 可用的软件是衡量进度的主要指标。
- 敏捷过程提倡可持续的开发。项目方、开发人员和用户应该能够保持恒久稳定的进展速度。
- 对技术的精益求精以及对设计的不断完善将提升敏捷性。
- 要做到简洁,即尽最大可能减少不必要的工作。这是一门艺术。
- 最佳的架构、需求和设计出自于自组织的团队。
- 团队要定期反省如何能够做到更有效,并相应地调整团队的行为
极限编程
极限编程是一种敏捷软件开发方法,它强调快速反馈、持续集成、测试驱动开发、简单设计和重构等实践。
极限编程的目标是提高软件开发的质量和效率,同时降低开发成本和风险。
极限编程是第一批敏捷开发方法中最具实效的一种。在各种敏捷方法中,极限编程最为重视工程实践。
在极限编程中,开发人员需要遵循以下实践:
- 快速反馈:团队成员理解客户在开发过程中给出的反馈,并能够迅速做出反应。
- 假设简单:开发人员需要专注于当前重要的工作,遵循所有问题都可以简单地解决原则。
- 增量变化:对产品一小步一小步的改变比一次性的大改变效果更好。
- 拥抱变化:如果客户认为产品需要改变,作为程序员,他们应该支持这个决定,并拟定如何实现新需求的计划。
- 高质量的工作:一个工作出色的团队,他们能够创造出有价值的产品,并为此感到自豪。
五个价值
- 沟通:团队中的每个人都互通工作。
- 简单性:开发人员努力编写简单的代码,为产品带来更多价值,因为这样可以节省时间和精力。
- 反馈:团队成员经常交付软件,获取有关软件的反馈,并根据新的需求改进产品。
- 尊重:每个被分配到项目中的人都为一个共同的目标做出贡献。
- 勇气:成员客观地评估自己的失误造成的后果而不是找借口,并且随时准备应对变化。
XP和Scrum的核心区别
XP 更关注技术和工程实践,而 Scrum 更关注团队协作和管理实践。
结对编程
设计和编程都是人的活动。忘记这一点,将会失去一切。——Bjarne Stroustrup
什么是结对编程?
结对编程(Pair programming)来自于极限编程(eXtreme Programming)。
顾名思义,结对编程就是由两个程序员用同一台电脑完成同一个任务,由一个人负责编写代码,另一个负责审查代码,从而能够时时刻刻的进行代码评审。
结对编程的优点
从项目角度,提高了产品质量
结对编程时,两个人共同完成一个功能,可以避免个人的误区存在,通常个人的想法难免有局限性,自己看自己写的代码总是觉得怎么都对。每个人站在不同的角度能够看到彼此的误差。
从团队角度,更好的实现了知识传递和分享,让成员关系更融洽
不可否认,结对这种面对面的沟通交流方式,对于知识和技能的传递是最好的形式。同时,这种即时的沟通交流也让同事之间关系变得融洽,相对比那种每个人一个格子间闷头写代码,更利于创建和谐的团队氛围。
培养新人,促进沟通,提升团队整体能力。
通过结对,年轻的团队成员可以向其他小伙伴学习,包括快捷键、算法、语法、SQL、设计、解决问题的思路、做事方式等等,1对1面对面师傅带徒弟式的学习是新技能get最快的方式之一。
五、软件需求分析
在软件开发前,进行有效的软件需求分析是非常重要的。
通过深入了解需求,可以防止项目在后续不断扩大,导致预算超支或项目延期,也能确保软件在实际使用中能够满足用户期望,提高用户满意度。
可行性分析
什么是可行性分析
检查并确定是否值得为项目或产品投入时间、金钱和资源。
这样的评估活动称为“可行性分析”。
为什么要进行可行性分析
在软件项目开发过程中,只要资源和时间不受限制,几乎所有项目都是可行的。
然而由于受到资源和交付时间的限制,使得软件系统的开发变得越来越困难。因此尽早对软件项目的可行性进行细致而谨慎的分析是十分必要的。
进行可行性分析才能明确系统是否值得做,避免投资损失,能否带来经济效益、企业效益或社会效益。
可行性分析的主要任务是什么
可行性分析的目的不是解决问题,而是确定问题是否可解并且是否值得去解决。
可行性分析的主要过程
- 检查系统规模和目标,明确限制或约束条件
- 研究正在使用的系统
- 导出新系统的高层次逻辑模型
- 提出可行性解决方案并评估比较
- 选择合适的解决方案
- 撰写可行性分析报告并提交审查
可行性分析主要集中在以下四个方面:
-
经济可行性分析
-
技术可行性分析
-
法律可行性分析
-
实施方案的选择
经济可行性分析
软件开发需要有投资,有投资就需要有收益。
经济可行性分析的目的是从经济角度评价一个新项目是否可行、是否划算,帮助投资人或用户正确投资。
技术可行性分析
主要考虑:
- 开发风险:在给定的限制范围内,能否设计出系统并实现必要的功能和性能。
- 资源可用性:是否有充足的技术人员可以支配。
- 技术条件:相关的技术条件是否能够支持系统的开发。
法律可行性分析
开发的软件项目是否会触犯法律法规
什么是软件需求
软件需求分析是软件开发过程中的首要步骤,它旨在收集、理解和明确定义软件系统的需求和目标。
软件需求包括4个不同的层次:
- **业务需求:**反映了组织结构或客户对系统、产品高层次的目标要求,它们在项目视图与范围文档中予以说明。
- 用户需求:站在用户的角度描述软件产品必须要完成的业务功能,这在使用实例文档或场景说明中予以详细描述。
- 功能需求:站在开发人员的角度定义了必须实现的软件功能,使得用户能完成他们的任务,从而满足了业务需求。
- 非功能需求:指逻辑上与软件相关的整体特性需求的集合,给用户提供处理能力并满足业务需求。
非功能需求可分为:
- 产品需求:描述产品行为的需求,包括系统运行速度和内存消耗等性能需求、出错率等可靠性需求和可用性需求。
- 机构需求:客户和开发者所在机构中的政策和规定要求。
- 外部需求:包括所有的系统外部因素和开发过程。
需求分析过程
需求分析主要是理解客户需要什么、分析要求、评价可行性、协商合理的方案、无歧义地详细说明方案、确认规格说明、管理需求以至将这些需求转化为可行系统。
沟通
当确定了商业需求或发现了潜在的新市场时开始。
在项目起始阶段,软件工程师会询问一些似乎与项目无直接关系的问题,目的是对问题、方案需求方、客户和开发人员之间初步的交流和合作的效果建立基本的协商准备。
导出需求
确定系统范围:系统的范围就是系统的边界,是客户和开发者共同关心的部分。
理解客户需要:客户/用户并不完全确定需要什么,系统工程师的任务是确定业务需求、需求冲突,说明有歧义和不可测试的需求。
易变问题:由于各种原因如客户讲不清楚、业务发生变化等,需求随时间变化。
识别真正的客户与用户:识别真正的客户不是一件容易的事情,项目要面对多方的客户,有时他们的利益各不相同给。
正确理解客户的需求:客户可能会说出客户不需要的、模糊、混乱矛盾的信息,甚至可能夸大或弱化真正的需求。
耐心听取客户意见:获取需求应能够从客户凌乱的建议和观点整理出真正的需求,耐心分析客户不确定性需求和过分需求,并进行沟通。
尽量使用符合客户语言习惯的表达:使用符合客户熟悉的术语进行交流。
精化需求
开发一个精确的技术模型,用以说明软件的功能、特征和约束。
精化是一个分析建模动作,由一系列建模和求精任务构成。
精化的结果是形成一个分析模型,该模型定义了问题的信息域、功能域和行为域。
可行性研究
可行性研究的目的是确定用最小的代价,在尽可能短的时间内确定问题是否能够解决。
从技术可行性、经济可行性、管理可行性和时间可行性4个方面研究每种方案的可行性。
与客户和用户协商
用户和客户提出了过高的目标要求,或者提出了相互冲突的要求,这就需要工程师通过协商和沟通的过程来调节这些冲突和问题。
编写需求规格说明
一个规格说明可以是一份写好的文档、一套图形化的模型、一个形式化的数学模型、一组使用场景、一个原型或以上各项的任意组合。
对于大型系统而言,文档最好采用自然语言描述(人话)和图形化模型来编写。
软件需求规格(Software Requirement Sepcification, SRS)是需求分析任务的最终“产品”,是客户、管理者、分析工程师、测试工程师、维护工程师交流的标准和依据。SRS说明文档描述了系统的数据、功能、行为、性能需求、设计约束、验收标准以及其他与需求相关的信息。
计算机软件需求规格说明规范现行标准:国家标准|GB/T 9385-2008 (samr.gov.cn)
验证需求
验证需求包括正确性、一致性、完整性、可行性、必要性、可检验性、可跟踪性及最后的签字确认。
管理需求
管理需求是对需求进行组织、控制和文档化的系统方法。
会谈技术
非正式会谈
非正式会谈将提出一些可自由回答的问题来鼓励会谈人员表达自己的想法。
非正式会谈一般从其他话题入手,建立融洽的氛围后,才开始转到项目的事情上来。
一般2~4个小时。
正式会谈
正式会谈将提出一些事先准备号的议题。
会谈者要准备一份有关会谈结果概要的书面报告,以便进一步陈述或者增加忽略的项目。
调查技术
获得需求的另外一种方法是向客户组织的相关人员发调查表。
确定调查内容
当需要对数百人进行个人意见调查时,调查技术十分有效。
先于主要的用户进行非正式会谈。在对此次会谈理解的基础上制定调查表,分发给所有客户组织人员。
可靠可信分析
虽然问卷调查对于有大量用户的项目而言是一个非常好的方法。然而由于问卷题目设置不当或者题目内容的不合理,也会导致得出错误的结论。
因此,需要根据问卷调查结果进行问卷可靠可信分析。
可靠可信分析的目的是检查问卷的指标设置是否合理,指标之间是否存在关联,以及结果是否可信等。
进行可靠可信分析的基本方法是层次分析法。
场景分析技术
若能把人与一个软件系统交互的过程用一个场景来描述,人们就容易理解并评论它。
需求分析从对场景的评论中得到信息,然后将其以形式化方式表示出来。这种方法称为场景分析,或情景分析。
场景开始于一个框架,在导出过程中,细节被逐渐增加,指导产生交互的一个完整的描述。
绝大多数情况,一个场景可能包括如下内容:
- 在场景开始部分有一个系统状态描述
- 一个关于标准事件流的描述
- 一个关于哪儿会出错,以及如果处理错误的描述
- 有关其他可能在同一时间进行的活动的信息
- 在场景完成后系统状态的描述
六、结构化分析
结构化分析(Structured Analysis,SA)方法是一种传统的系统建模技术,其过程是创建描述信息内容和数据流的模型,依据功能和行为对系统进行划分,并描述必须建立的系统要素。
结构化分析方法一般采用以下指导性原则:
- 理解问题
- 开发模型
- 描述需求
- 建立系统模型
- 确定需求优先级
- 验证需求
结构化分析模型
结构化分析方法是一种半形式化的建模技术,其过程是对系统信息进行分析,抽取其本质要素,创建描述数据和行为的模型。
结构化分析模型必须分别达到以下主要目标:描述客户需求,建立软件设计的基础,定义在软件完成后可以确认的一组需求。
面向数据的模型主要刻画软件中所涉及的数据及其关系,用来确定系统的数据结构和存储模型。
面向系统行为的模型包括两种类型模型:
- 数据流模型:用来描述系统中的数据处理过程。
- 状态转化模型:用来描述系统如何对事件做出响应。
结构化分析模型分别用**数据字典(Data Dictionary,DD)、数据流图(Data Flow Diagram,DFD)、状态转换图(State Transition Diagram,STD)、实体关系图(Entity Relationship Diagram,ERD)**等描述。
分析模型结构的核心是数据字典,包含了软件使用或生产的所有数据对象描述的中心库)。
面向数据流的建模方法
结构化分析是面向数据流进行需求分析的方法,是一种建模活动。
数据流图(待详细)
期末可能考给案例画数据流图
用数据流图描述系统处理过程是一种很直观的方式。
数据流图的基本要点是描绘“做什么”,而不考虑“怎么做”。
数据字典
Data Dictionary, DD
数据字典是对数据流图中包含的所有元素的定义的集合,是分析模型中出现的所有名字的一个集合,并包括有关命名实体的描述。
符号
符号 | 含义 | 说明 |
---|---|---|
= | 被定义为 | 姓名 = 10字符 |
+ | 与 | x = a + b,x由a和b组成 |
[…|…] | 或 | x = [a|b],x由a或b组成 |
m{…}n或{…} | 重复 | x = 1{b}5或x = {b},表示x中最少出现1次b,最多5次,m下限,n上限 |
(…) | 可选 | x = (a) 表示a可在x中出现,也可不出现 |
… | 连接符 | x = 0…9,x可取0~9中任意一个符。 |
数据流条目
列出该数据流的各组成数据项
数据流的组成成员是数据项,数据项条目是不可再分解的数据单位。
例:
名字:订货报表
别名:订货信息
描述:每天一次需要订货的零件表
定义:订货报表=零件编号+零件名称+订货数量+价格+1{供应者}3
位置:输出到打印机
零件编号=8位字符
零件名称=20位字符
订货数量=[1|2|3|4|5]
价格={零件单价}
供应者=24位字符
这种数据字典卡片主要包含:名字、别名、描述、定义、位置
七、结构化设计
设计:一种软件开发活动,定义实现需要规约所需的软件结构
设计的目标:
- 依据需求规约在一个抽象层上建立系统软件模型,包括软件体系结构(数据和程序结构),以及详细的处理算法。
- 给出软件解决方案,产生设计规格说明书。
结构化设计分为:
- 总体设计:确定系统的整体模块结构(系统实现所需要的软件模块以及这些模块之间的调用关系)。
- 详细设计:详细描述模块。
整体框架
-
体系结构设计(MSD):定义软件模块及其之间的关系,从分析模型(如数据流图)导出。
-
接口设计:
外部接口设计:根据分析模型中的顶层数据流图得到,包括用户界面、目标系统与其他硬件设备、软件系统的外部接口
内部接口设计:系统内部各种元素间的接口
-
数据设计:根据数据字典确定软件涉及的文件系统的结构及数据库的表结构
模块化设计
分而治之
基本概念
精化:基于模块化原理“高内聚,低耦合”将初始的MSD转化为最终可详细设计使用的MSD。
模块:执行一个特殊任务的一组程序和数据结构。
模块化:把系统分解成若干模块的过程,使得程序能够被理性的管理。
高内聚 低耦合
内聚:一个模块之内各成分之间相互依赖程度的度量。
耦合:不同模块间相互依赖程度的度量。
英:
高内聚:High Cohesion; Strong cohesion; Maximize Cohesion
cohesion 美 [koʊˈhiʒ(ə)n] n.内聚力;结合;凝聚性;黏合
低耦合:Low Coupling; loosely coupled; Minimize Coupling
coupling 美 [ˈkʌp(ə)lɪŋ] n.联轴器;连接;联结;结合
内聚类型(由低到高)
- 偶然内聚:一个模块之内各成分之间没有任何关系。
- 逻辑内聚:几个逻辑上相关的功能放在同一模块中。
- 时间内聚:一个模块完成的功能必须在同一时间内完成,而这些功能只是因为时间因素关联在一起。
- 过程内聚:处理成分必须以特定的次序执行。
- 通信内聚:各成分都操作在同一数据集或生成同一数据集。
- 顺序内聚:各成分与一个功能相关,且一个成分的输出作为另一成分的输入。
- 功能内聚:模块的所有成分对完成单一功能是最基本的,且该模块对完成这一功能而言是充分必要的。
耦合类型(由高到低)
- 内容耦合:一个模块直接修改或操作另一个模块的数据。
- 公共耦合:两个及以上的模块共引用一个全局数据项。
- 控制耦合:一个模块向另一个模块传递控制信号。
- 标记耦合:两个模块至少有一个通过界面传递的公共参数,包含内部数据,如数组,字符串等。
- 数据耦合:模块间通过参数传递基本类型的数据。
耦合的强度所依赖的因素:
- 模块间的引用
- 模块间传递的数据量
- 模块间的施加控制量
- 模块间接口复杂度
软件结构图
结构图(Structure Chart,SC)是精确表达软件结构的图形表示方法,它以特定的符号表示模块、模块间的调用关系和模块间信息的传递。
主要构成
- 模块(Module):用矩形框表示,框内为模块名,说明模块功能。
- 调用:用箭头表示,一般是上层调用下层。
- 数据:调用点头旁的短箭头表示调用时从一个模块传给另一个模块的数据。短箭头旁注有信息名字,常用尾端带有空心圆的短箭头表示数据信息,用尾端带有实心圆的短箭头表示控制信息。
- 条件符号:当模块A有条件的调用模块B时,在模块A的调用箭头尾部标以菱形符号。
- 循环符号:当模块A反复的调用其他模块时,在调用箭头尾部标以弧形符号。