计算机学习笔记-归档
软件工程-笔记
软件工程
课程介绍
课程链接
哈工大软件工程(中文,录屏效果好,优先学):https://www.bilibili.com/video/BV1Aa4y177Wc/?spm_id_from=333.337.search-card.all.click&vd_source=2d5bdee7ea59486ed4aa4a9b10020224
学习目标
1、熟练使用基本的软件工程方法
2、完成考试的相关部分考题
课程概念
软件工程是一门研究用工程化方法构建和维护有效、实用和高质量的软件的学科。
它涉及程序设计语言、数据库、软件开发工具、系统平台、标准、设计件有电子邮件、嵌入式系统、人机界面、办公套件、操作系统、编译器、数据库、游戏等。
课程局限
哈工大的课程整体质量比较高,知识点上没问题,细节比较丰富,适合在校学生。某些概念性内容比较啰嗦,例如XXX的概念和意义,应该理解为主+实践操作,而不是简单的背诵概念(当然,面对考试还是需要背诵)。
课程概况(AI)
软件工程是一个广泛的领域,涵盖了软件开发的各个方面。以下是一些软件工程的主要知识点,包括技术细节:
软件开发过程
-
需求分析:收集和定义软件需求
-
设计:创建软件系统的高级设计(概要设计)和详细设计
-
实现:编写代码和构建软件
-
测试:验证软件是否满足需求和工作正确
-
部署:将软件发布到生产环境
-
维护:修复错误、更新软件和添加新功能
软件设计
-
面向对象设计(OOD):使用类、对象和继承等概念设计软件
-
结构化设计:使用模块化和分层等概念设计软件
-
设计模式:使用预定义的解决方案来解决常见问题
-
体系结构:定义软件系统的整体结构和组件
编程语言和技术
-
编程语言:Java、C++、Python、JavaScript等
-
数据库:关系型数据库(RDBMS)、NoSQL数据库等
-
网络协议:HTTP、TCP/IP、FTP等
-
操作系统:Windows、Linux、macOS等
软件测试
-
单元测试:测试软件的单个组件
-
集成测试:测试软件的多个组件之间的交互
-
系统测试:测试整个软件系统
-
测试驱动开发(TDD):先写测试代码,然后写实现代码
软件工程工具
-
版本控制系统(VCS):Git、SVN等
-
项目管理工具:Jira、Asana等
-
持续集成和持续部署(CI/CD):Jenkins、Travis CI等
-
代码分析工具:SonarQube、CodeCoverage等
软件工程原则
-
SOLID原则:单一职责原则(SRP)、开闭原则(OCP)、里氏替换原则(LSP)、接口隔离原则(ISP)、依赖反转原则(DIP)
-
YAGNI原则:你不会需要它(You Ain’t Gonna Need It)
-
KISS原则:保持简单,傻瓜(Keep It Simple, Stupid)
软件安全
-
认证和授权:确保用户身份和访问控制
-
输入验证:防止恶意输入
-
加密:保护数据的机密性和完整性
-
错误处理:处理异常和错误
这些是软件工程的主要知识点,包括技术细节。当然,这不是一个详尽的列表,但它涵盖了软件工程的主要方面。
1-1 软件工程概论
软件工程:用工程化的方法,开发软件(把工程管理学应用在软件行业)
目的:理解软件开发面临的问题,用软件工程的思维方法,开发测试维护复杂庞大的软件系统。
课程要求:理解软件工程,理解软件工程解决什么问题,具体涉及哪些方面
工程化思想开发流程:需求分析-软件设计-程序设计-软件测试-软件维护
目标:可用,正确,合算
软件工程和一般工程的区别:软件功能复杂,实现复杂,能见度低(外层看不到内层逻辑),结构多样。
软件工程和系统工程的区别:系统工程包括计算机开发所有方面(硬件+软件处理)
软件工程和编程的区别:编程是用代码解决一个小问题,软件工程是系统化解决一个大工程,如何分配任务等
如何培养自己的软件工程思维和方法
培养软件工程的思维与方法,需要长期的实践和学习
-
学习软件工程的基本原理:了解软件工程的基本概念、原则和方法,例如软件生命周期、需求分析、设计模式、测试等。
-
实践编程:通过编程实践来应用软件工程的原理和方法。选择一个项目,设计和实现它,遇到问题时,思考如何使用软件工程的方法来解决。
-
阅读开源代码:阅读开源代码是学习软件工程的好方法。通过阅读他人的代码,可以学习到新的设计模式、编程技巧和软件工程方法。
-
参与软件工程社区:参与软件工程社区,例如参加会议、加入在线论坛、阅读软件工程博客等,可以学习到最新的软件工程方法和技术。
-
反思和总结:在编程和软件工程实践中,反思和总结自己的经验和教训,可以帮助你形成自己的软件工程思维和方法。
-
学习设计模式和架构:学习设计模式和架构可以帮助你理解软件系统的结构和组织,提高你的软件工程能力。
-
实践测试驱动开发:测试驱动开发(TDD)是软件工程中的一种重要方法,通过实践TDD,可以提高你的软件工程能力和代码质量。
-
学习版本控制和协作工具:学习版本控制和协作工具,例如Git、SVN、Jenkins等,可以帮助你理解软件工程中的协作和版本控制。
-
阅读软件工程书籍:阅读软件工程书籍,例如《软件工程》、《代码大全》、《设计模式》等,可以帮助你深入理解软件工程的原理和方法。
-
参加软件工程培训和课程:参加软件工程培训和课程,可以帮助你系统地学习软件工程的原理和方法。
1-2 软件及软件分类
软件(Software)是指计算机系统中除硬件以外的所有部分,包括程序、数据、文档等。
软件的分类可以从不同的角度进行,以下是一些常见的软件分类:
1. 根据软件的功能分类
-
操作系统(Operating System):管理计算机硬件资源,提供基本的输入/输出功能,例如Windows、Linux、macOS。
-
应用软件(Application Software):为用户提供特定的功能,例如文字处理软件(Word)游戏软件等。
-
工具软件(Utility Software):提供系统维护、备份、安全等功能,例如磁盘清理软件、病毒扫描软件等。
2. 根据软件的开发方式分类
-
开源软件(Open Source Software):软件的源代码公开,允许用户修改和分发,例如Linux、Apache。
-
闭源软件(Closed Source Software):软件的源代码不公开,用户无法修改和分发,例如Windows、Office。
-
自由软件(Free Software):软件的源代码公开,允许用户修改和分发,但可能有一些限制,例如GPL(General Public License)。
3. 根据软件的运行平台分类
-
桌面软件(Desktop Software):运行在个人计算机上,例如Windows、macOS。
-
移动软件(Mobile Software):运行在移动设备上,例如Android、iOS。
-
服务器软件(Server Software):运行在服务器上,例如Apache、Nginx。
-
嵌入式软件(Embedded Software):运行在嵌入式系统上,例如机器人、汽车电子系统。
4. 根据软件的开发语言分类
-
Java软件:使用Java语言开发的软件,例如Android应用、Web应用。
-
C++软件:使用C++语言开发的软件,例如游戏、操作系统。
-
Python软件:使用Python语言开发的软件,例如数据分析、机器学习。
5. 根据软件的许可证分类
-
免费软件(Freeware):软件免费使用,但可能有一些限制,例如广告、功能限制。
-
共享软件(Shareware):软件可以免费试用,但需要付费才能使用全部功能。
-
商业软件(Commercial Software):软件需要付费才能使用,例如Windows、Office。
1-3 软件发展和软件危机
软件发展
软件发展:软件从最初的概念到最终的交付的整个过程,包括需求分析、设计、实现、测试、部署和维护等阶段。
软件发展是软件生命周期的总体框架,涵盖了软件开发的所有阶段。
软件危机
软件危机:软件开发过程中出现的各种问题和挑战,包括软件成本超支、软件开发时间延迟、软件质量不高、软件维护困难等。
软件危机是软件开发过程中的一个常见现象,可能导致软件项目的失败或软件产品的质量不高。
软件危机的原因包括:
-
需求不明确
-
设计不良
-
实现不当
-
测试不充分
-
维护不善
软件危机的解决方法包括:
-
需求管理
-
设计评审
-
实现评审
-
测试评审
-
维护评审
软件发展是软件生命周期的总体框架
而软件危机是软件开发过程中的一个常见现象,可能导致软件项目的失败或软件产品的质量不高。
1-4 软件生命周期和软件开发模型
软件生命周期:
软件从概念到交付的整个过程,包括需求分析、设计、实现、测试、部署和维护等阶段。
软件生命周期是软件开发的总体框架,涵盖了软件开发的所有阶段。
软件开发模型:
软件开发模型是指软件开发过程中使用的具体方法和框架,用于指导软件开发的各个阶段。
软件开发模型是软件生命周期的具体实现,提供了软件开发过程中需要遵循的步骤和原则。
常见的软件开发模型包括:
-
瀑布模型(Waterfall Model)
-
迭代模型(Iterative Model)
-
螺旋模型(Spiral Model)
-
敏捷模型(Agile Model)
-
极限编程模型(Extreme Programming Model)
软件生命周期和软件开发模型的关系:
软件生命周期是软件开发的总体框架,而软件开发模型是软件生命周期的具体实现。
软件开发模型提供了软件开发过程中需要遵循的步骤和原则,帮助软件开发团队按照软件生命周期的要求进行软件开发。
1-5 瀑布模型
瀑布模型(Waterfall Model)它将软件开发过程划分为几个阶段,每个阶段完成后才进入下一个阶段。
特点:每个阶段的输出,成为下一个阶段的输入,类似于瀑布流水般的顺序。
瀑布模型的典型阶段包括:
-
需求分析(Requirements Analysis)
-
设计(Design)
-
实现(Implementation)
-
测试(Testing)
-
部署(Deployment)
-
维护(Maintenance)
瀑布模型的优点是:
-
简单易懂
-
阶段之间的依赖关系明确
-
容易管理和跟踪进度
但是,瀑布模型也有一些缺点:
-
不适合复杂、变化频繁的项目
-
每个阶段的输出可能需要大量的返工
-
测试阶段可能发现早期阶段的错误,导致返工量大
现在,瀑布模型已经被许多其他软件开发过程模型所取代,例如敏捷开发(Agile Development)、迭代开发(Iterative Development)等。
1-6 快速原型模型
快速原型模型(Rapid Prototyping Model)
它强调快速创建一个可用的原型系统,以便尽早地得到用户的反馈和验证需求。
主要特点是:
-
快速创建原型:使用快速开发工具和技术,快速创建一个可用的原型系统。
-
迭代开发:根据用户的反馈和需求变化,迭代地更新和完善原型系统。
-
用户参与:用户在整个开发过程中积极参与,提供反馈和建议。
快速原型模型的优点是:
-
快速响应用户需求
-
减少开发风险
-
提高用户满意度
-
可以快速验证需求和假设
快速原型模型的步骤包括:
-
需求分析:快速收集和分析用户需求
-
原型设计:快速设计原型系统的架构和界面
-
原型实现:快速实现原型系统
-
测试和反馈:用户测试原型系统并提供反馈
-
迭代更新:根据反馈和需求变化,迭代地更新和完善原型系统
快速原型模型适用于:
-
需求不明确或变化频繁的项目
-
需要快速响应用户需求的项目
-
需要降低开发风险的项目
快速原型模型的缺点是:
-
可能导致系统结构不清晰
-
可能导致系统性能不佳
-
可能需要大量的返工
总的来说,快速原型模型是一种快速响应用户需求的软件开发过程模型,适用于需求不明确或变化频繁的项目。
1-7 增量模型
增量模型(Incremental Model)是一种软件开发过程模型,它将软件开发过程划分为几个增量,每个增量都包含一组特定的功能或特性。
通过逐步增加软件的功能和特性来实现最终的软件产品。
增量模型适用于需求比较明确的项目,需要快速交付部分功能的项目,和需要降低开发风险的项目。
增量模型的特点是:
-
将软件开发过程划分为几个增量
-
每个增量都包含一组特定的功能或特性
-
每个增量都经过测试和验证
-
增量之间可以有重叠或迭代
增量模型的优点是:
-
可以快速交付部分功能
-
可以早期发现和解决问题
-
可以提高用户满意度
-
可以降低开发风险
增量模型的步骤包括:
-
需求分析:确定软件的总体需求
-
增量规划:将需求划分为几个增量
-
增量设计:设计每个增量的详细功能和特性
-
增量实现:实现每个增量的功能和特性
-
增量测试:测试每个增量的功能和特性
-
增量交付:交付每个增量的功能和特性
增量模型适用于:
-
需求比较明确的项目
-
需要快速交付部分功能的项目
-
需要降低开发风险的项目
增量模型的缺点是:
-
可能导致系统结构不清晰
-
可能导致系统性能不佳
-
可能需要大量的返工
1-8 螺旋模型
螺旋模型适用于复杂的软件项目,有效地管理风险的项目,提高用户满意度的项目,和需要适应变化的需求的项目。
螺旋模型(Spiral Model)是一种软件开发过程模型,它结合了瀑布模型和迭代开发的特点,强调风险管理和用户参与。
螺旋模型的特点是:
-
将软件开发过程划分为几个螺旋形的阶段
-
每个阶段都包括风险分析、工程设计、实现和测试
-
每个阶段都有明确的目标和输出
-
用户参与整个开发过程
螺旋模型的优点是:
-
可以有效地管理风险
-
可以提高用户满意度
-
可以适应变化的需求
-
可以降低开发风险
螺旋模型的步骤包括:
-
规划阶段:确定软件的总体目标和范围
-
风险分析阶段:识别和分析软件开发过程中的风险
-
工程设计阶段:设计软件的详细结构和功能
-
实现阶段:实现软件的功能和特性
-
测试阶段:测试软件的功能和特性
-
评估阶段:评估软件的质量和满足度
螺旋模型适用于:
-
复杂的软件项目
-
需要有效地管理风险的项目
-
需要提高用户满意度的项目
-
需要适应变化的需求的项目
螺旋模型的缺点是:
-
可能导致开发周期较长
-
可能需要大量的资源
-
可能需要高水平的开发人员
1-9 喷泉模型和变换模型
喷泉模型(Fountain Model)
喷泉模型是一种软件开发过程模型,它强调软件开发过程中的连续性和流动性。
喷泉模型将软件开发过程比喻为一个喷泉,开发人员在整个过程中不断地添加新的功能和特性,就像水不断地从喷泉中流出一样。
喷泉模型的特点是:
-
软件开发过程是连续的和流动的
-
开发人员在整个过程中不断地添加新的功能和特性
-
软件产品在整个过程中不断地演进和完善
喷泉模型的优点是:
-
可以快速响应变化的需求
-
可以提高软件产品的质量和可靠性
-
可以降低开发风险
喷泉模型的缺点是:
-
可能导致软件产品的结构不清晰
-
可能导致软件产品的性能不佳
变换模型(Transformation Model)
变换模型是一种软件开发过程模型,它强调软件开发过程中的变换和转换。
变换模型将软件开发过程比喻为一个变换过程,开发人员在整个过程中不断地变换和转换软件产品的状态。
变换模型的特点是:
-
软件开发过程是变换和转换的过程
-
开发人员在整个过程中不断地变换和转换软件产品的状态
-
软件产品在整个过程中不断地演进和完善
变换模型的优点是:
-
可以有效地管理软件产品的变换和转换
-
可以提高软件产品的质量和可靠性
-
可以降低开发风险
变换模型的缺点是:
-
可能导致软件产品的结构不清晰
-
可能导致软件产品的性能不佳
1-10 软件工程的基本目标和原则
基本目标:
-
质量: 高质量,满足用户的需求和期望。
-
可靠性: 可靠的,能够正常运行和提供服务。
-
效率: 高效的,能够快速地完成任务和提供服务。
-
可维护性: 可维护的,能够容易地修改和更新。
-
可扩展性: 可扩展的,能够容易地添加新功能和特性。
基本原则:
-
模块化: 能够容易地分解和组装。
-
抽象: 能够容易地描述和理解。
-
封装: 能够容易地隐藏和保护内部细节。
-
继承: 能够容易地重用和扩展现有的代码。
-
可重用性: 能够容易地在不同的环境和应用中使用。
-
可测试性: 能够容易地测试和验证。
-
可维护性: 能够容易地修改和更新。
-
可扩展性: 能够容易地添加新功能和特性。
软件工程的基本原则还包括:
-
需求分析: 软件开发应该从需求分析开始,确保软件产品满足用户的需求和期望。
-
设计: 软件开发应该包括设计阶段,确保软件产品的结构和功能是合理的。
-
实现: 软件开发应该包括实现阶段,确保软件产品是可行的和有效的。
-
测试: 软件开发应该包括测试阶段,确保软件产品是可靠的和高质量的。
-
维护: 软件开发应该包括维护阶段,确保软件产品是可维护的和可扩展的。
1-11 软件工程的三要素
软件工程的三要素是:
-
过程(Process):软件开发和维护的整个过程,包括需求分析、设计、实现、测试、维护等阶段。
-
方法(Method):软件开发和维护中使用的具体方法和技术,包括编程语言、开发工具、测试方法等。
-
工具(Tool):软件开发和维护中使用的具体工具和软件,包括编译器、调试器、版本控制系统等。
这三个要素是软件工程的基础,共同构成了软件工程的框架。
-
过程 是软件工程的骨架,提供了软件开发和维护的整个过程和阶段。
-
方法 是软件工程的血肉,提供了具体的方法和技术来实现软件开发和维护。
-
工具 是软件工程的助手,提供了具体的工具和软件来支持软件开发和维护。
这三个要素是相互关联的,过程决定了方法和工具的选择,方法和工具又反过来影响过程的实施。
软件工程的三要素是软件开发和维护的基础,共同构成了软件工程的框架。
2-1 可行性研究的任务
计算机软件可行性研究任务,是在软件开发前期,对软件项目的技术、经济、社会等方面研究分析,确定其是否可行及值得投资。
其任务涵盖:
-
软件项目背景研究:探究目的、目标、范围等背景情况。
-
市场需求研究:考察市场规模、增长潜力、竞争情况等需求状况。
-
技术可行性研究:分析技术方案可行性、技术风险等。
-
经济可行性研究:研究投资、成本、收益等经济情况。
-
社会可行性研究:考量对社会影响、社会接受度等。
-
风险分析:剖析技术、市场、财务等风险。
-
软件项目实施计划:制定时间表、资源分配、实施步骤等计划。
-
软件项目评估:评估技术、经济、社会等方面可行性。
计算机软件可行性研究,旨在确定软件项目可行性与投资价值,助力软件开发人员和投资者做出明智决策。
2-2 可行性研究的步骤
计算机软件可行性研究步骤如下:
-
软件项目背景研究:探究目的、目标、范围。
-
市场需求研究:考察规模、潜力、竞争情况。
-
技术可行性研究:分析方案可行性、技术风险。
-
经济可行性研究:研究投资、成本、收益。
-
社会可行性研究:考量对社会影响、接受度。
-
风险分析:剖析技术、市场、财务风险。
-
软件项目实施计划:制定时间表、资源分配、步骤。
-
软件项目评估:评估技术、经济、社会可行性。
其工具包括:
-
SWOT分析:分析优势、劣势、机会、威胁。
-
PEST分析:分析政治、经济、社会、技术环境。
-
市场研究报告:研究市场需求与竞争情况。
-
技术可行性报告:研究技术可行性与风险。
-
经济可行性报告:研究经济可行性与收益。
-
社会可行性报告:研究社会可行性与影响。
-
风险分析报告:分析风险及应对措施。
-
软件项目实施计划报告:制定计划与资源分配。
2-3 系统开发计划的内容
系统开发计划的格式
系统开发计划的格式可以根据项目的具体需要进行调整和补充。
以下是一个常见的系统开发计划格式:
-
封面:项目名称、项目编号、版本号和日期。
-
目录
-
正文:项目概述、系统需求、系统架构、系统设计、系统开发、系统测试、系统部署、系统维护、项目管理、风险管理、质量管理、配置管理、文档管理和培训和支持的详细内容。
-
附录:项目的相关文档、图表和数据。
2-4 系统流程图
系统流程图(System Flowchart),是一种用于描述系统或软件系统的流程和交互的图表。
它可以帮助我们理解系统的整体架构、数据流动和控制流程。
系统流程图通常包括以下元素:
-
输入/输出(I/O): 表示系统的输入和输出,例如用户界面、数据库、外部系统等。
-
处理(Process): 表示系统中的处理步骤,例如数据处理、逻辑判断、数据存储等。
-
数据存储(Data Storage): 表示系统中的数据存储,例如数据库、文件系统等。
-
控制流(Control Flow): 表示系统中的控制流程,例如条件判断、循环等。
-
连接线(Connector): 表示系统中的数据流动和控制流程。
系统流程图可以用于软件设计、系统分析、系统测试等方面。
它可以帮助我们理解系统的整体架构、数据流动和控制流程,帮助我们设计和开发更加清晰、易于维护的系统。
2-5 结构化分析实例(一)
结构化分析实例——一个学校财务系统的需求分析
需求:学校人员增加,现有的财务系统不满足需要,能否开发一个新的计算机财务报表系统,取代原有的人力统计财务系统
误区:这里不是研究如何实现财务系统的具体计算机技术细节,而是研究是否需要做财务系统?是否有必要去做?
1、已有费用分析:已有的人工财务系统,每年预算2万,通常甲方希望3年收回成本,这个软件预算就是 6万(+-50%)
2、可行性研究:系统规模和目标的报告,需要请领导和甲方审查

花尽量少的成本,决定问题是否存在可行的解法;如果盲目开发系统,就会浪费时间金钱。
3、澄清系统规模和问题:如果确定开发这个项目,需要开发人员了解这个项目的具体逻辑(例如财务管理的逻辑),然后才能实现转换成计算机软件实现。这里不需要成为财务专家,不过需要了解基础的财务相关工作。
期间需要请专业财务人员进行指导和分析,完善这个功能和流程的设计


2-6 结构化分析实例(二)
总结:结构化分析案例
结构化分析主要包含以下几个步骤:
确定系统边界
明确所开发的软件系统的范围,确定哪些部分属于系统要处理的内容(根据教师的课时数,决定工资数量),哪些是外部环境相关的、不在系统功能范畴内的(学校的钱给教师转账),区分出系统与外界的接口等,以此清晰界定系统的边界所在。
建立当前系统的物理模型-流程图
通过对现行系统的详细调研,了解系统的实际运作情况,采用诸如面谈、实地观察、查阅文档等多种方式收集信息,并用一些直观的图形工具(如系统流程图等)来描绘出当前系统具体是如何运行的,展现出其物理层面的构成和流程,包括涉及的人员、设备、数据流向等要素。
抽象出当前系统的逻辑模型-数据流图
在物理模型基础上,去除掉物理实现的细节部分,比如具体的设备、人员操作方式等,着重关注系统内部的业务逻辑、数据处理逻辑以及各部分之间的逻辑关系,提炼出系统的核心逻辑,用数据流图等工具进行表示,展现出数据的输入、处理、输出等逻辑流程。
建立目标系统的逻辑模型
依据用户需求以及对现有系统逻辑模型的分析,明确目标系统在功能、性能等方面需要改进和实现的内容,对现有逻辑模型进行相应的调整、扩充、优化等操作,构建出目标系统的逻辑模型,这个模型将指导后续的软件设计工作,同样也是用数据流图等工具来准确呈现其逻辑架构。
编写需求规格说明书
将目标系统逻辑模型等相关分析成果,以文档的形式进行整理和规范表述,详细说明系统的功能需求、性能需求、数据要求、接口需求等各方面内容,为后续的软件设计、开发、测试等环节提供清晰准确的依据,使得参与项目的不同人员(开发人员、测试人员、用户等)能够基于此文档对系统有统一的认识和理解。
进行需求验证
组织相关的用户、领域专家等人员,通过评审会、用户试用等多种方式,对需求规格说明书所描述的内容进行检查和验证,查看是否真正符合用户的期望和业务实际需求,是否存在遗漏、错误或者不合理之处,若发现问题及时进行修改完善,确保需求的准确性和完整性。
2-7 成本效益分析的基本方法
软件工程中的成本效益分析(Cost-Benefit Analysis,CBA)是一种系统化的方法,用于评估软件项目的成本和收益,以确定是否值得投资。以下是成本效益分析的基本方法:
-
确定目标和范围:明确软件项目的目标和范围,包括功能、性能和质量要求。
-
识别成本:估算软件项目的成本,包括:
-
人力成本(开发人员、测试人员、项目经理等)
-
硬件和软件成本(服务器、数据库、开发工具等)
-
外部服务成本(咨询、培训等)
-
维护和更新成本
-
-
识别收益:估算软件项目的收益,包括:
-
直接收益(例如,增加销售额、提高生产率)
-
间接收益(例如,改善客户满意度、增强竞争力)
-
长期收益(例如,提高公司声誉、增强核心竞争力)
-
-
计算成本和收益:使用各种方法计算成本和收益,例如:
-
现金流分析(Cash Flow Analysis)
-
净现值分析(Net Present Value,NPV)
-
内部收益率分析(Internal Rate of Return,IRR)
-
回收期分析(Payback Period)
-
-
比较成本和收益:比较软件项目的成本和收益,以确定是否值得投资。
-
敏感性分析:进行敏感性分析,以评估软件项目的成本和收益对各种假设和变量的敏感度。
-
决策:根据成本效益分析的结果,做出软件项目的投资决策。
成本效益分析的基本方法包括:
-
成本效益比(Cost-Benefit Ratio):成本与收益的比率。
-
净现值(Net Present Value,NPV):软件项目的未来现金流的当前值。
-
内部收益率(Internal Rate of Return,IRR):软件项目的投资回报率。
-
回收期(Payback Period):软件项目的投资回收期。
通过使用这些方法和指标,软件工程师可以进行系统化的成本效益分析,以帮助决策者做出明智的投资决策。
2-9 项目开发计划
项目开发计划(Project Development Plan)是一份详细的文档,描述了项目开发过程中的各个阶段、任务、里程碑、资源分配和时间表。
它是项目管理的重要工具,帮助项目团队确保项目按时、按质、按预算完成任务。
项目开发计划通常包括以下内容:
-
项目概述:项目的背景、目标、范围、交付成果等。
-
项目阶段:项目开发过程中的各个阶段,例如需求分析、设计、开发、测试、部署等。
-
任务列表:每个阶段的具体任务,包括任务名称、任务描述、负责人、开始时间、结束时间、资源需求等。
-
里程碑:项目开发过程中的重要事件或成果,例如完成需求分析、完成设计、完成开发等。
-
资源分配:项目团队成员、外部资源、设备、材料等资源的分配计划。
-
时间表:项目开发过程中的时间安排,包括开始时间、结束时间、任务持续时间等。
-
风险管理:项目开发过程中的潜在风险、风险评估、风险应对措施等。
-
质量保证:项目开发过程中的质量控制措施,包括代码审查、测试计划等。
-
沟通计划:项目团队成员、客户、利益相关者之间的沟通计划,包括沟通频率、沟通方式等。
项目开发计划的目的,是确保项目团队,按照既定的计划和时间表,完成项目开发工作,确保项目质量、成本和时间的控制。
实际案例
|
|
3-1 需求分析的任务
在软件工程中,需求分析的主要任务包括以下几方面:
确定需求
准确识别和定义用户对软件系统的各类需求,涵盖
-
功能需求(比如软件要实现的具体操作、业务流程等)
-
非功能需求(像性能方面,要求的响应时间、吞吐量;可靠性方面,容错能力;易用性方面,操作便捷程度等)
-
用户的约束条件(例如预算限制、使用的特定技术平台等)。
分析需求
对收集到的众多需求,进行梳理、剖析,判断其合理性、完整性以及一致性。
查看各项需求之间是否存在矛盾冲突之处,是否存在需求遗漏情况,确保整个需求体系逻辑连贯、条理清晰,能够为后续软件设计提供可靠的依据。
建立模型
运用合适的建模方法与工具(例如用例图、数据流图、实体关系图等)来对需求进行可视化呈现,将抽象的需求,转化为直观易懂的模型,方便开发团队成员以及与用户沟通交流,使各方对软件系统的预期架构、功能流程等有更清晰的理解。
编写文档
生成详细且规范的需求规格说明书
其内容要全面记录软件系统的各项需求、功能、性能指标等关键信息,作为后续软件开发过程中设计、编码、测试等各阶段工作的重要参照,同时也便于在项目进行过程中与用户核对需求、进行需求变更管理等操作。
验证需求
和用户一起对需求进行审核验证,确保所确定的需求确实是用户真正想要的,符合用户的业务期望与实际使用场景,能够准确无误地指导软件开发工作,避免后续因需求偏差而导致的返工等问题。
3-2 需求分析的过程
需求分析过程包含以下关键阶段:
需求获取
-
与相关方沟通:通过面谈、访谈、会议等,了解相关方对软件系统的期望、目标及业务场景需求,如业务流程、不同角色操作等。
-
收集现有资料:收集业务文档、过往项目文档、报表数据等,梳理出软件需求相关信息。
-
观察实际操作:深入实际业务环境,观察日常操作,发现潜在需求与痛点,确保需求贴合实际。
需求整理
-
分类归纳需求:按功能需求、非功能需求及其他约束条件,分类整理零散需求,使其条理清晰。
-
去除重复冗余:排查分类后的需求,去除重复内容,避免资源浪费与理解混淆。
需求分析与建模
-
分析需求特性:研究需求合理性、完整性与一致性,检查是否符合业务逻辑等。
-
构建需求模型:运用合适工具方法,如用例图、数据流图、实体关系图等,将需求可视化、结构化呈现。
需求评审
-
组织内部评审:开发团队内部召集成员评审需求及模型,从专业角度提意见,确保可行性。
-
与用户共同评审:邀请相关方参与评审,核对需求是否符合期望,按需修改完善,保障准确性。
需求文档编制
-
撰写需求规格说明书:按规范记录软件系统所有需求内容,形成说明书,作为开发依据。
-
更新与维护文档:需求变更时及时更新维护文档,确保其反映最新需求状态。
3-3 需求分析的原则
需求分析遵循以下原则:
准确性原则
-
需求理解精准:开发团队要通过充分沟通、调研,准确把握用户需求关键内容,避免理解偏差影响开发方向。
-
需求表述清晰:用清晰无歧义语言表述需求,让开发各方能准确理解。
完整性原则
-
功能覆盖全面:涵盖软件所有功能,包括核心、辅助及特殊情况处理功能,防止遗漏。
-
非功能需求完备:全面考虑并明确性能、可靠性、安全性、易用性等非功能需求。
一致性原则
-
内部逻辑一致:各项需求逻辑关系要协调,避免相互矛盾。
-
需求变更一致:变更需求要与原需求体系保持连贯、一致,及时更新相关内容。
可行性原则
-
技术实现可行:需求要在现有或规划技术条件下可实现,考虑团队能力、资源与时间限制。
-
成本效益可行:衡量需求成本与效益合理性,确保成本可控、效益可观。
可验证性原则
-
需求标准明确:为每项需求制定清晰验证标准,便于检验。
-
验证方法可用:配套可行验证方法,有效验证软件是否满足需求。
需求优先级原则
-
业务重要性区分:按对业务重要程度区分优先级,优先处理核心业务需求。
-
紧急程度考量:结合项目时间、用户紧急需求确定紧急程度,按需提高优先级。
3-4 需求分析的基本方法
以下是需求分析的一些基本方法:
访谈法
-
用户访谈:与软件系统的各类潜在用户、实际使用者、业务负责人等进行一对一或一对多的访谈。提前准备好详细且有针对性的问题清单,涵盖功能需求(如日常业务操作需要软件实现哪些功能)、非功能需求(像对响应速度、操作便捷性的期望等)以及业务场景相关问题。在访谈过程中,认真倾听对方的回答,做好记录,并适时追问细节,确保全面准确地了解他们的需求和期望。
-
专家访谈:对于涉及专业领域知识的软件项目,与相关领域专家进行访谈。这些专家熟悉业务流程、行业规范以及深层次的技术要求等,通过与他们交流,能获取到更具专业性、权威性的需求信息,有助于完善软件在专业层面的功能设定和性能要求等内容。
观察法
-
实地观察:深入到用户的实际工作环境中,观察他们当前的业务操作流程、处理业务的方式以及与现有软件(若有)或工具的交互情况等。例如,观察工作人员如何录入数据、如何查询信息、不同环节之间如何衔接等,从中发现实际操作中的痛点、不便之处以及可以通过软件优化的环节,从而提炼出准确且贴合实际的需求。
-
模拟观察:如果无法进行实地观察,可通过创建模拟业务场景,邀请相关人员进行操作演示,同样观察其操作过程,留意操作习惯、容易出现问题的地方等,为需求分析提供直观的参考依据。
问卷调查法
-
设计合理问卷:根据项目目标和预期获取的需求类型,精心设计问卷内容。问卷应包含选择题、简答题等多种题型,既要有对基本功能需求的询问(如是否需要某种特定功能模块),也要涉及非功能需求(如对软件界面风格偏好等),并且问题表述要清晰、简洁,避免产生歧义。
-
广泛发放收集:将问卷发放给目标用户群体、相关业务部门人员等,确保覆盖范围足够广,以收集到多样化的需求反馈。对回收的问卷进行整理、统计和分析,了解大多数人的共性需求以及部分人的特殊需求,为后续需求分析提供数据支撑。
文档分析法
-
收集业务文档:收集与软件相关的各类业务文档,比如业务流程手册、操作规范、过往项目文档、行业报告等。通过对这些文档的仔细研读,梳理出其中涉及的业务逻辑、业务规则、数据处理要求等内容,从中挖掘出对软件功能、性能等方面的需求线索。
-
分析现有系统文档:如果是对现有软件系统进行升级改造,分析其原有的需求规格说明书、设计文档、测试报告等,了解系统的现状、存在的问题以及用户反馈的改进点,从而准确把握新的需求方向。
原型法
-
构建简易原型:根据初步了解的需求,快速构建出软件系统的简易原型,可以是低保真的纸质原型(用纸张简单绘制界面布局、流程示意等),也可以是利用原型工具制作的高保真电子原型(模拟出接近最终软件外观和交互效果的版本)。
-
用户反馈迭代:将原型展示给用户,让他们实际操作体验,收集他们关于功能是否符合期望、操作是否便捷、是否遗漏重要功能等方面的反馈意见。依据这些反馈,对原型进行修改完善,不断迭代,在这个过程中逐步精准确定软件的各项需求。
用例分析法
-
识别参与者和用例:确定与软件系统相关的各类参与者(如系统用户、外部接口等),分析每个参与者与系统之间的交互行为,识别出相应的用例,也就是参与者期望通过系统完成的具体任务或操作。例如,对于电商系统,买家是参与者,“下单购买商品”就是一个用例。
-
绘制用例图和描述用例:使用统一建模语言(UML)等工具绘制用例图,直观展示参与者、用例以及它们之间的关系。同时,详细描述每个用例的前置条件、后置条件、基本流程、可选流程等内容,清晰地界定软件的功能需求范围,保证需求分析的准确性和完整性。
3-5 画数据流图的步骤
画数据流图(DFD)步骤如下:
确定系统边界
-
明确研究对象:界定软件系统或业务流程范围,分清系统内部与外部实体,如电商系统中确定内部模块及外部买家等实体。
-
画出系统边界线:用矩形框等画出边界线,区分内外,便于梳理数据交互情况。
识别外部实体
-
找出相关参与者:分析业务环境,找出与系统有数据交互的外部实体,像医院管理系统里的患者、医生等。
-
标注外部实体名称:用矩形标注外部实体名称,体现与系统关联。
确定主要流程和数据流向
-
梳理核心业务流程:依系统业务功能梳理主要流程,如图书馆管理系统的借书、还书等流程。
-
分析数据的流动路径:沿业务流程分析数据在系统内外的流向,如借书流程中读者数据的流入、处理及反馈情况。
划分功能模块(加工)
-
分解系统功能:按系统复杂程度和业务逻辑划分功能模块,用圆形或圆角矩形表示,如电商系统划分出用户注册登录等模块。
-
标注功能模块名称:给模块标注简洁准确的名称,反映其主要数据处理操作。
绘制数据流
-
表示数据流动:用带箭头线条表示数据流,标注数据名称展示流向,如订单处理中“购物车商品信息”的流向标注。
-
梳理各层级数据流:从整体开始绘制,先体现高层次流向,再细化各模块内部情况,构建分层数据流图。
检查和完善
-
逻辑性检查:检查元素逻辑关系,保证数据流向合理,无来源不明等问题。
-
完整性检查:确认涵盖主要业务流程、外部实体及重要流向,有遗漏及时完善。
分层细化(如有需要)
-
确定分层结构:复杂系统构建多层数据流图,先绘顶层展示总体情况,再对主要模块细化绘制下层图。
-
保持层级关联:注意各层级对应关系和数据一致性,构成完整描述体系。
3-7 数据字典
数据字典介绍
-
作用
-
消除歧义:让不同人员对数据元素理解一致,避免差异。
-
辅助开发与维护:助力开发人员工作,也是维护人员的重要参考。
-
确保数据完整性与一致性:规范数据相关内容,防止出现数据不一致问题。
-
-
包含的内容
-
数据项:不可再分的最小数据单位,描述含名称、别名、类型、长度、取值范围、含义说明等。
-
数据结构:由数据项等组成的组合,说明有名称、组成成分、使用场景等。
-
数据流:体现数据流动过程,涵盖名称、来源、去向、组成、流量等。
-
数据存储:数据保存处,描述含名称、组成、存储方式、存取频率等。
-
处理过程:对应功能模块,描述含名称、处理逻辑、输入及输出数据流等。
-
-
编制步骤
-
收集相关资料:收集数据流图、业务需求文档等资料,梳理数据相关信息作素材。
-
确定结构和格式:依项目特点选合适结构、格式,确定要包含的内容及描述方式。
-
定义数据元素:按既定要求准确完整定义描述各数据元素,避免模糊表述。
-
审核与完善:组织相关人员审核,据意见修改完善,形成实用的数据字典来支持工作。
-
3-11 判定表
判定表介绍
-
作用
-
清晰呈现逻辑关系:直观展示多条件与动作组合的对应关系,避免逻辑混乱。
-
确保逻辑完整性和准确性:罗列条件组合及对应动作,防遗漏,助测试,保决策准确。
-
方便沟通理解:简洁呈现,便于开发团队内部及与用户沟通,减少理解分歧。
-
-
组成要素
-
条件桩:列出影响决策的条件,以陈述句表述,相互独立,是判断基础。
-
动作桩:指满足条件组合时系统执行的操作或结果,语句简洁,代表应对行为。
-
条件项:是条件取值情况,涵盖所有可能组合,常以真(T)、假(F)等表示。
-
动作项:对应条件组合下系统应执行的动作,与条件项行一一对应。
-
-
构建步骤
-
确定条件和动作:分析业务逻辑,梳理全面且独立的条件与动作,列出条件桩和动作桩。
-
确定条件项的组合:按条件个数计算组合数量,依顺序罗列所有组合形成条件项矩阵。
-
确定动作项:分析各条件组合对应的动作,填入动作项完成构建。
-
化简判定表(可选步骤):检查并合并可简化的规则,确保化简后逻辑符合业务实际。
-
-
使用场景举例
-
订单处理系统:用判定表确定订单处理方式,清晰呈现不同条件下处理流程。
-
员工请假审批系统:展现请假审批逻辑,保证流程准确、一致。
-
3-12 判定树
判定树介绍
-
作用
-
直观呈现逻辑流程:以树状图形展示决策流程,比文字描述更直观易懂。
-
梳理复杂逻辑关系:助梳理多条件及多样化结果间的逻辑,便于发现问题。
-
便于沟通与验证:可视化表达易被接受,提高沟通效率,方便验证业务逻辑。
-
-
组成要素
-
根节点:判定树起始点,是决策开端,一般放首个或最主要条件,只有一个,决定后续走向。
-
分支:从节点引出的线条,对应条件取值情况的路径,数量取决于条件取值个数,相互独立。
-
中间节点:在根与叶节点间,承载判断条件,起细分情况、引导流程作用,数量依决策复杂程度定。
-
叶节点:末端节点,代表最终决策结果或动作,有多个,涵盖全部决策情况。
-
-
构建步骤
-
确定决策问题及相关条件:分析业务场景梳理影响决策的关键条件,明确最终决策结果。
-
选择根节点条件:挑出关键或首先考虑的条件作根节点,标注在树顶端。
-
构建分支及中间节点:依根节点条件取值绘分支,沿分支设中间节点,重复扩展完善树状结构。
-
确定叶节点及标注决策结果:分支尽头是叶节点,标注对应结果,检查完整性确保涵盖所有情况。
-
-
使用场景举例
-
医疗诊断辅助系统:辅助医生诊断疾病,按症状设节点与分支,叶节点为具体诊断结果。
-
学生成绩评定系统:呈现成绩评定流程,根节点、分支、中间节点、叶节点体现评定规则。
-
3-13 其它图形工具
在软件工程的需求分析阶段,常见的图形工具有以下几种:
数据流图(DFD)
作用:描绘系统数据流动、处理与存储情况,展现数据从输入到输出的过程及各部分间交互关系,助梳理业务流程与系统功能。 示例:图书馆管理系统中展示借书时数据的流入、处理及反馈,还有借阅记录存储情况。
用例图
作用:从用户角度描述系统功能及用户与功能的交互关系,明确系统功能范围,便于沟通需求。 示例:电商系统里呈现买家、卖家、管理员等参与者和对应操作功能。
实体关系图(ERD)
作用:用于数据库设计相关分析,描述数据实体间关系,确定数据库表结构与关联方式。 示例:学校管理系统中展现“学生”“课程”“教师”等实体间的多种对应关系。
状态图
作用:描述系统中对象状态变化及触发条件,梳理复杂对象的状态流转情况。 示例:订单系统里展示订单不同状态及在何种条件下转变状态。
活动图
作用:类似流程图,展示业务流程执行顺序、并行情况及活动间逻辑关系,助理解业务流程细节。 示例:企业报销流程中呈现各环节先后顺序及分支情况。
序列图
作用:展示对象间交互顺序与消息传递时间顺序,体现多对象协作情况。 示例:在线支付场景中呈现多对象间支付请求等消息传递过程。
3-14 需求规格说明和需求评审
需求规格说明
定义
需求规格说明(Requirements Specification)是对软件系统需要满足的各项需求进行详细、准确、完整描述的文档,它是软件开发过程中极为关键的指导性文件,将用户的期望、业务需求等转化为开发团队能够依据其进行设计、编码、测试等工作的具体规格要求。
内容构成
-
引言部分:
-
项目背景介绍:简述软件项目启动的缘由、所属的业务领域以及期望解决的主要问题等,让阅读者了解项目的来龙去脉和宏观目标。
-
文档目的说明:明确撰写该需求规格说明书的目的,例如是用于指导开发、作为项目验收依据,还是便于后续的维护工作等。
-
范围界定:清晰划定软件系统的功能范围和边界,指明哪些业务功能包含在本项目内,哪些不在,避免开发过程中出现功能的无端扩展或遗漏。
-
-
总体描述:
-
产品概述:概括性地描述软件产品的整体定位、主要功能特点以及预期的用户群体等信息,从宏观角度呈现软件的基本面貌。
-
系统架构概述:如果已经有初步确定的系统架构设想,可简要介绍系统的整体架构风格(如客户端-服务器架构、分布式架构等)、主要的模块划分以及它们之间的大致关联方式,帮助开发人员对系统的整体结构有初步认识。
-
-
具体需求描述:
-
功能需求:这是核心部分,详细列出软件系统需要实现的每一项功能,通常采用用例(Use Case)等形式进行描述。对于每个用例,要说明其名称、参与的执行者(如用户角色等)、前置条件(在什么情况下可以启动该用例)、后置条件(执行完该用例后系统所处的状态)、基本流程(正常情况下的操作步骤)以及可选流程(可能出现的异常或分支情况的处理步骤)等内容,确保开发人员清楚知道要开发出什么样的功能。
-
非功能需求:涵盖性能需求(如响应时间要求、系统吞吐量等)、可靠性需求(像系统的容错能力、可用性指标等)、安全性需求(例如用户认证授权方式、数据加密要求等)、易用性需求(操作界面的友好程度、操作的便捷性等)以及兼容性需求(与哪些操作系统、其他软件等兼容)等多方面内容,明确软件在除功能之外各方面应达到的标准。
-
数据需求:描述软件系统涉及的数据元素,包括数据的来源、格式、存储方式、数据之间的关系等内容,比如数据库中表结构的设计需求、数据的输入输出格式要求等,为后续的数据设计与管理提供依据。
-
-
接口需求:
-
用户接口需求:规定软件面向用户的操作界面应具备的特点和交互方式,如界面布局、菜单设置、操作按钮的功能及样式等,保证最终的软件界面符合用户的使用习惯和操作便捷性要求。
-
外部接口需求:如果软件需要与其他外部系统进行交互(如调用第三方支付平台、与企业内部的其他管理系统对接等),要详细说明接口的类型(如 API 接口、文件传输接口等)、接口的数据格式、交互的协议以及交互的流程等内容,确保系统间能顺利进行数据交换和协同工作。
-
-
其他需求:
-
约束条件:列举出在软件开发过程中受到的各种限制,例如项目预算限制、开发时间限制、必须采用的特定技术或工具等,这些约束会影响开发团队的决策和实施方式。
-
质量属性需求:进一步强调软件应具备的质量相关特性,如可维护性(便于后续的修改、升级等维护工作)、可扩展性(能够轻松添加新功能或模块)等要求,确保软件在整个生命周期内都能保持良好的性能和适应性。
-
重要性
-
开发依据:开发团队依据需求规格说明书来开展系统设计、编码、测试等各项工作,确保开发出的软件满足用户的需求和期望,是整个软件开发流程的核心指导文件。
-
沟通桥梁:在项目参与各方(用户、开发团队、测试团队、项目管理人员等)之间起到沟通桥梁的作用,各方通过该文档来统一对软件需求的理解,减少因理解不一致而产生的误解和返工情况。
-
验收标准:在软件项目验收阶段,需求规格说明书中描述的各项需求就成为衡量软件是否合格的重要标准,用于判断软件是否达到了预期的功能、性能等要求。
需求评审
定义
需求评审(Requirements Review)是对需求规格说明书以及相关的需求分析成果进行系统性的审查、评估和验证的过程,旨在确保需求的准确性、完整性、可行性、一致性等,发现并解决需求中存在的问题,为后续的软件开发工作奠定良好的基础。
参与人员
-
用户代表:他们最了解业务需求,能够从实际业务使用角度出发,判断需求是否准确反映了业务期望,是否覆盖了所有必要的业务功能和场景,确保软件最终能切实解决业务问题。
-
开发团队成员:包括开发人员、架构师等,他们从技术实现的角度审查需求是否在现有技术条件下可行,是否存在技术难点或不合理的技术要求,同时评估需求对开发工作的影响,如工作量、开发周期等方面的影响。
-
测试团队成员:测试人员参与评审可以提前了解需求,以便从测试的角度思考如何制定测试计划、测试用例等,同时判断需求是否具有可测试性,是否明确了验证需求是否满足的标准和方法等。
-
项目管理人员:他们关注需求是否符合项目的整体目标、预算和时间安排,协调各方意见,确保需求评审过程顺利进行,并根据评审结果对项目计划进行合理调整。
评审内容
-
准确性评审:检查需求规格说明书中的各项需求描述是否准确无误,是否清晰地表达了用户的意图,避免出现模糊、歧义或错误的表述,确保开发团队对需求的理解与用户期望一致。
-
完整性评审:查看需求是否涵盖了软件系统应具备的所有功能、非功能等方面的要求,有没有遗漏重要的业务场景、功能模块或者需求细节,保证软件交付后能全面满足用户的业务需求。
-
可行性评审:从技术、资源、时间等多方面评估需求是否能够实现,分析现有技术水平能否支持需求的实现,开发团队是否具备相应的技术能力,以及在给定的项目预算和时间限制内能否完成相应的开发工作。
-
一致性评审:确认需求之间是否相互矛盾或冲突,例如不同功能需求之间的逻辑是否连贯,非功能需求与功能需求是否匹配,各项需求是否符合项目整体的定位和目标等,保证整个需求体系逻辑严谨、协调一致。
-
可测试性评审:审查需求是否定义了明确的验证标准和方法,是否便于后续通过测试来检验软件是否满足需求,例如是否有清晰的性能指标、功能操作的预期结果等,以便测试团队能够据此开展有效的测试工作。
-
优先级评审:对需求的优先级进行评估和确认,根据业务重要性、紧急程度等因素合理确定各项需求的开发先后顺序,确保资源能够优先投入到关键需求的开发上,提高项目的整体效率。
评审方法
-
正式会议评审:组织各方参与人员召开正式的评审会议,由需求分析人员或者相关负责人对需求规格说明书进行详细讲解,参会人员依次提出疑问、意见和建议,然后共同讨论、分析并记录相关问题,会后根据讨论结果对需求进行修改完善。
-
同行评审:开发团队内部成员之间进行相互评审,利用各自的专业知识和经验,从不同角度对需求进行审查,这种方式可以在正式评审会议之前进行,提前发现一些明显的问题,提高评审效率。
-
走查:由需求分析人员带领其他参与人员,按照需求规格说明书的内容,逐步对软件的功能、流程等进行模拟走查,一边走查一边发现问题,这种方式更注重实际操作过程中的逻辑连贯性和完整性,有助于发现一些隐藏较深的问题。
评审结果处理
-
问题记录与分类:将评审过程中发现的所有问题进行详细记录,并按照问题的严重程度、类型(如准确性问题、完整性问题等)进行分类整理,以便后续有针对性地进行处理。
-
修改与完善:需求分析人员根据评审意见,对需求规格说明书以及相关的需求分析成果进行修改完善,解决存在的问题,确保需求满足准确性、完整性等各项要求。
-
再次评审(如有必要):对于修改后的需求,如果涉及重大变更或者仍然存在争议的部分,可能需要再次组织评审,重复上述评审过程,直至需求达到各方认可的质量标准为止。
4-1 概要设计的概念
概要设计(Outline Design)是一种软件设计方法,用于描述软件系统的总体结构和功能。它是一种高层次的设计方法,用于概括软件系统的主要组件、接口和功能。
概要设计的定义
概要设计是一种软件设计方法,用于描述软件系统的总体结构和功能。它是一种高层次的设计方法,用于概括软件系统的主要组件、接口和功能。
概要设计的目的如下:
-
描述软件系统的总体结构:概要设计用于描述软件系统的总体结构,包括软件系统的主要组件、接口和功能。
-
定义软件系统的功能:概要设计用于定义软件系统的功能,包括软件系统的输入、输出和处理过程。
-
确定软件系统的性能:概要设计用于确定软件系统的性能,包括软件系统的响应时间、吞吐量和安全性。
-
为详细设计提供基础:概要设计为详细设计提供基础,详细设计可以在概要设计的基础上进行。
概要设计的内容如下:
-
软件系统的总体结构:概要设计描述软件系统的总体结构,包括软件系统的主要组件、接口和功能。
-
软件系统的功能:概要设计定义软件系统的功能,包括软件系统的输入、输出和处理过程。
-
软件系统的性能:概要设计确定软件系统的性能,包括软件系统的响应时间、吞吐量和安全性。
-
软件系统的接口:概要设计描述软件系统的接口,包括软件系统的输入、输出和通信协议。
-
软件系统的数据结构:概要设计描述软件系统的数据结构,包括软件系统的数据类型、数据关系和数据存储。
概要设计的方法如下:
-
功能分解:功能分解是一种概要设计方法,用于将软件系统的功能分解为更小的子功能。
-
数据流图:数据流图是一种概要设计方法,用于描述软件系统的数据流和处理过程。
-
系统流图:系统流图是一种概要设计方法,用于描述软件系统的总体结构和功能。
-
对象模型:对象模型是一种概要设计方法,用于描述软件系统的对象结构和行为。
概要设计的工具如下:
-
UML:UML是一种统一建模语言,用于描述软件系统的结构和行为。
-
数据流图工具:数据流图工具是一种用于创建和编辑数据流图的工具。
-
系统流图工具:系统流图工具是一种用于创建和编辑系统流图的工具。
-
对象模型工具:对象模型工具是一种用于创建和编辑对象模型的工具。
4-2 概要设计的原则
概要设计的原则是指在进行概要设计时需要遵循的一些基本原则和指导思想。
这些原则可以帮助设计人员创建出高质量的概要设计,确保软件系统的功能、性能和可维护性。
概要设计的原则
-
模块化:将软件系统分解为多个模块,每个模块负责一个特定的功能或任务。
-
抽象:使用抽象的概念和模型来描述软件系统的结构和行为。
-
封装:将软件系统的实现细节封装在模块或对象内部,仅暴露必要的接口和数据。
-
接口:定义明确的接口来描述模块或对象之间的交互和通信。
-
可重用性:设计模块或对象以便于重用和组合。
-
可维护性:设计软件系统以便于维护和更新。
-
可扩展性:设计软件系统以便于扩展和升级。
-
可靠性:设计软件系统以确保其可靠性和稳定性。
-
安全性:设计软件系统以确保其安全性和保密性。
-
可测试性:设计软件系统以便于测试和验证。
概要设计的指导思想
-
面向对象:使用面向对象的思想和方法来设计软件系统。
-
面向服务:使用面向服务的思想和方法来设计软件系统。
-
事件驱动:使用事件驱动的思想和方法来设计软件系统。
-
数据驱动:使用数据驱动的思想和方法来设计软件系统。
-
功能驱动:使用功能驱动的思想和方法来设计软件系统。
概要设计的最佳实践
-
使用标准化的设计语言:使用标准化的设计语言,如UML,来描述软件系统的结构和行为。
-
创建详细的设计文档:创建详细的设计文档来描述软件系统的设计决策和实现细节。
-
进行设计评审:进行设计评审来确保软件系统的设计质量和完整性。
-
使用设计模式和原则:使用设计模式和原则来指导软件系统的设计。
-
考虑软件系统的整个生命周期:考虑软件系统的整个生命周期,包括开发、测试、部署和维护。
4-3 软件设计过程
在概要设计中,软件设计过程通常包含以下几个关键阶段:
需求理解与梳理阶段
-
深入分析需求规格说明书:仔细研读在需求分析阶段形成的需求规格说明书,全面、准确地理解软件系统需要实现的功能、应具备的性能指标、对安全性和可靠性等方面的要求,以及各种约束条件等内容,确保后续设计工作紧密围绕这些既定需求展开。
-
梳理需求要点:将分散在文档中的各类需求进行梳理、归纳,重点明确核心功能需求以及与之相关联的非功能需求,比如确定哪些功能是支撑业务流程的关键环节,相应的性能上对响应时间、吞吐量有怎样的具体要求等,为软件系统的整体架构设计奠定基础。
总体架构设计阶段
-
确定系统架构风格:结合软件项目的规模、应用场景、性能要求等因素,选择合适的系统架构风格,例如是采用传统的客户端-服务器(C/S)架构、浏览器-服务器(B/S)架构,还是分布式架构、微服务架构等。不同的架构风格有其各自的特点和适用范围,需权衡利弊后做出选择。
-
划分功能模块:依据业务功能的逻辑关系和独立性,将整个软件系统划分为若干相对独立的功能模块,明确各个模块的大致职责和功能范围,比如对于电商系统,可划分为用户管理模块、商品展示模块、订单处理模块、支付模块等,使系统结构清晰,便于开发和维护。
-
规划模块间的关系:确定各功能模块之间的交互方式、接口定义以及数据传递关系,例如某个模块是通过接口调用的方式向另一个模块请求数据,还是采用消息队列的形式进行数据传递等,确保模块之间既相互协作又保持相对独立,共同构成一个有机的整体系统。
接口设计阶段
-
外部接口设计:如果软件系统需要与外部其他系统进行交互,如调用第三方支付平台接口、与企业内部的其他业务系统对接等,要详细设计外部接口,明确接口的类型(如 API 接口、Web Service 接口等)、接口的数据格式(如 JSON 格式、XML 格式等)、交互的协议(如 HTTP 协议、TCP/IP 协议等)以及接口的调用流程和权限控制等内容,保障系统间能顺利通信和协同工作。
-
内部接口设计:针对软件系统内部各功能模块之间的接口,同样要进行细致设计,定义接口的输入输出参数、接口的功能语义以及调用规则等,使得模块之间的交互清晰明了,方便开发人员进行模块的独立开发与集成测试。
数据结构与算法设计阶段
-
分析数据需求:根据软件系统的功能需求,梳理出需要处理的数据类型、数据量大小、数据的存储和使用特点等,例如对于一个社交软件,要处理用户的基本信息、好友关系数据、聊天记录等不同类型且海量的数据,为后续合理设计数据结构做准备。
-
选择合适的数据结构:依据数据的特点和操作要求,选用恰当的数据结构来组织和存储数据,比如对于频繁查找操作的数据可选用哈希表结构,对于需要保持元素顺序的数据可采用链表或数组结构等,提高数据的存储和访问效率。
-
设计算法:针对软件系统中涉及的关键业务逻辑和功能实现,如搜索功能、排序功能、数据加密功能等,设计相应的算法,要综合考虑算法的时间复杂度、空间复杂度以及算法的准确性和稳定性等因素,确保算法能高效、准确地完成相应的数据处理任务。
用户界面设计阶段
-
确定界面风格与布局:根据目标用户群体的特点、使用习惯以及软件的功能特性,确定用户界面的整体风格,是简洁明了的商务风格,还是活泼生动的娱乐风格等,同时规划界面的布局,确定各个功能按钮、菜单、信息展示区域等在界面上的位置和呈现方式,以提高界面的易用性和用户体验。
-
设计交互流程:设计用户与软件系统进行交互的流程,比如用户如何进行登录操作、如何查找信息、如何提交业务请求等,确保交互过程自然、便捷,符合用户的操作预期,减少用户的操作成本和学习成本。
安全性与可靠性设计阶段
-
安全性设计:从多个方面考虑软件系统的安全保障,包括用户身份认证与授权机制的设计,确保只有合法用户能访问相应功能;对敏感数据进行加密处理,防止数据泄露;设置访问控制策略,限制不同用户角色对系统资源的访问权限等,构建起全方位的安全防护体系。
-
可靠性设计:通过采用冗余设计(如服务器冗余、数据备份等)、容错机制(如错误捕获与处理、自动恢复功能等)以及制定合理的系统监控与维护策略等方式,提高软件系统在面对各种异常情况(如硬件故障、网络中断、软件错误等)时的可靠性,保障系统能持续稳定地运行。
设计评审与优化阶段
-
组织内部评审:召集开发团队中的相关成员(如架构师、资深开发人员、测试人员等),对概要设计方案进行评审,从不同专业角度提出意见和建议,例如架构师查看整体架构的合理性和扩展性,开发人员评估设计的可实现性,测试人员考虑是否便于后续测试等,确保设计方案符合技术要求和项目需求。
-
根据评审意见优化:针对评审过程中发现的问题和提出的建议,对概要设计方案进行修改和优化,完善系统架构、细化接口设计、调整数据结构等,不断提升设计的质量,确保其能为后续的详细设计和编码工作提供坚实、合理的基础。
4-4 概要设计的基本任务
概要设计基本任务
-
定义软件系统功能和性能,涵盖输入、输出及处理过程。
-
确定软件系统结构与组织,包含模块、组件和接口。
-
设计软件系统接口,涉及输入、输出及通信协议。
-
定义软件系统数据结构和算法,包括数据类型、关系及存储。
-
确定软件系统安全性和保密性,像访问控制、数据加密、安全协议。
-
设计软件系统用户界面,例如图形、命令行、Web界面。
-
定义软件系统测试和验证,包含测试用例、数据和脚本。
-
确定软件系统部署和维护,如安装、配置、升级。
-
设计软件系统文档和培训,包括用户手册、开发文档、培训材料。
-
进行设计评审和优化,有设计评审、优化及改进。
概要设计基本步骤
-
需求分析,确定软件系统功能和性能。
-
确定软件系统结构和组织。
-
设计软件系统接口。
-
定义软件系统数据结构和算法。
-
确定软件系统安全性和保密性。
-
设计软件系统用户界面。
-
定义软件系统测试和验证。
-
确定软件系统部署和维护。
-
设计软件系统文档和培训。
-
进行设计评审和优化。
概要设计基本工具
-
UML,描述软件系统结构和行为。
-
数据流图,描述软件系统数据流和处理过程。
-
系统流图,描述软件系统总体结构和功能。
-
对象模型,描述软件系统对象结构和行为。
-
设计模式和原则,指导软件系统设计。
4-5 模块设计的基本原理
模块设计是软件开发中概要设计阶段的重要工作,其基本原理主要包括以下几个方面:
模块化原理
-
模块划分
-
将软件系统按照一定的规则分解成多个相对独立的模块。例如,在一个电商系统中,可以划分为用户管理模块、商品管理模块、订单管理模块等。每个模块负责特定的功能,使得系统结构更加清晰,便于开发和维护。
-
模块划分的依据可以是功能、业务流程、数据相关性等。如按照功能划分,登录功能可以作为一个独立模块,负责用户身份验证和登录逻辑处理。
-
-
模块独立性
-
强调模块之间的低耦合和高内聚。耦合是指模块之间的依赖程度,低耦合意味着模块之间的联系尽可能少,一个模块的修改对其他模块的影响较小。例如,用户管理模块和商品管理模块之间应尽量减少直接的数据交互和功能调用。
-
内聚是指模块内部各元素之间的联系紧密程度,高内聚表示模块内部的功能联系紧密,一个模块只完成一个相对独立的功能。比如,订单处理模块应专注于订单的创建、支付、发货等与订单相关的操作,而不涉及用户信息修改等其他功能。
-
抽象与信息隐藏原理
-
抽象
- 忽略系统中具体的实现细节,只关注系统的整体功能和行为。在模块设计中,通过抽象可以定义模块的接口和对外提供的服务,而不考虑模块内部的具体实现方式。例如,定义一个文件操作模块,对外提供打开文件、读取文件、写入文件等抽象接口,用户只需要调用这些接口即可完成文件操作,无需了解文件在磁盘上的存储格式和具体读写算法。
-
信息隐藏
- 将模块内部的实现细节隐藏起来,只对外提供必要的接口。这样可以保护模块内部的数据和算法不被外部随意访问和修改,提高模块的安全性和可维护性。例如,一个数据库访问模块,将数据库连接的细节、SQL 语句的执行过程等隐藏起来,只提供查询、插入、更新等简单的接口供其他模块调用。
逐步求精原理
-
从抽象到具体
- 模块设计是一个逐步细化的过程,从最初的抽象概念开始,逐步将其分解为更具体的子模块和功能。例如,在设计一个企业资源规划(ERP)系统时,最初可以将系统抽象为财务管理、人力资源管理、生产管理等几个大的模块,然后再将每个大模块逐步细化为更具体的子模块,如财务管理模块可以细化为账务处理、报表生成、预算管理等子模块。
-
迭代优化
- 在逐步求精的过程中,不断对模块进行评估和优化。根据实际情况调整模块的划分和设计,确保模块的功能合理、接口清晰、性能良好。例如,在开发过程中发现某个模块的功能过于复杂,可以进一步将其分解为更小的模块;或者发现模块之间的耦合度过高,通过调整接口和数据传递方式来降低耦合度。
扇入与扇出原理
-
扇入
- 指一个模块的直接上级模块的个数。扇入越大,说明该模块被多个上级模块调用,其复用性越高。例如,一个通用的日期处理模块可能被用户信息管理模块、订单管理模块、报表生成模块等多个模块调用,该模块的扇入就较大。
-
扇出
- 指一个模块直接调用的下级模块的个数。扇出过大可能会导致模块的复杂度增加,管理难度增大;扇出过小则可能表示模块的功能过于单一。一般来说,扇出的合理范围在 3 - 5 之间较为合适,但这也需要根据具体的系统情况进行调整。例如,一个订单处理模块可能会调用库存检查模块、支付处理模块、物流信息模块等下级模块,要合理控制其扇出数量,以保证模块的可维护性和可扩展性。
控制层次原理
-
模块层次结构
- 软件系统的模块通常构成一个层次结构,高层模块负责对低层模块进行调用和协调,低层模块完成具体的功能实现。例如,在一个多层架构的 Web 应用中,表现层模块调用业务逻辑层模块,业务逻辑层模块再调用数据访问层模块,各层模块之间通过接口进行交互,形成一个清晰的控制层次。
-
职责分配
- 根据模块在控制层次中的位置,合理分配其职责。高层模块主要负责系统的整体控制和协调,关注业务流程的调度;低层模块专注于具体的业务处理和数据操作。例如,在一个游戏开发中,游戏主控制模块负责管理游戏的启动、暂停、结束等整体流程,而角色移动模块、战斗计算模块等低层模块则负责具体的游戏功能实现。
4-6 抽象
-
含义:抽象是一种对复杂现实世界系统进行简化和概括的思维方式与设计手段。它着重于提取系统中关键的、具有共性的部分,隐藏那些具体的、非关键的实现细节,从而让设计人员能够站在更高层次、更宏观的角度去把握系统的整体架构和主要功能。例如,在设计一个电商系统时,将商品管理模块抽象为包含商品信息录入、查询、修改等核心功能的单元,而暂不深入考虑具体数据库中每条商品记录的存储格式、索引构建等细节内容,只关注其对外提供的功能接口,方便后续对整个系统进行模块划分与架构搭建。
-
作用:有助于降低系统的复杂性,使开发人员可以聚焦于重要的功能和结构,便于不同开发人员基于抽象出来的概念和接口进行分工协作,同时也提高了系统的可扩展性和可维护性,因为后续若对抽象部分的具体实现进行修改,只要保证接口不变,就不会对其他依赖该抽象的部分产生较大影响。
4-7 耦合
含义:耦合是用来衡量软件系统中不同模块之间相互依赖程度的指标。简单来说,就是一个模块与其他模块之间关联的紧密程度。耦合程度有高有低,
例如,若模块A直接调用了模块B内部的具体函数、变量,并且模块A的正常运行高度依赖模块B的内部实现细节,那么模块A和模块B之间就是高耦合关系;反之,如果模块A和模块B之间仅通过定义好的标准接口进行交互,各自内部实现对对方来说是透明的,它们之间的耦合程度就相对较低。
影响:高耦合不利于系统的维护与扩展,因为当一个高耦合的模块发生变化时,很可能会牵一发而动全身,导致与之耦合的其他模块也要跟着修改;而低耦合则使得各个模块相对独立,便于单独进行开发、测试、维护以及替换,系统的灵活性和可扩展性更强。在概要设计中,要尽量降低模块间的耦合度,让系统结构更加合理、健壮。
4-8 内聚
含义:内聚主要描述的是模块内部各元素(如函数、数据等)之间联系的紧密程度,体现了模块功能的单一性和完整性。一个内聚性高的模块,其内部的所有元素都是围绕着一个明确、单一的功能目标而存在并协作的。
例如,在用户登录模块中,包含了获取用户输入信息、验证用户名和密码格式、与数据库交互验证账号合法性等功能元素,这些元素紧密配合,共同实现用户登录这一功能,该模块就具有较高的内聚性;相反,如果一个模块中混杂了许多关联性不强、功能分散的元素,像既包含用户登录功能相关代码,又有订单处理的部分代码,那它的内聚性就比较低。
意义:高内聚的模块更易于理解、维护和复用,因为其功能明确,内部逻辑清晰,开发人员可以很清楚地知道这个模块的作用以及如何对其进行改进优化。在概要设计阶段,需要尽量提高模块的内聚性,使系统的各个组成部分功能分明、结构合理,提升整个软件系统的质量。
4-9 结构化设计方法
结构化设计方法是经典软件设计法,基于数据流图,强调系统模块化与层次结构,提升软件可维护性等。
基本思想
自顶向下、逐步求精、模块化与信息隐藏,把复杂系统按功能分解成小模块。
设计步骤
-
分析数据流图:判断数据流类型,有变换型(含输入、变换、输出)和事务型(依事务中心发散)。
-
确定模块结构:变换型分输入、变换、输出模块;事务型设事务中心模块及子模块。
-
设计接口与功能:明确模块输入输出,定义单一、清晰的功能。
-
优化模块结构:降低模块间耦合度,提高模块内聚性。
工具与表示法:常用结构图展示模块关系和调用。
4-10 面向数据流的设计方法
面向数据流的设计方法基于数据流图,将数据流动和处理过程映射为软件模块结构。
基本概念
以系统数据流为设计基础,按数据流动与处理顺序划分模块,使软件结构清晰、易维护。
设计步骤
-
分析数据流图:判断数据流类型,有变换型(含输入、变换、输出部分,如图书管理系统查询流程)和事务型(以事务中心发散,如银行系统不同业务处理)。
-
确定模块结构
-
变换分析:分输入、变换、输出模块,各负责数据接收预处理、核心处理、结果输出。
-
事务分析:设事务中心模块分发请求,为各事务处理流程设计子模块。
-
4-11 变换分析
变换分析是面向数据流设计中针对变换型数据流图的设计技术,可将其映射为软件模块结构。
变换型数据流图特点
有输入、变换、输出三部分。外部数据经输入预处理,进变换中心做核心处理,再经输出输出结果。
如成绩统计系统,接收成绩数据、处理数据、输出报表。
变换分析步骤
-
确定三部分:从物理输入向中间找输入流,从物理输出向中间找输出流,二者间为变换中心。
-
设计模块结构:顶层为主控模块,调用输入、变换、输出三个第一层模块。
-
分解模块:输入模块分解为数据采集等子模块;变换模块按处理逻辑分解,如成绩统计的计算子模块;输出模块分解为结果格式化等子模块。
4-12 事务分析
事务分析是面向数据流设计里针对事务型数据流图的软件结构设计技术。
事务型数据流图特点
存在事务中心,接收输入数据(事务),按事务类型将其分解成多个发散的数据流,每个数据流对应不同处理流程。
如银行系统依取款、存款等业务请求分发给不同处理模块。
事务分析步骤
-
确定事务中心和动作路径:找到接收并分发事务的事务中心,确定每个事务对应的动作路径。
-
设计顶层和第一层模块:顶层主控模块调用事务中心模块和各动作路径模块,事务中心模块负责分发事务。
-
分解模块:事务中心模块分解为接收、分类、调度子模块;动作路径模块按功能细分。
4-13 模块结构的改进
在软件设计中,模块结构的合理性对软件的质量和可维护性至关重要。对模块结构进行改进可以从多个方面入手,以下是详细介绍:
降低耦合度
耦合度指的是模块之间的依赖程度,高耦合会使软件的修改和维护变得困难,因此需要降低模块间的耦合。
-
数据耦合:尽量采用数据耦合,即模块之间仅通过参数传递数据。例如在一个学生成绩管理系统中,成绩计算模块和成绩显示模块之间通过传递学生成绩数据来交互,这种方式使模块间的依赖关系较为简单,一个模块的修改不会对另一个模块产生过多影响。
-
避免内容耦合:内容耦合是最糟糕的耦合方式,即一个模块直接访问另一个模块的内部数据或控制逻辑。应坚决避免这种情况,保证每个模块的独立性。比如,不能让一个模块直接修改另一个模块内部的私有变量,而应通过合理的接口来实现数据交互。
-
减少公共环境耦合:公共环境耦合是指多个模块共享全局数据或公共环境。虽然有时难以完全避免,但要尽量减少其使用。例如,避免多个模块同时依赖一个全局变量来进行操作,可通过参数传递等方式来实现数据共享。
提高内聚性
内聚性体现了模块内部各元素之间联系的紧密程度,高内聚的模块功能单一、便于维护和复用。
-
功能内聚:使模块具有功能内聚性,即一个模块只完成一个明确的功能。例如,在一个电商系统中,购物车模块只负责管理用户的购物车信息,包括添加商品、删除商品、修改商品数量等操作,而不涉及商品的展示、订单的处理等其他功能。
-
避免偶然内聚:偶然内聚是指模块内的元素之间没有明确的逻辑关系,只是因为偶然的原因被放在一起。这种模块不利于理解和维护,应尽量避免。比如,不要将一些无关的功能代码随意拼凑在一个模块中。
模块扇入和扇出的平衡
-
扇入:扇入指的是一个模块被其他模块调用的次数。较高的扇入表示该模块的复用性较好。例如,在一个图形处理系统中,通用的图形绘制函数模块被多个不同的绘图界面模块调用,扇入较高,说明该模块的复用价值高。
-
扇出:扇出指的是一个模块调用其他模块的数量。扇出过大可能导致模块的控制过于复杂,应尽量控制在一个合理的范围内。一般来说,扇出以 3 - 4 个为宜。例如,一个模块调用了过多的子模块来完成不同的功能,会使该模块的逻辑变得复杂,难以理解和维护。
模块的作用域和控制域
-
作用域:模块的作用域是指受该模块内一个判定影响的所有模块的集合。
-
控制域:模块的控制域是指该模块本身以及所有直接或间接从属于它的模块的集合。
-
应尽量使模块的作用域在其控制域之内,这样可以使系统的控制结构更加清晰,便于对系统进行修改和维护。例如,如果一个判定条件的影响范围超出了该模块的控制范围,会导致系统的逻辑变得混乱,难以追踪和调试。
模块的大小
模块的大小要适中,既不能过大也不能过小。
-
模块过大可能包含过多的功能,导致内聚性降低、耦合度增加,难以理解和维护。例如,一个包含了整个系统所有功能的超级模块,会使代码的可读性和可维护性变得极差。
-
模块过小则会增加模块之间的交互复杂度,使系统的整体结构变得松散。比如,将一个简单的功能拆分成过多的小模块,会增加模块之间的调用开销和管理成本。
4-14 Jackson方法
Jackson 方法是一种结构化设计方法,用于软件设计和开发。
它由Michael A. Jackson于1970年代提出,主要用于设计和开发大型软件系统。
Jackson方法的主要特点包括
-
结构化设计:Jackson方法强调结构化设计的重要性,通过分解复杂的系统为更小的模块,来提高系统的可维护性和可扩展性。
-
数据流图:Jackson方法使用数据流图(Data Flow Diagram,DFD)来描述系统的数据流和处理过程。数据流图是一种图形化的表示方法,用于描述系统的输入、输出、处理和存储过程。
-
状态转换图:Jackson方法使用状态转换图(State Transition Diagram,STD)来描述系统的状态和状态转换过程。状态转换图是一种图形化的表示方法,用于描述系统的状态、事件和状态转换规则。
-
模块化:Jackson方法强调模块化的重要性,通过将系统分解为更小的模块,来提高系统的可维护性和可扩展性。
-
接口化:Jackson方法强调接口化的重要性,通过定义模块之间的接口,来确保模块之间的通信和数据交换。
Jackson方法的主要步骤包括
-
需求分析:收集和分析软件系统的需求。
-
数据流图设计:使用数据流图来描述系统的数据流和处理过程。
-
状态转换图设计:使用状态转换图来描述系统的状态和状态转换过程。
-
模块化设计:将系统分解为更小的模块。
-
接口化设计:定义模块之间的接口。
-
实现:根据设计文档编写代码。
Jackson方法的优点包括
-
提高软件系统的可维护性和可扩展性
-
提高软件系统的可靠性和稳定性
-
提高软件开发效率和质量
-
降低软件开发成本和风险
Jackson方法的缺点包括
-
设计过程复杂和耗时
-
需要大量的文档和设计工作
-
可能导致过度设计和不必要的复杂性
总之,Jackson方法是一种结构化设计方法,用于软件设计和开发。
它通过数据流图、状态转换图、模块化和接口化等原则来提高软件系统的可维护性、可扩展性和可靠性。
4-16 详细设计
软件工程中的详细设计(Detailed Design)是软件开发过程中的一个阶段,旨在对软件系统的总体设计进行详细的描述和定义。
详细设计的主要目标是
-
明确软件系统的结构和行为:详细设计阶段需要明确软件系统的结构、组件、接口和行为。
-
定义软件系统的详细规格:详细设计阶段需要定义软件系统的详细规格,包括数据结构、算法、接口和协议。
-
确定软件系统的实现细节:详细设计阶段需要确定软件系统的实现细节,包括编程语言、开发工具和技术。
详细设计的主要步骤包括
-
模块设计:对软件系统的每个模块进行详细设计,包括模块的结构、接口和行为。
-
数据结构设计:设计软件系统的数据结构,包括数据类型、数据关系和数据存储。
-
算法设计:设计软件系统的算法,包括算法的逻辑、流程和性能。
-
接口设计:设计软件系统的接口,包括用户接口、程序接口和数据接口。
-
协议设计:设计软件系统的协议,包括通信协议、数据协议和安全协议。
-
测试设计:设计软件系统的测试计划,包括测试用例、测试数据和测试脚本。
详细设计的输出包括
-
详细设计文档:详细设计文档是详细设计阶段的主要输出,包括软件系统的详细规格、结构和行为。
-
软件系统的详细模型:详细设计阶段需要创建软件系统的详细模型,包括数据流图、状态转换图和类图。
-
测试计划:测试计划是详细设计阶段的输出,包括测试用例、测试数据和测试脚本。
详细设计的优点包括
-
提高软件系统的质量和可靠性
-
提高软件系统的可维护性和可扩展性
-
提高软件开发效率和质量
-
降低软件开发成本和风险
详细设计的缺点包括
-
设计过程复杂和耗时
-
需要大量的文档和设计工作
-
可能导致过度设计和不必要的复杂性
4-17 过程设计
过程设计(Process Design)是软件工程中的一个阶段,旨在设计软件开发过程和工作流程。过程设计的目标是创建一个高效、有效和可持续的软件开发过程,确保软件项目的成功。
过程设计的主要步骤包括:
-
定义软件开发过程:定义软件开发过程的范围、目标和任务。
-
确定软件开发方法:确定软件开发方法,包括敏捷开发、瀑布开发等。
-
设计工作流程:设计软件开发工作流程,包括需求分析、设计、实现、测试和维护等阶段。
-
定义角色和职责:定义软件开发团队的角色和职责,包括项目经理、开发人员、测试人员等。
-
确定软件开发工具:确定软件开发工具,包括编程语言、开发环境、测试工具等。
-
设计软件开发环境:设计软件开发环境,包括硬件、软件和网络等。
-
定义软件开发标准:定义软件开发标准,包括编码标准、测试标准等。
过程设计的输出包括:
-
软件开发过程文档:软件开发过程文档是过程设计阶段的主要输出,包括软件开发过程的定义、工作流程和角色职责等。
-
软件开发方法文档:软件开发方法文档是过程设计阶段的输出,包括软件开发方法的选择和应用等。
-
工作流程图:工作流程图是过程设计阶段的输出,包括软件开发工作流程的图形化表示。
-
软件开发环境文档:软件开发环境文档是过程设计阶段的输出,包括软件开发环境的定义和配置等。
过程设计的优点包括:
-
提高软件开发效率和质量
-
提高软件开发团队的协作和沟通
-
提高软件开发过程的可视化和控制
-
降低软件开发风险和成本
过程设计的缺点包括:
-
设计过程复杂和耗时
-
需要大量的文档和设计工作
-
可能导致过度设计和不必要的复杂性
4-18 NS图 PAD图
NS图(Nassi-Shneiderman图)和PAD图(Program Analysis Diagram)都是用于描述软件系统结构和行为的图形化工具。
NS图
NS图是一种用于描述软件系统结构和行为的图形化工具。
它由Nassi和Shneiderman在1973年提出。
NS图使用一种特殊的符号和布局来描述软件系统的结构和行为。
NS图的主要特点是:
-
使用矩形框来表示软件系统的模块或函数
-
使用箭头来表示模块或函数之间的调用关系
-
使用特殊符号来表示循环、条件判断和其他控制结构
NS图的优点是:
-
可以清晰地描述软件系统的结构和行为
-
可以帮助开发人员理解软件系统的复杂性
-
可以用于软件系统的设计、开发和测试
PAD图
PAD图是一种用于描述软件系统结构和行为的图形化工具。
它由Ross和Schoman在1977年提出。
PAD图使用一种特殊的符号和布局来描述软件系统的结构和行为。
PAD图的主要特点是:
-
使用圆圈来表示软件系统的模块或函数
-
使用箭头来表示模块或函数之间的调用关系
-
使用特殊符号来表示循环、条件判断和其他控制结构
PAD图的优点是:
-
可以清晰地描述软件系统的结构和行为
-
可以帮助开发人员理解软件系统的复杂性
-
可以用于软件系统的设计、开发和测试
NS图和PAD图的比较
NS图和PAD图都是用于描述软件系统结构和行为的图形化工具。两者都有其优点和缺点。
NS图的优点是:
-
可以清晰地描述软件系统的结构和行为
-
可以帮助开发人员理解软件系统的复杂性
PAD图的优点是:
-
可以清晰地描述软件系统的结构和行为
-
可以帮助开发人员理解软件系统的复杂性
NS图和PAD图的主要区别在于:
-
NS图使用矩形框来表示软件系统的模块或函数,而PAD图使用圆圈
-
NS图使用箭头来表示模块或函数之间的调用关系,而PAD图使用箭头和特殊符号
4-19 判定表
软件工程中的判定表(Decision Table)是一种用于描述软件系统的逻辑关系和决策过程的工具。它是一种表格形式的工具,用于描述软件系统的输入、输出和决策过程。
判定表的组成
-
条件:描述软件系统的输入条件和约束。
-
动作:描述软件系统的输出和动作。
-
规则:描述软件系统的决策过程和逻辑关系。
判定表的作用
-
描述软件系统的逻辑关系:判定表可以描述软件系统的逻辑关系和决策过程。
-
简化软件系统的设计:判定表可以简化软件系统的设计过程。
-
提高软件系统的可读性:判定表可以提高软件系统的可读性和可理解性。
判定表的类型
-
简单判定表:只包含一个条件和一个动作。
-
复杂判定表:包含多个条件和动作。
-
嵌套判定表:包含多个判定表。
判定表的应用
应用于软件系统的设计、测试与维护中,判定表均可用于描述、测试及维护其逻辑关系和决策过程。
判定表的优点:判定表可简化软件系统设计过程、提高软件系统可读性与可理解性以及提高其可靠性与稳定性。
判定表的缺点
-
复杂性:判定表可能很复杂,难以理解和维护。
-
可扩展性:判定表可能不易扩展,难以适应软件系统的变化。
-
可读性:判定表可能不易读懂,难以理解软件系统的逻辑关系和决策过程。
4-20 详细设计说明书
详细设计说明书(DDS)是描述软件系统详细设计的重要文档,涵盖架构、组件等多方面内容。
其目的包括:
-
描述软件系统详细设计,含架构、组件等要素。
-
为开发人员提供实施指南。
-
为测试人员提供测试依据。
-
为维护人员提供维护参考。
内容涉及:
- 软件系统的架构、组件、接口、数据结构、算法、安全性、性能等方面的具体描述。
格式包含:
-
标题(含软件系统名称、版本号等)。
-
摘要(概述、功能、性能等)。
-
内容(架构、组件等多方面)。
-
附录(相关文档、图表、代码等)。
作用有:
-
指导开发、测试、维护工作。
-
提高软件系统质量。
5-1 用户界面设计的任务
用户界面设计(User Interface Design,简称 UI Design)
主要任务:设计软件产品的交互界面,使其易于使用、直观、美观和高效。
具体来说,UI 设计的任务包括:
-
定义界面布局和结构:确定软件产品的界面布局、菜单、按钮和其他控件的位置和组织方式。
-
设计界面元素:设计界面元素,如按钮、图标、颜色、字体等,使其符合软件产品的品牌和风格。
-
创建交互原型:创建交互原型,模拟软件产品的交互行为,测试用户体验。
-
优化用户体验:根据用户反馈和测试结果,优化界面设计,改善用户体验。
-
确保可用性和可访问性:确保软件产品的界面设计符合可用性和可访问性标准,方便不同用户群体使用。
-
与开发团队合作:与开发团队合作,确保界面设计的实现和开发。
UI 设计的任务是创造一个直观、易用、美观和高效的软件产品界面,提高用户体验和满意度。
5-2 用户界面的任务
用户界面的任务包括:
-
接收用户输入:接受用户的命令、数据和其他输入。
-
显示系统信息:显示系统状态、数据和其他信息。
-
提供交互功能:提供各种交互功能,如按钮、菜单、对话框等。
-
控制系统行为:控制系统的行为,根据用户输入执行相应的操作。
-
提供反馈:提供反馈,告知用户操作结果、错误信息等。
-
管理用户会话:管理用户会话,记录用户的操作、状态等。
-
确保安全:确保系统的安全性,防止未经授权的访问和操作。
总之,用户界面的任务是为用户提供一个友好的、直观的、安全的交互环境,方便用户使用系统。
5-3 用户界面基本类型
用户界面:
-
命令行界面(CLI):使用命令行输入命令和参数,通过文本输出结果。
-
图形用户界面(GUI):使用图形元素,如窗口、按钮、菜单等,通过鼠标和键盘交互。
-
语音用户界面(VUI):使用语音输入命令和参数,通过语音输出结果。
-
触摸用户界面(TUI):使用触摸屏输入命令和参数,通过图形输出结果。
-
Web用户界面(Web UI):使用Web浏览器访问和交互,通过HTML、CSS、JavaScript等技术实现。
-
移动用户界面(Mobile UI):使用移动设备,如智能手机、平板电脑等,通过触摸屏和语音输入交互。
5-4 用户界面的分类
用户界面常见的分类方法:
-
根据交互方式分类:
-
命令行界面(CLI)
-
图形用户界面(GUI)
-
语音用户界面(VUI)
-
触摸用户界面(TUI)
-
Web用户界面(Web UI)
-
移动用户界面(Mobile UI)
-
-
根据设备类型分类:
-
桌面用户界面(Desktop UI)
-
移动用户界面(Mobile UI)
-
嵌入式用户界面(Embedded UI)
-
Web用户界面(Web UI)
-
-
根据应用领域分类:
-
操作系统用户界面(OS UI)
-
应用程序用户界面(Application UI)
-
网络用户界面(Network UI)
-
嵌入式系统用户界面(Embedded System UI)
-
-
根据用户群体分类:
-
普通用户界面(General User UI)
-
专家用户界面(Expert User UI)
-
残疾用户界面(Accessible UI)
-
-
根据设计风格分类:
-
现代用户界面(Modern UI)
-
简约用户界面(Minimalist UI)
-
Material Design用户界面(Material Design UI)
-
Flat Design用户界面(Flat Design UI)
-
5-5 用户界面设计的原则
用户界面设计的原则包括:
-
直观性:界面元素应该是直观的,用户能够快速理解和使用。
-
一致性:界面应该保持一致的风格和设计原则,提高用户体验。
-
简洁性:界面应该尽量简洁,减少不必要的元素,提高用户体验。
-
可用性:界面应该易于使用,用户能够快速找到和使用所需的功能。
-
可访问性:界面应该满足不同用户群体的需求,包括残障用户。
-
反馈性:界面应该及时提供反馈,告知用户操作结果和状态。
-
清晰性:界面应该清晰地显示系统状态和数据,提高用户理解和使用的效率。
-
灵活性:界面应该能够适应不同的用户需求和屏幕大小。
-
个性化:界面应该能够根据用户的个性化需求进行个性化设置。
-
多任务性:界面应该能够同时处理多个任务,提高用户的工作效率。
5-6 数据输入界面设计
数据输入界面设计:用于输入数据的界面,包括表单、输入框、按钮等元素。
原则和最佳实践:
-
简洁明了:数据输入界面应该简洁明了,避免不必要的元素和复杂的布局。
-
清晰的标签:每个输入框和按钮应该有清晰的标签,说明其用途和要求。
-
合理的布局:输入框和按钮应该按照逻辑顺序排列,方便用户输入数据。
-
实时反馈:输入界面应该提供实时反馈,告知用户输入数据的有效性和格式。
-
错误处理:输入界面应该能够处理错误输入,提供清晰的错误消息和纠正建议。
-
兼容性:输入界面应该兼容不同设备和浏览器,确保用户可以在任何设备上输入数据。
-
安全性:输入界面应该确保数据安全,使用 HTTPS 协议和加密技术保护用户数据。
-
可访问性:输入界面应该满足不同用户群体的需求,包括残障用户。
设计模式包括:
-
表单:用于收集用户数据的表单,包括输入框、选择框、按钮等元素。
-
输入框:用于输入单个数据项的输入框,包括文本输入框、密码输入框等。
-
选择框:用于选择多个数据项的选择框,包括下拉菜单、复选框等。
-
按钮:用于提交数据或执行操作的按钮,包括提交按钮、重置按钮等。
高效、易用和安全的数据输入界面。
5-7 输入表格设计
设计模式包括:
-
单行输入表格:用于输入单个数据项的表格,包括输入框和按钮。
-
多行输入表格:用于输入多个数据项的表格,包括输入框、选择框和按钮。
-
表格输入:用于输入数据的表格,包括输入框、选择框和按钮。
-
树形输入表格:用于输入树形结构数据的表格,包括输入框、选择框和按钮。
最佳实践:
-
使用清晰的标签:每个输入框应该有清晰的标签,说明其用途和要求。
-
使用合理的布局:输入框应该按照逻辑顺序排列,方便用户输入数据。
-
提供实时反馈:输入表格应该提供实时反馈,告知用户输入数据的有效性和格式。
-
处理错误输入:输入表格应该能够处理错误输入,提供清晰的错误消息和纠正建议。
-
确保兼容性:输入表格应该兼容不同设备和浏览器,确保用户可以在任何设备上输入数据。
5-8 数据显示界面设计
设计模式包括:
-
图表:用于展示数据趋势和关系的图表,包括折线图、柱状图、饼图等。
-
表格:用于展示数据的表格,包括简单表格、树形表格等。
-
文本:用于展示数据的文本,包括简单文本、富文本等。
-
仪表盘:用于展示数据的仪表盘,包括速度仪表盘、温度仪表盘等。
-
地图:用于展示地理数据的地图,包括静态地图、交互式地图等。
最佳实践:
-
使用颜色和图形:使用颜色和图形来突出重要数据和趋势。
-
提供交互性:提供交互性,用户能够通过点击、滑动等方式探索数据。
-
保持一致性:保持一致的风格和设计原则,提高用户体验。
-
实时更新:实时更新数据,反映最新的数据变化。
-
考虑可访问性:考虑不同用户群体的需求,包括残障用户。
5-9 图形显示和控制界面的设计
设计模式包括:
-
图形编辑器:用于编辑和创建图形数据的编辑器,包括绘图工具、图形处理工具等。
-
图形浏览器:用于浏览和展示图形数据的浏览器,包括缩放、旋转等功能。
-
图形控制器:用于控制图形数据的控制器,包括播放、暂停等功能。
-
图形分析器:用于分析图形数据的分析器,包括数据统计、数据挖掘等功能。
-
图形可视化:用于可视化图形数据的可视化工具,包括图表、图形等。
最佳实践:
-
使用颜色和图形:使用颜色和图形来突出重要图形数据和趋势。
-
提供交互性:提供交互性,用户能够通过点击、滑动等方式探索图形数据。
-
保持一致性:保持一致的风格和设计原则,提高用户体验。
-
实时更新:实时更新图形数据,反映最新的图形数据变化。
-
考虑可访问性:考虑不同用户群体的需求,包括残障用户。
5-10 直接操纵
直接操纵(Direct Manipulation):通过直接接触物理对象,来操作和控制数字内容的技术。
设计原则和最佳实践(高效、易用和直观的直接操纵界面):
-
直观性:用户能够快速理解和操作物理对象。
-
灵活性:能够适应不同的用户需求和屏幕大小。
-
可访问性:满足不同用户群体的需求,包括残障用户。
-
实时反馈:提供实时反馈,告知用户操作结果和状态。
-
多任务性:能够同时处理多个任务,提高用户的工作效率。
一些常见的直接操纵设计模式包括:
-
物理对象:使用物理对象来操作数字内容,如拖放、旋转、缩放等。
-
触摸屏:使用触摸屏来操作数字内容,如多点触控、滑动、旋转等。
-
手部识别:使用手部识别技术来操作数字内容,如手势识别、手部动作识别等。
-
VR/AR:使用VR/AR技术来操作数字内容,如虚拟手部、虚拟环境等。
最佳实践:
-
使用清晰的标签:使用清晰的标签,说明物理对象的用途和要求。
-
提供实时反馈:提供实时反馈,告知用户操作结果和状态。
-
考虑可访问性:满足不同用户群体的需求,包括残障用户。
-
灵活性:灵活,能够适应不同的用户需求和屏幕大小。
-
多任务性:能够同时处理多个任务,提高用户的工作效率。
5-11 帮助和出错界面设计
帮助和出错界面设计:设计用于提供帮助和处理错误的界面,包括帮助文档、错误消息、提示等。
原则和最佳实践:
-
清晰易读:清晰易读,避免使用复杂的语言和技术术语。
-
直观性:直观,用户能够快速理解和解决问题。
-
可访问性:满足不同用户群体的需求,包括残障用户。
-
实时反馈:提供实时反馈,告知用户问题解决状态。
-
多任务性:能够同时处理多个任务,提高用户的工作效率。
常见的帮助和出错界面设计模式包括:
-
帮助文档:提供帮助文档,包括用户手册、FAQ等。
-
错误消息:提供错误消息,包括错误代码、错误描述等。
-
提示:提供提示,包括工具提示、气泡提示等。
-
诊断工具:提供诊断工具,包括错误诊断、性能诊断等。
-
反馈机制:提供反馈机制,包括用户反馈、错误报告等。
6-1 结构化程序设计
结构化程序设计(Structured Programming)是一种编程方法论,它强调程序的逻辑结构和可读性。
它的核心思想是将程序分解为更小的、更可管理的模块,并使用流程图、顺序图和数据流图等工具来描述程序的控制流程和数据流动。
结构化程序设计的目标是提高程序的可靠性、可维护性和可扩展性。
它通过使用结构化编程语言(如C、C++、Java等)和结构化编程技术(如循环、条件语句、函数等)来实现。
6-2 结构化程序设计的原则
结构化程序设计是一种软件设计方法,注重软件的模块化与层次结构,其原则如下:
-
模块化:把软件拆分成独立模块,各模块承担特定功能。
-
层次结构:将软件按层次组织,各层次负责相应功能。
-
信息隐藏:把实现细节藏于模块内,对外仅提供必要接口。
-
封装:把数据和操作封装成独立模块。
-
抽象:将复杂细节抽象为简单接口,让用户关注接口就行。
-
重用:尽量复用已有模块和代码。
-
简洁性:用简洁语言和结构表达软件逻辑。
-
可读性:通过易懂的命名与结构提升代码可读性。
-
可维护性:借助模块化和层次结构增强软件可维护性。
-
可扩展性:依靠模块化和层次结构提高软件可扩展性。
总之,这些原则是软件设计的核心指导,因强调模块化和层次结构,使软件更易理解、维护与扩展。
6-3 结构化程序设计的风格
结构化程序设计的风格是自顶向下(Top-Down)和模块化(Modular)的设计风格。
自顶向下设计风格是指从软件的总体功能和需求开始,逐步分解为更小的模块和子模块,直到实现具体的功能。
模块化设计风格是指将软件分解为独立的模块,每个模块负责特定的功能,并且可以独立地开发、测试和维护。
结构化程序设计的风格还包括逐步细化(Stepwise Refinement)的设计风格,即通过逐步细化和分解软件的功能和结构来实现软件的设计。
6-4 数据说明
数据说明
在结构化程序设计里,数据说明主要涉及对程序中所使用的数据进行合理的定义与组织,其目的在于提升程序的可读性、可维护性,避免出现数据使用方面的错误。具体包含以下要点:
-
数据说明的次序应规范化:按照一定的顺序进行数据说明,例如先说明全局变量,再说明局部变量,或者按照数据类型(如先整型、后浮点型等)依次说明,使代码结构清晰,便于程序员查找和理解数据定义。
-
变量名的选择要有实际意义:使用能够反映变量用途和含义的名称,如用 studentName 表示学生姓名,totalScore 表示总成绩,这样可提高代码的可读性,让其他开发者更容易理解代码的功能。
-
数据说明时要添加必要的注释:对复杂的数据结构、特殊用途的变量等添加注释,解释其含义、取值范围、使用方法等,帮助后续维护人员理解代码。
6-5 语句说明
语句说明
语句说明强调的是程序中语句的编写规范与质量,良好的语句编写有助于提高程序的清晰度和可维护性。具体内容如下:
-
语句要简单直接:避免使用过于复杂、嵌套过深的语句,让代码易于理解。例如,尽量减少多层嵌套的条件语句和循环语句,可将复杂逻辑拆分成多个简单的语句实现。
-
避免使用难懂的技巧性语句:不要为了追求代码的简洁而使用一些晦涩难懂的编程技巧,保持代码的直观性。比如,避免使用过于复杂的三元运算符嵌套,使代码逻辑一目了然。
-
利用括号来明确表达式的运算顺序:在复杂的表达式中,合理使用括号可以避免因运算符优先级问题导致的错误,同时也能增强代码的可读性。例如 (a + b) * c 比 a + b * c 更清晰地表达了运算顺序。
6-6 输入-输出
输入 - 输出
输入 - 输出(I/O)操作是程序与外界交互的重要方式,在结构化程序设计中需要关注以下方面:
-
输入格式要清晰明确:为用户提供清晰的输入提示信息,告知用户需要输入的数据类型、格式和范围等。例如,在要求用户输入日期时,提示 “请输入日期,格式为 YYYY - MM - DD”。
-
对输入数据进行有效性检查:在程序接收用户输入后,要检查输入数据是否合法,避免因非法输入导致程序出错。比如,检查用户输入的年龄是否在合理范围内(通常为 0 - 150 岁)。
-
输出信息要具有可读性:输出的结果要清晰、易懂,符合用户的认知习惯。可以添加必要的文字说明,使输出信息更有意义。例如,在输出学生成绩时,不仅显示成绩数值,还显示 “该学生的数学成绩为:[成绩值]”。
6-7 效率
效率
效率主要涉及程序的时间效率和空间效率,在结构化程序设计中需要在保证程序正确性和可读性的前提下,尽可能提高效率。
-
时间效率:优化算法设计,选择时间复杂度较低的算法来解决问题。例如,在排序问题中,使用快速排序算法(平均时间复杂度为 $O(n log n)$)比冒泡排序算法(时间复杂度为 $O(n^2)$)效率更高。
-
空间效率:合理使用内存资源,避免不必要的内存开销。例如,及时释放不再使用的变量和对象所占用的内存空间,避免内存泄漏。
6-8 影响输入-输出的因素
影响输入 - 输出的因素
在程序设计中,有多个因素会对输入 - 输出操作产生影响,具体如下:
-
数据量大小:输入或输出的数据量越大,操作所需的时间就越长,可能还会受到系统内存和磁盘空间的限制。例如,处理一个大型文件的输入输出时,可能需要考虑分块处理,以避免内存溢出。
-
I/O 设备性能:不同的 I/O 设备(如键盘、鼠标、磁盘、网络等)具有不同的读写速度和性能。例如,机械硬盘的读写速度相对较慢,而固态硬盘的读写速度较快,这会影响数据的输入输出效率。
-
数据传输速率:在进行网络输入输出时,网络带宽和传输速率会影响数据的传输时间。例如,在低带宽网络环境下,下载大文件会花费较长时间。
-
操作系统的调度:操作系统对 I/O 操作的调度策略也会影响其性能。例如,当系统资源紧张时,操作系统可能会优先处理某些重要的 I/O 请求,而延迟其他请求的处理。
6-9 程序复杂性度量
程序复杂性度量包括:
-
Halstead复杂性度量
-
Cyclomatic复杂性度量
-
McCabe复杂性度量
-
程序长度
-
程序复杂度
-
程序难度
-
程序错误
-
程序可维护性
-
程序可读性
这些度量方法可以帮助开发人员和项目管理人员了解程序的复杂度和难度。
6-10 Mccbabe方法
McCabe 麦卡比方法是一种软件复杂性度量方法,由Thomas J. McCabe Jr.于1976年提出。该方法用于度量软件的复杂性,特别是控制流复杂性。
McCabe方法使用以下公式计算复杂性度量:
V(G) = e - n + 2p
其中:
-
V(G) 是控制流复杂性度量
-
e 是程序中的边数(即控制流的数量)
-
n 是程序中的节点数(即语句或模块的数量)
-
p 是程序中的连接点数(即程序中的入口和出口点)
McCabe方法将复杂性度量分为以下几个级别:
-
低复杂性:V(G) ≤ 10
-
中等复杂性:10 < V(G) ≤ 20
-
高复杂性:20 < V(G) ≤ 30
-
极高复杂性:V(G) > 30
McCabe方法的优点是:
-
简单易懂
-
快速计算
-
能够度量控制流复杂性
McCabe方法的缺点是:
-
只能度量控制流复杂性,不考虑数据流复杂性
-
不适合于大型软件系统
-
不考虑软件的模块化和层次结构
总的来说,McCabe方法是一种简单易用的软件复杂性度量方法,但其局限性较大,不适合于所有类型的软件系统。
6-11 Halstead方法
Halstead 哈尔斯泰德方法:是一种软件复杂性度量方法,由Maurice Halstead于1977年提出。
该方法使用以下四个指标来度量软件的复杂性:
-
程序长度(N):程序中的总代码行数。
-
程序体积(V):程序的体积,使用以下公式计算:V = N * log2(n),其中n是程序中的操作符和操作数的总数。
-
程序难度(D):程序的难度,使用以下公式计算:D = (n1/2) * (N2/n2),其中n1是程序中的操作符数,n2是程序中的操作数数。
-
程序智能度(E):程序的智能度,使用以下公式计算:E = V/D。
Halstead方法将复杂性度量分为以下几个级别:
-
低复杂性:E ≤ 10
-
中等复杂性:10 < E ≤ 20
-
高复杂性:20 < E ≤ 30
-
极高复杂性:E > 30
Halstead方法的优点是:
-
能够度量软件的复杂性和难度
-
能够评估软件的智能度
-
能够比较不同软件的复杂性
Halstead方法的缺点是:
-
只能度量软件的静态复杂性,不考虑动态复杂性
-
不考虑软件的模块化和层次结构
-
计算复杂,需要大量的数据
总的来说,Halstead方法是一种较为复杂的软件复杂性度量方法,能够提供较为详细的复杂性评估结果。但是,其计算复杂,需要大量的数据,且不考虑软件的动态复杂性。
7-1 软件测试的目地和原则
软件测试的目的
-
确保软件质量:主要确保软件在功能、性能、安全性、可靠性等方面的质量。
-
发现和修复缺陷:找出并修复软件里的错误、bug、漏洞等缺陷。
-
评估软件可靠性:对软件的稳定性、可维护性等可靠性方面进行评估。
-
提供软件可信度:从软件的安全性、可靠性等方面来提供可信度。
软件测试的原则
-
测试应独立于开发:测试人员要独立于开发人员。
-
测试应全面:涵盖功能测试、性能测试、安全性测试等。
-
测试应重复:包含回归测试、重复测试等。
-
测试应自动化:借助自动化测试工具、自动化测试脚本等实现。
-
测试应持续:涉及持续测试、持续集成等。
-
测试应基于风险:进行风险评估、确定风险优先级等。
-
测试应基于需求:包含需求分析、需求测试等。
总之,软件测试的目的和原则:保障软件的质量、可靠性与可信度。
7-2 软件测试的过程和策略
软件测试的过程和策略,是其核心部分。
软件测试的过程
-
测试计划:第一步,涵盖测试目标、范围、策略等。
-
测试用例设计:第二步,包含测试用例的设计与开发。
-
测试环境搭建:第三步,涉及测试环境搭建与配置。
-
测试执行:第四步,包括执行测试用例及记录结果。
-
测试结果分析:第五步,进行结果分析与缺陷报告。
-
缺陷报告和跟踪:第六步,负责缺陷报告与跟踪。
-
测试总结和评估:第七步,开展测试总结与评估。
软件测试的策略
-
黑盒测试:测试人员不知软件内部实现细节的策略。
-
白盒测试:测试人员知晓软件内部实现细节的策略。
-
灰盒测试:测试人员部分了解软件内部实现细节的策略。
-
基于风险的测试:按软件风险级别确定测试优先级的策略。
-
基于需求的测试:依软件需求确定测试内容的策略。
-
基于场景的测试:根据软件使用场景确定测试内容的策略。
-
自动化测试:借助自动化工具执行测试的策略。
总之,软件测试的过程和策略保障软件的质量与可靠性。
7-3 软件测试的方法
软件测试的方法如下:
-
黑盒测试:测试人员仅知晓软件输入和输出,不知内部实现细节。
-
白盒测试:测试人员了解内部实现细节,测试其内部逻辑与结构。
-
灰盒测试:测试人员对内部实现细节不完全了解。
-
等价类划分法:按输入数据等价类划分测试用例。
-
边界值分析法:测试软件边界值,如最值、正常值等。
-
状态转换测试法:测试软件的状态转换情况。
-
用例测试法:测试软件正常与异常用例。
-
场景测试法:测试软件正常与异常场景。
-
自动化测试法:借助自动化工具执行测试。
-
手工测试法:由测试人员手工开展测试。
这些测试方法可以根据软件的特点和需求来选择和组合使用。
黑盒测试方法:
黑盒测试方法包括:
-
等价类划分法
-
边界值分析法
-
状态转换测试法
-
用例测试法
-
场景测试法
白盒测试方法:
白盒测试方法包括:
-
语句覆盖法
-
判定覆盖法
-
条件覆盖法
-
路径覆盖法
灰盒测试方法:
灰盒测试方法包括:
-
等价类划分法
-
边界值分析法
-
状态转换测试法
-
用例测试法
-
场景测试法
这些测试方法可以根据软件的特点和需求来选择和组合使用。
7-4 白盒测试(逻辑覆盖)
白盒测试(White Box Testing)也称为逻辑覆盖测试(Logic Coverage Testing),
通过检查软件内部的逻辑结构和代码实现来发现软件中的错误和缺陷。
白盒测试的主要目的包括:
-
确保软件的逻辑正确性:确保软件内部的逻辑结构和代码实现是正确的。
-
发现软件中的错误和缺陷:发现软件中的错误和缺陷,特别是那些难以通过黑盒测试发现的错误。
-
提高软件的可靠性和可维护性:通过检查软件内部的逻辑结构和代码实现来提高软件的可靠性和可维护性。
白盒测试的方法包括:
-
语句覆盖:每个语句至少被执行一次。
-
分支覆盖:每个分支至少被执行一次。
-
条件覆盖:每个条件至少被执行一次。
-
路径覆盖:每个路径至少被执行一次。
-
循环覆盖:每个循环至少被执行一次。
白盒测试的工具包括:
-
代码分析工具:例如SonarQube、CodeCoverage等。
-
测试框架:例如JUnit、TestNG等。
-
测试驱动开发工具:例如Cucumber、SpecFlow等。
白盒测试的优势包括:
-
能够发现软件中的错误和缺陷:能够发现软件中的错误和缺陷,特别是那些难以通过黑盒测试发现的错误。
-
能够提高软件的可靠性和可维护性:通过检查软件内部的逻辑结构和代码实现来提高软件的可靠性和可维护性。
-
能够减少软件的维护成本:通过发现和修复软件中的错误和缺陷来减少软件的维护成本。
白盒测试的缺点包括:
-
需要大量的时间和资源:需要大量的时间和资源来检查软件内部的逻辑结构和代码实现。
-
需要高水平的技术能力:需要高水平的技术能力来检查软件内部的逻辑结构和代码实现。
-
可能无法发现所有的错误和缺陷:可能无法发现所有的错误和缺陷,特别是那些复杂的错误和缺陷。
7-5 黑盒测试(等价类划分)
黑盒测试(Black Box Testing)也称为等价类划分测试(Equivalence Class Partitioning),通过检查软件的输入和输出,来发现软件中的错误和缺陷。
黑盒测试的主要目的包括:
-
确保软件的功能正确性:确保软件的功能是正确的。
-
发现软件中的错误和缺陷:发现软件中的错误和缺陷。
-
提高软件的可靠性和可维护性:通过检查软件的输入和输出,来提高软件的可靠性和可维护性。
黑盒测试的方法包括:
-
等价类划分:将软件的输入数据划分为等价类。
-
边界值分析:检查软件的输入数据的边界值。
-
状态转换测试:检查软件的状态转换。
-
错误猜测:根据软件的历史数据和错误报告,来猜测软件中的错误。
黑盒测试的步骤包括:
-
确定软件的输入数据:确定软件的输入数据。
-
划分等价类:将软件的输入数据划分为等价类。
-
选择测试用例:选择测试用例。
-
执行测试:执行测试。
-
检查结果:检查结果。
黑盒测试的工具包括:
-
测试框架:例如JUnit、TestNG等。
-
测试驱动开发工具:例如Cucumber、SpecFlow等。
-
自动化测试工具:例如Selenium、Appium等。
黑盒测试的优势包括:
-
能够发现软件中的错误和缺陷:黑盒测试能够发现软件中的错误和缺陷。
-
能够提高软件的可靠性和可维护性:通过检查软件的输入和输出来提高软件的可靠性和可维护性。
-
能够减少软件的维护成本:通过发现和修复软件中的错误和缺陷来减少软件的维护成本。
黑盒测试的缺点包括:
-
可能无法发现所有的错误和缺陷:黑盒测试可能无法发现所有的错误和缺陷。
-
需要大量的时间和资源:黑盒测试需要大量的时间和资源来检查软件的输入和输出。
-
需要高水平的技术能力:黑盒测试需要高水平的技术能力来检查软件的输入和输出。
7-6 边界值分析和错误推测
边界值分析(Boundary Value Analysis)和错误推测(Error Guessing)是两种常用的软件测试技术。
边界值分析
边界值分析是一种测试技术,用于测试软件系统的边界值。
边界值是指软件系统的输入数据或输出数据的边界值,例如最小值、最大值、空值等。
边界值分析的步骤包括:
-
确定边界值:确定软件系统的边界值。
-
选择测试用例:选择测试用例,包括边界值和非边界值。
-
执行测试:执行测试,检查软件系统的行为。
-
检查结果:检查结果,确保软件系统的行为是正确的。
边界值分析的优点包括:
-
能够发现边界值错误:边界值分析能够发现软件系统的边界值错误。
-
能够提高软件系统的可靠性:通过测试边界值,能够提高软件系统的可靠性。
边界值分析的缺点包括:
-
需要大量的时间和资源:边界值分析需要大量的时间和资源来测试软件系统的边界值。
-
可能无法发现所有的错误:边界值分析可能无法发现所有的错误。
错误推测
错误推测是一种测试技术,用于测试软件系统的错误处理能力。
错误推测是指,根据软件系统的历史数据和错误报告,来推测软件系统可能出现的错误。
错误推测的步骤包括:
-
收集历史数据:收集软件系统的历史数据,包括错误报告和日志文件。
-
分析历史数据:分析历史数据,确定软件系统可能出现的错误。
-
选择测试用例:选择测试用例,包括错误场景和正常场景。
-
执行测试:执行测试,检查软件系统的错误处理能力。
-
检查结果:检查结果,确保软件系统的错误处理能力是正确的。
错误推测的优点包括:
-
能够发现错误:错误推测能够发现软件系统的错误。
-
能够提高软件系统的可靠性:通过测试错误处理能力,能够提高软件系统的可靠性。
错误推测的缺点包括:
-
需要大量的时间和资源:错误推测需要大量的时间和资源来收集和分析历史数据。
-
可能无法发现所有的错误:错误推测可能无法发现所有的错误。
7-7 因果图
在软件测试中,因果图(Cause-and-Effect Graph)是一种用于测试设计的工具。
它用于描述软件系统的输入和输出之间的关系,以及输入的变化对输出的影响。
因果图是一种图形化的工具,用于描述软件系统的输入和输出之间的关系。它由以下几个部分组成:
-
输入:输入是指软件系统的输入数据或事件。
-
输出:输出是指软件系统的输出数据或事件。
-
因果关系:因果关系是指输入和输出之间的关系,描述了输入的变化对输出的影响。
因果图在软件测试中有以下几个作用:
-
测试设计:帮助测试人员设计测试用例,确保测试覆盖了软件系统的所有输入和输出。
-
测试优先级:帮助测试人员确定测试的优先级,确保最重要的测试用例被优先执行。
-
测试覆盖率:帮助测试人员评估测试覆盖率,确保测试覆盖了软件系统的所有输入和输出。
因果图的例子
例如,一个软件系统有两个输入:用户名和密码。输出是登录成功或失败。因果图可以如下所示:
-
输入:用户名、密码
-
输出:登录成功、登录失败
-
因果关系:
-
用户名正确,密码正确 -> 登录成功
-
用户名错误,密码正确 -> 登录失败
-
用户名正确,密码错误 -> 登录失败
-
用户名错误,密码错误 -> 登录失败
-
通过因果图,我们可以设计测试用例,确保测试覆盖了所有的输入和输出。
7-9 单元测试
定义:单元测试是一种测试方法,用于测试软件系统的最小单元,即函数或方法。单元测试的目的是确保软件系统的每个单元功能正确,且不会引入新的错误。
单元测试特点:
-
测试最小单元:单元测试测试软件系统的最小单元,即函数或方法。
-
独立测试:单元测试独立于其他测试,测试每个单元的功能。
-
快速执行:单元测试执行速度快,通常在几秒钟内完成。
-
自动化:单元测试通常使用自动化测试工具来执行。
单元测试有以下几个好处:
-
确保软件质量:单元测试确保软件系统的每个单元功能正确。
-
减少错误:单元测试减少了软件系统中的错误。
-
提高开发效率:单元测试提高了开发效率,开发人员可以快速发现和修复错误。
-
降低维护成本:单元测试降低了维护成本,软件系统更容易维护。
单元测试有以下几个工具:
-
JUnit:JUnit是一种流行的单元测试框架,用于Java语言。
-
TestNG:TestNG是一种流行的单元测试框架,用于Java语言。
-
PyUnit:PyUnit是一种流行的单元测试框架,用于Python语言。
-
NUnit:NUnit是一种流行的单元测试框架,用于.NET语言。
单元测试的步骤如下:
-
编写测试代码:编写测试代码,用于测试软件系统的每个单元。
-
执行测试:执行测试,测试软件系统的每个单元。
-
检查结果:检查测试结果,确保软件系统的每个单元功能正确。
-
维护测试代码:维护测试代码,确保测试代码随着软件系统的变化而变化。
7-10 集成测试
集成测试的定义:集成测试是一种软件测试方法,用于测试软件系统的多个单元或模块之间的集成。
集成测试的目的:确保软件系统的各个部分能够正确地协同工作。
集成测试有以下几个特点:
-
测试集成:集成测试测试软件系统的多个单元或模块之间的集成。
-
测试接口:集成测试测试软件系统的各个部分之间的接口。
-
测试数据流:集成测试测试软件系统的数据流。
-
测试功能:集成测试测试软件系统的功能。
集成测试有以下几个好处:
-
确保集成正确:集成测试确保软件系统的各个部分能够正确地协同工作。
-
减少错误:集成测试减少了软件系统中的错误。
-
提高软件质量:集成测试提高了软件系统的质量。
-
降低维护成本:集成测试降低了维护成本。
集成测试有以下几个方法:
-
大爆炸集成:大爆炸集成是一种集成测试方法,所有的模块都一次性地集成在一起。
-
自顶向下集成:自顶向下集成是一种集成测试方法,从软件系统的顶层开始,逐步向下集成各个模块。
-
自底向上集成:自底向上集成是一种集成测试方法,从软件系统的底层开始,逐步向上集成各个模块。
-
混合集成:混合集成是一种集成测试方法,结合了大爆炸集成、自顶向下集成和自底向上集成的方法。
7-11 确认测试
确认测试(Confirmation Testing)是软件测试方法,目的是确认软件系统功能和性能是否符合预期,确保其能正确执行预期功能与任务。
特点
-
测试功能:对软件系统功能进行测试。
-
测试性能:测试软件系统性能。
-
测试兼容性:测试软件系统兼容性。
-
测试用户界面:测试软件系统用户界面。
好处
-
确保软件质量。
-
减少错误。
-
提高用户满意度。
-
降低维护成本。
方法
-
功能测试:用于测试软件系统功能。
-
性能测试:用于测试软件系统性能。
-
兼容性测试:用于测试软件系统兼容性。
-
用户界面测试:用于测试软件系统用户界面。
步骤
-
确定测试范围:涵盖功能、性能、兼容性及用户界面等方面。
-
设计测试用例:用于测试上述相关内容。
-
执行测试:用测试用例测试相应方面。
-
检查结果:确保各方面符合预期。
7-12 测试种类
软件工程中测试种类如下:
-
单元测试:针对软件最小单元,如函数、方法。
-
集成测试:考查软件多个单元间的集成情况。
-
系统测试:对软件整个系统进行测试。
-
验收测试:验证软件是否满足用户需求与期望。
-
回归测试:查看软件修改或更新有无引入新错误。
-
性能测试:检测软件性能,像速度、吞吐量等。
-
安全测试:检查软件安全性,如有无漏洞。
-
兼容性测试:确认软件能否在不同环境运行。
-
用户界面测试:考查软件用户界面是否友好、易用。
-
自动化测试:借助自动化工具测试软件。
-
手动测试:依靠人工进行测试。
-
黑盒测试:聚焦软件外部行为,不考虑内部实现。
-
白盒测试:测试软件内部实现与结构。
-
灰盒测试:兼顾软件内部实现和外部行为。
-
探索性测试:检测软件未知或未文档化功能。
-
负载测试:测试软件高负载下的性能。
-
压力测试:测试软件极限条件下的性能。
-
恢复测试:检验软件故障或出错后能否恢复正常。
-
配置测试:考查软件在不同配置下的表现。
-
本地化测试:测试软件在不同语言、文化环境下的表现。
7-13 编写测试计划
测试计划是软件测试的重要文档,涵盖测试范围、策略、方法及资源等内容。编写测试计划步骤如下:
-
确定测试目标:明确测试目的,如保障软件功能、性能、安全性等方面达标。
-
定义测试范围:确定需测试的功能、模块或组件。
-
选择测试策略:如黑盒、白盒、灰盒测试等策略中进行选择。
-
确定测试方法:选定手动或自动化等测试方法。
-
定义测试用例:涵盖测试输入、预期结果及测试步骤。
-
确定测试资源:明确测试人员、环境、工具等资源。
-
制定测试计划:依上述信息安排测试时间表、分配测试任务等。
-
审查和更新:对测试计划进行审查并适时更新,保证其准确、有效。
测试计划的内容通常包括:
-
测试目标和范围
-
测试策略和方法
-
测试用例和测试数据
-
测试环境和测试工具
-
测试时间表和任务分配
-
测试风险和假设
-
测试标准和准则
下面是1个案例
|
|
8-1 软件维护的概念
软件维护——运维人员的工作
定义
对软件系统进行维护和更新,确保其继续运行并满足用户需求,涵盖各组成部分(源代码、文档、测试用例)。
目的
确保软件系统可靠、可维护,降低风险,提升性能,使其正确工作、便于更新、抵御错误故障等。
类型
纠错、改进、适应、预防维护
分别对应修复错误缺陷、改进功能性能、适应新环境、预防错误缺陷。
过程
包含问题报告、分析、解决、测试及部署相关问题解决方案。
工具
版本控制系统(如Git、Subversion等)
缺陷跟踪系统(如JIRA、Bugzilla等)
测试工具(如JUnit、TestNG等)
代码分析工具(如SonarQube、CodeCoverage等)
最佳实践
定期维护,且运用版本控制系统、缺陷跟踪系统、测试工具、代码分析工具分别管理版本、跟踪问题、测试方案、分析代码。
8-2 软件维护的活动
软件维护活动
包含任务
包含问题报告、分析、解决,测试、部署,还有代码、文档、测试用例更新,以及配置管理、备份和恢复等操作。
活动类型
-
纠错活动:修复软件系统错误与缺陷。
-
改进活动:改进软件系统功能和性能。
-
适应活动:让软件适应新环境。
-
预防活动:预防软件系统错误与缺陷。
活动流程
涵盖问题报告、分析、解决、测试、部署、代码更新、文档更新、测试用例更新、配置管理、备份和恢复各环节。
活动工具
-
版本控制系统:如Git、Subversion等。
-
缺陷跟踪系统:如JIRA、Bugzilla等。
-
测试工具:如JUnit、TestNG等。
-
代码分析工具:如SonarQube、CodeCoverage等。
-
配置管理工具:如Apache Ant、Apache Maven等。
-
备份和恢复工具:如Backup Exec、Veritas NetBackup等。
8-3 软件维护的副作用
软件维护:对现有软件系统进行修复、优化、升级和改进,以契合新需求或环境。
副作用
维护成本增加
需额外人力、资源,像维护人员、工具及环境,复杂软件系统尤易致成本上升。
风险增加
可能引入新问题与风险,如破坏现有功能、产生新错误或增加安全风险,复杂软件系统更易出现。
兼容性问题
或许带来兼容性问题,像与旧版或新版软件不兼容,复杂软件系统此类情况更易增多。
维护周期延长
可能致使软件生命周期延长,比如软件版本升级或功能改进,复杂软件系统的这种延长情况更易发生。
说明
这些副作用并非必然,实际取决于软件系统复杂性、维护频率及维护质量。
8-4 软件可维护性及度量
软件可维护性
指软件系统在维护时能被轻松修改、更新和修复的程度。
涵盖方面
-
可理解性:关乎软件代码和文档是否易理解。
-
可修改性:看软件代码是否易修改与更新。
-
可测试性:考量软件是否易测试和验证。
-
可靠性:判断软件能否正常运行并提供预期功能。
-
可扩展性:确定软件能否轻松添加新功能和模块。
度量指标
-
圈复杂度:衡量软件代码复杂度。
-
哈尔斯塔德度量:衡量软件代码复杂度、长度和难度。
-
维护难度指数:衡量软件维护难度。
-
可维护性指数:衡量软件可维护性综合指标。
-
代码覆盖率:衡量软件测试覆盖率。
-
缺陷密度:衡量软件缺陷密度。
-
平均修复时间:衡量软件缺陷修复时间。
作用
帮助开发与维护人员评估软件可维护性,以便采取相应措施提升其可维护性。
8-5 提高可维护性方法
提高软件可维护性的方法有:
-
进行模块化设计,将软件分解为独立小模块;
-
重用现有代码,减少重复和复杂度;
-
遵循代码规范提升可读性;
-
提供详细注释与文档辅助理解;
-
采用测试驱动开发、持续集成和部署、自动化测试保证代码正确可靠;
-
定期代码审查确保质量;
-
定期重构消除技术债务;
-
运用设计模式和原则,提高可维护性与可扩展性
这些方法利于提升软件可维护性,降低成本并提高软件质量。
8-6 软件复用和再生工程
软件复用:通过重用现有软件组件、模块或代码,以代码、组件、设计复用等方式,减少开发时间和成本,还能提高软件质量与可靠性、降低维护更新难度。
再生工程:对现有软件系统分析、设计与实现,借助软件重构、重写、迁移等方式,提高软件质量与可靠性、降低维护更新难度、增强软件适应性与灵活性。
两者关系:相互关联,软件复用可借再生工程实现,再生工程能靠软件复用提升效率,都意在提高开发效率、降低成本、改善软件质量。
9-1 面向对象的基本概念
软件工程中,面向对象的基本概念包括:
-
类(Class):类是软件工程中面向对象程序设计的基本单位,它定义了对象的属性和行为。
-
对象(Object):对象是类的实例,它具有类定义的属性和行为。
-
继承(Inheritance):一个类可以继承另一个类的属性和行为,使得子类可以拥有父类的所有特性,并可以添加新的特性或覆盖父类的特性。
-
多态(Polymorphism):一个对象可以以多种形式存在,例如,一个对象可以是多个类的实例,或者一个方法可以被多种类型的对象调用。
-
封装(Encapsulation):将一个对象的属性和行为封装在一起,使得外部无法直接访问对象的内部细节,只能通过对象提供的接口,来访问和操作对象。
-
抽象(Abstraction):将复杂的系统或过程,简化为一个简单的模型或接口,使得用户可以忽略系统的内部细节,只需要关注系统的外部行为和接口。
-
接口(Interface):一个类或对象提供的公共方法或服务,使得其他类或对象可以通过接口来访问和操作该类或对象。
-
组合(Composition):一个类或对象可以包含其他类或对象,使得它们可以共同工作来实现某个功能或服务。
9-2 面向对象的开发过程
面向对象开发过程
阶段
需求分析:收集、分析用户需求,明确软件功能与性能要求。
系统设计:依据需求分析,设计软件总体与体系架构,涵盖类、对象、接口及关系等。
类设计:确定类的属性、方法与行为,考虑继承、多态与封装。
对象设计:规划对象状态与行为,包括创建、销毁及交互。
接口设计:设计类或对象接口,涉及方法、参数与返回值。
代码实现:按设计编写代码实现类、对象与接口。
测试:检测软件功能、性能与安全性,开展单元、集成及系统测试。
维护:对软件进行维护,如修复 bug、新增功能、优化性能。
步骤
创建用例图:描述软件功能与用户需求。
创建类图:展现软件的类、对象及关系。
创建对象图:刻画软件对象与状态。
创建序列图:描绘软件交互与行为。
创建状态图:阐述软件状态与转换。
9-3 面向对象的开发方法
面向对象开发方法包括:
-
面向对象分析和设计(OOAD):系统分析设计软件结构与行为。
-
统一建模语言(UML):标准描述软件结构与行为。
-
面向对象编程(OOP):实现软件结构与行为。
-
设计模式:预定义解决软件设计常见问题。
-
面向对象测试:测试软件结构与行为。
-
面向对象重构:改进软件结构与行为。
-
敏捷开发:强调快速迭代与持续交付。
-
极限编程(XP):强调测试驱动开发与持续集成。
-
Scrum:强调团队合作与迭代开发。
-
面向对象的软件工程:强调面向对象原则方法。
9-4 面向对象的分析(OOA)
面向对象分析(OOA)是分析软件系统需求和功能的方法
主要目的是确定软件结构和行为,如类、对象、属性和方法等。
面向对象分析 OOA 步骤:
-
需求收集:了解用户需求和期望。
-
需求分析:明确软件功能和性能要求。
-
创建用例图:展示软件功能及与用户的交互。
-
创建类图:描绘软件的类、对象及关系。
-
创建对象图:呈现软件对象和状态。
-
创建序列图:描述软件交互和行为。
-
创建状态图:阐述软件状态及转换。
面向对象分析 OOA 目标:
-
确定类和对象。
-
明确类的属性和状态。
-
界定类的方法和行为。
-
梳理类之间的关系和交互。
面向对象分析 OOA 好处:
-
提升软件质量,满足用户需求。
-
增强可维护性,便于维护和更新。
-
提高可扩展性,利于扩展和修改。
9-5 面向对象的设计(OOD)
面向对象的设计(OOD)是设计软件系统结构和行为的方法,目的是确定满足用户需求和功能要求的类、对象、属性、方法等。
-
步骤
-
类设计:明确类的属性、方法和行为。
-
对象设计:确定对象状态和行为。
-
关系设计:规划类间关系与交互。
-
接口设计:设计类和对象间接口。
-
系统设计:构建软件总体结构和体系架构。
-
-
目标
-
类:确定软件中的类和对象。
-
属性:明确类的属性和状态。
-
方法:界定类的方法和行为。
-
关系:梳理类间关系与交互。
-
接口:确定类和对象间接口。
-
-
原则
-
单一职责:一个类只负责一项职责。
-
开放封闭:类对扩展开放、对修改封闭。
-
里氏替换:子类能替换父类。
-
接口隔离:类不依赖不需要的接口。
-
依赖倒置:类依赖抽象而非具体实现。
-
-
好处
-
质量提升:设计软件结构和行为,满足用户需求。
-
可维护性增强:便于软件维护和更新。
-
可扩展性提高:利于软件扩展和修改。
-
9-6 面向对象的测试(OOT)
面向对象的测试(OOT)是测试软件系统结构和行为的方法,主要目的是确保软件满足用户需求与功能要求。
-
步骤
-
单元测试:测单个类或方法。
-
集成测试:测多个类或方法间交互。
-
系统测试:测软件总体结构和行为。
-
验收测试:测软件是否满足用户需求和功能要求。
-
-
目标:确保软件结构和行为正确,包括类的属性与方法、对象的状态与行为、类间关系与交互、类和对象间接口正确。
-
技术
-
白盒测试:测软件内部结构和行为。
-
黑盒测试:测软件外部行为和功能。
-
灰盒测试:测软件内部结构和外部行为。
-
-
工具
-
JUnit:Java 单元测试框架。
-
TestNG:Java 测试框架。
-
PyUnit:Python 单元测试框架。
-
-
好处
-
质量提升:确保软件满足用户需求。
-
可维护性增强:便于软件维护更新。
-
可扩展性提高:利于软件扩展修改。
-
9-7 ATM实例
ATM系统是一种自动化的银行服务设备,用于提供各种金融服务,如取款、存款、转账等。
一个ATM实例通常包括以下组件:
-
硬件:包括ATM机身、显示器、键盘、扫描器等。
-
软件:包括ATM操作系统、银行应用程序、安全软件等。
-
数据库:用于存储银行账户信息、交易记录等数据。
ATM实例的主要功能包括:
-
取款:允许用户输入卡号和密码,然后输入取款金额,并输入密码确认。
-
存款:允许用户输入卡号和密码,然后输入存款金额,并输入密码确认。
-
转账:允许用户输入卡号和密码,然后输入转账金额和目标账户信息,并输入密码确认。
-
查询余额:允许用户输入卡号和密码,然后显示账户余额。
-
语音交互:允许用户通过语音输入指令,执行取款、存款、转账等操作。
ATM实例的开发过程通常包括以下步骤:
-
需求分析:确定ATM系统的功能和性能要求。
-
设计:设计ATM系统的结构和行为。
-
实现:编写代码实现ATM系统的功能。
-
测试:测试ATM系统的功能和性能。
-
部署:将ATM系统部署到银行分支机构。
ATM实例的优点包括:
-
提高效率:通过自动化和智能化,减少人工劳动,提高服务效率。
-
提高安全性:通过安全机制,保护银行账户信息和交易安全。
-
提高可用性:通过自动化和智能化,提高ATM的可用性和可靠性。
10-1 软件质量的概念
软件质量指软件产品或服务的总体特性与属性
涵盖功能性、可靠性、效率、可维护性、可移植性、可用性、安全性等方面。
分类
-
功能性质量:软件能否正确执行预期功能。
-
可靠性质量:软件在各类环境条件下能否稳定运行。
-
效率质量:软件能否有效利用系统资源与时间。
-
可维护性质量:软件维护与更新的难易程度。
-
可移植性质量:软件能否在不同环境及平台运行。
-
可用性质量:软件是否易于使用和理解。
-
安全性质量:软件对用户数据与隐私的保护能力。
评估方法
-
功能性测试:检验软件执行预期功能的正确性。
-
性能测试:测试软件性能与效率。
-
安全性测试:检测软件安全性及对用户数据隐私的保护。
-
可用性测试:评估软件可用性与用户体验。
-
维护性测试:测试软件维护与更新的便捷性。
改进方法
-
需求管理:保证软件需求明确且一致。
-
设计评审:审查软件设计是否符合需求与标准。
-
代码评审:审核软件代码是否遵循标准与最佳实践。
-
测试和验证:确保软件符合需求与标准。
-
持续集成和交付:实现软件快速且高质量发布。
10-2 软件质量保证
软件质量保证概述
软件质量保证(Software Quality Assurance,SQA)是确保软件产品或服务符合用户需求和期望的过程,贯穿软件开发的需求分析、设计、编码、测试和维护各阶段。
软件质量保证的目标
-
满足用户需求:使软件契合用户需求与期望。
-
可靠性:保障软件正常运行,无故障、错误。
-
安全性:保护用户数据和隐私。
-
性能:实现软件高效运行,无性能问题。
-
可维护性:便于软件维护和更新。
软件质量保证的过程
-
需求分析:明确软件需求与期望。
-
设计:规划软件架构和功能。
-
编码:编写软件代码。
-
测试:检测软件产品或服务。
-
维护:对软件进行维护和更新。
软件质量保证的方法
-
测试:检验软件。
-
代码审查:审核软件代码。
-
设计审查:评审软件设计。
-
需求审查:核查软件需求。
-
配置管理:管理软件配置。
-
变更管理:管控软件变更。
-
缺陷管理:处理软件缺陷。
软件质量保证的工具
-
测试工具:如 JUnit、TestNG 。
-
代码审查工具:像 SonarQube、CodeCoverage 。
-
设计审查工具:例如 Lucidchart、Draw.io 。
-
需求审查工具:如 JIRA、Trello 。
-
配置管理工具:像 Git、SVN 。
-
变更管理工具:例如 JIRA、Trello 。
-
缺陷管理工具:如 JIRA、Bugzilla 。
软件质量保证的优势
-
提高软件质量:确保软件品质。
-
降低软件成本:减少开发和维护成本。
-
提高软件可靠性:保障软件稳定运行。
-
提高软件安全性:保护用户数据安全。
-
提高软件性能:实现软件高效运作。
-
提高软件可维护性:便于软件维护更新。
10-3 软件可靠性
软件可靠性概述
软件可靠性(Software Reliability)指软件产品或服务在正常使用条件下,按预期正常运行的能力。
它是软件质量关键部分,直接关联软件可用性、安全性与性能。
软件可靠性定义
-
正确性:正确执行预期功能。
-
完整性:完整执行预期功能。
-
一致性:一致执行预期功能。
-
可用性:需要时可正常使用。
-
可维护性:易于维护和更新。
软件可靠性影响因素
-
软件设计
-
软件编码
-
软件测试
-
软件维护
-
硬件环境
-
软件配置
软件可靠性评估方法
-
软件测试:评估可靠性的主要方式。
-
软件审查:评估软件设计和编码质量。
-
软件度量:评估软件质量。
-
故障树分析:评估软件故障。
-
可靠性模型:评估可靠性的数学模型。
软件可靠性提高方法
-
软件设计改进
-
软件编码改进
-
软件测试改进
-
软件维护改进
-
硬件环境改进
-
软件配置改进
10-4 常用故障总数估算方法
故障总数估算方法,是软件可靠性工程重要工具,用于估算软件系统在一定时间内可能出现的故障总数,常见方法如下:
-
MTBF(平均故障间隔时间)方法:MTBF 指系统正常运行时两次故障间的平均时长,测量 MTBF 可估算故障总数。
-
MTTR(平均故障修复时间)方法:MTTR 指系统故障后平均修复时长,测量 MTTR 能估算故障总数。
-
故障率(Failure Rate)方法:故障率是系统单位时间内发生故障的概率,以此可估算故障总数。
-
Weibull 分布方法:利用常用的描述系统故障时间分布的 Weibull 分布估算。
-
指数分布方法:通过常用的描述系统故障时间分布的指数分布进行估算。
-
Markov 模型方法:借助常用的描述系统故障行为的 Markov 数学模型估算。
-
Bayes 网络方法:运用常用的描述系统故障行为的 Bayes 概率图模型估算。
-
故障树分析(FTA)方法:采用该常用故障分析方法描述系统故障行为并估算。
-
故障模式和影响分析(FMEA)方法:通过此常用故障分析方法描述系统故障行为以估算。
可依据系统具体情况和需求选用上述方法。
10-5 软件评审
软件评审(Software Review)是对软件产品或服务,进行评估审查,看是否符合质量、功能和性能要求,能保障其质量、安全性与可靠性。
主要目的:
-
确保软件质量,符合预期标准要求。
-
提高软件安全性,避免安全漏洞和风险。
-
改进软件性能,满足功能要求。
-
降低软件风险,防止对组织或用户造成损害。
步骤:
-
准备评审:明确目的、范围和标准。
-
收集信息:收集相关信息,如设计文档、源代码、测试结果等。
-
评审软件:检查是否符合标准要求。
-
记录结果:记录问题及改进建议。
-
跟踪改进:确保符合标准要求。
方法:
-
静态评审:针对设计文档、源代码等。
-
动态评审:针对运行情况。
-
黑盒评审:针对功能和性能。
-
白盒评审:针对内部结构和实现。
工具:
-
评审软件,如 SonarQube、CodeCoverage 等。
-
测试工具,如 JUnit、TestNG 等。
-
安全扫描工具,如 OWASP ZAP、Burp Suite 等。
-
性能测试工具,如 Apache JMeter、Gatling 等。
10-6 配置管理
软件配置管理(SCM)是对软件系统配置进行管理与控制,保障其完整性、可靠性和可维护性,涵盖软件系统各组成部分,像源代码、文档、测试用例等。
主要目的:
-
确保软件系统完整性,保证各部分完整且能正常工作。
-
提高软件系统可靠性,使其能正确工作并抵御错误、故障。
-
提高软件系统可维护性,便于维护和更新。
-
降低软件系统风险,使其能抵御风险与错误。
步骤:
-
配置识别:识别各组成部分并确定配置。
-
配置控制:控制各部分配置,确保完整性和可靠性。
-
配置状态账目:记录各部分配置状态,方便跟踪管理。
-
配置审查:审查各部分配置,确保符合要求。
-
配置更新:更新各部分配置,保证能正常工作。
工具:
-
版本控制系统,如 Git、Subversion 等
-
配置管理工具,如 Apache Ant、Apache Maven 等。
-
构建工具,如 Gradle、Maven 等。
-
部署工具,如 Docker、Kubernetes 等。
最佳实践:
-
使用版本控制系统管理源代码和配置。
-
使用配置管理工具管理配置。
-
使用构建工具构建软件系统。
-
使用部署工具部署软件系统。
-
定期审查配置,确保符合要求。
10-7 版本控制
版本控制(Version Control)是管理和控制软件系统不同版本,保障其完整性、可靠性与可维护性,涉及对源代码、文档、测试用例等各组成部分的管理。目的:
-
确保软件系统完整性,保证各部分完整且能正常工作。
-
提高软件系统可靠性,使其能正确工作并抵御错误、故障。
-
提高软件系统可维护性,便于维护和更新。
-
降低软件系统风险,使其能抵御风险与错误。
步骤:
-
创建版本库:用于存储软件系统各版本。
-
提交版本:将各版本提交到版本库。
-
管理版本:对库中版本进行创建、更新、删除等操作。
-
比较版本:确定不同版本间差异。
-
恢复版本:回滚到之前版本。
工具:
-
Git:分布式版本控制系统。
-
Subversion:集中式版本控制系统。
-
Mercurial:分布式版本控制系统。
-
CVS:集中式版本控制系统。
最佳实践:
-
使用版本控制系统管理软件系统版本。
-
定期提交版本到版本库。
-
使用分支管理不同版本。
-
使用标签标记不同版本。
-
定期备份版本库确保版本安全。
11-1 软件项目管理过程
软件项目管理过程
在软件工程里,软件项目管理过程是确保软件项目能够按时、按预算、高质量完成的一系列活动和方法。其主要包含以下几个关键阶段和内容:
-
项目启动:确定项目的目标、范围和可行性。明确软件要解决的问题,判断项目在技术、经济、操作等方面是否可行。例如,评估开发一款新的电商 APP 是否有市场需求,技术团队是否具备相应的开发能力等。
-
项目计划:制定详细的项目计划,包括项目进度安排、资源分配、成本预算等。要确定项目的各个阶段和里程碑,合理安排人员的工作任务和时间节点。比如,规划电商 APP 开发分需求分析、设计、编码、测试等阶段,每个阶段的时间和参与人员。
-
项目执行:按照计划开展项目的各项工作,包括软件开发、测试、文档编写等。在此过程中,要对项目进度进行监控,及时解决出现的问题。例如,开发团队按照设计文档进行代码编写,测试团队同步进行测试,发现问题及时反馈给开发人员。
-
项目监控与控制:定期检查项目的进展情况,对比实际进度和计划进度,分析偏差原因并采取纠正措施。同时,对项目的质量、成本等进行监控。比如,如果发现电商 APP 开发进度滞后,要分析是人员不足、技术难题还是其他原因导致的,并采取增加人员、调整计划等措施。
-
项目收尾:完成项目的各项任务,交付软件产品,进行项目总结和经验教训的积累。例如,将开发好的电商 APP 正式上线,对项目过程中的成功经验和失败教训进行总结,为后续项目提供参考。
11-2 质量度量
质量度量
质量度量是用于评估软件质量的一系列量化指标和方法,通过对软件的各种特性进行测量和分析,以确保软件满足规定的质量要求。主要包括以下方面:
-
产品质量度量:对软件产品本身的质量进行度量,如功能性、可靠性、易用性、效率、可维护性和可移植性等。例如,功能性度量可以通过测试用例的通过率来衡量软件是否满足用户的功能需求;可靠性度量可以用平均无故障时间(MTTF)来评估软件在一定时间内正常运行的能力。
-
过程质量度量:关注软件开发过程的质量,如过程的效率、规范性和稳定性等。例如,通过测量项目的进度偏差率来评估项目计划执行的效率;通过检查代码审查的覆盖率来衡量开发过程的规范性。
-
质量度量的作用:帮助开发团队及时发现软件质量问题,采取相应的改进措施;为项目决策提供依据,如是否可以进入下一阶段的开发;也有助于评估不同开发团队或项目的质量水平,促进团队之间的经验交流和学习。
11-3 估算
估算
估算在软件工程中是对项目的各种要素进行预测和评估的过程,主要包括以下几种常见的估算类型:
-
成本估算:预测软件开发项目所需的成本,包括人力成本、硬件设备成本、软件工具成本等。例如,根据项目的规模和复杂度,估算开发人员的工作量和薪酬,以及购买服务器、开发工具等所需的费用。常见的成本估算方法有类比估算法、参数估算法等。
-
进度估算:预估项目的开发周期和各个阶段的时间安排。可以根据以往类似项目的经验,或者使用专业的项目管理工具来进行进度估算。例如,通过分析历史数据,估算开发一款小型管理软件大概需要 3 个月时间,其中需求分析阶段 1 周,设计阶段 2 周等。
-
资源估算:确定项目所需的各种资源,如人力资源、硬件资源、软件资源等。例如,根据项目的功能需求和工作量,估算需要多少开发人员、测试人员,以及需要多大的服务器存储空间等。准确的估算可以帮助项目管理者合理分配资源,避免资源浪费或不足的情况发生。
11-4 软件开发成本估算
软件开发成本估算:估算软件开发项目的成本和时间。
软件开发成本估算目的:帮助软件开发团队,和项目管理人员,进行项目规划和管理。
软件开发成本估算步骤:
-
定义项目范围:确定软件开发项目的范围和功能。
-
确定软件规模:估算软件的大小和复杂度。
-
确定软件复杂度:估算软件的复杂度和难度。
-
确定开发团队的经验和技能:估算开发团队的经验和技能水平。
-
选择估算模型:选择合适的估算模型,例如COCOMO模型、功能点模型等。
-
输入参数:输入估算模型所需的参数,例如软件规模、软件复杂度、开发团队的经验和技能等。
-
计算估算结果:使用估算模型计算估算结果,例如软件开发成本和时间。
软件开发成本估算的优势包括:
-
提高项目可预测性
-
改善项目计划
-
降低项目风险
-
提高项目效率
11-5 软件开发成本估算模型
软件开发成本估算模型,是指用于估算软件开发项目成本的数学模型或方法。
常见的软件开发成本估算模型包括:
-
COCOMO模型:(Constructive Cost Model)基于软件规模和复杂度的成本估算模型。
-
功能点模型:基于软件功能点的成本估算模型。
-
LOC模型:(Lines of Code)基于软件代码行数的成本估算模型。
-
人月模型:基于软件开发人员数量和开发时间的成本估算模型。
-
三角模型:基于软件开发项目的范围、时间、成本的成本估算模型。
-
敏捷估算模型:基于敏捷开发方法的成本估算模型。
-
用例点模型:基于软件用例点的成本估算模型。
这些模型,可以帮助软件开发团队,估算软件开发项目的成本,并进行项目规划和管理。
COCOMO模型是最常用的软件开发成本估算模型之一,它基于以下三个主要参数:
-
软件规模:软件的大小和复杂度。
-
软件复杂度:软件的复杂度和难度。
-
开发团队的经验和技能:开发团队的经验和技能水平。
通过这些参数,COCOMO模型可以估算软件开发项目的成本和时间。
11-6 项目组织
在软件工程里,“项目组织”是为开展软件项目进行的人员架构、角色分配与协作模式设计等活动,利于提升项目效率和质量。
组织形式
-
职能型:按专业职能分部门,项目时从各部门抽人。优点是专业交流易,缺点是协调难、部门易重自身利益。
-
项目型:为项目单独组团队,成员全职投入,结束后团队或解散。优点是目标明确、沟通高效,缺点是资源难共享、成员安置有问题。
-
矩阵型:结合前两者特点,成员属职能部门又参与项目,需向双领导汇报。优点是资源利用好,缺点是可能有双重领导冲突。
团队角色与职责
-
项目经理:规划、组织、协调、控制项目,定计划、分资源、监控进度、解决问题。如电商项目中协调各方工作、与客户沟通。
-
系统分析师:收集、分析、定义用户需求,转化为系统需求文档。像 ERP 项目中了解企业业务流程。
11-7 CMM
CMM(Capability Maturity Model)是软件过程改进的模型,用于评估和改进软件开发组织的能力和成熟度。
CMM定义了五个级别的软件过程能力:
-
初始级别(Level 1):软件过程是混乱的,缺乏纪律和控制。
-
可管理级别(Level 2):软件过程是可管理的,有基本的纪律和控制。
-
已定义级别(Level 3):软件过程是已定义的,有标准的过程和方法。
-
量化管理级别(Level 4):软件过程是量化管理的,有详细的度量和控制。
-
优化级别(Level 5):软件过程是优化的,有持续的改进和创新。
CMM定义了七个关键过程域:
-
需求管理:确保软件需求是完整、准确和一致的。
-
项目计划:确保软件项目是有计划、有组织和有控制的。
-
项目监控和控制:确保软件项目是按照计划执行的。
-
配置管理:确保软件配置是完整、准确和一致的。
-
质量保证:确保软件质量是符合要求的。
-
验证和确认:确保软件是符合需求和规范的。
-
测量和分析:确保软件过程是有数据支持的。
CMM的评估和认证是由SEI(Software Engineering Institute)负责的。评估和认证的目的是为了确定软件开发组织的CMM级别。
12-1 个人总结
1、软件工程这门课,重在实践。上面都是理论性知识,更重要的是实践,针对不同类型的项目和需求,如何选择合适的开发方式和开发模式,避免纸上谈兵。
2、软件工程,早期就是为了解决大型软件的问题——切记是大型软件系统,不是小型软件。
如果是小型软件,需求明确,那么没有必要这么折腾,直接开发就行了。
大型软件,才需要产品,UI,技术,测试,维护等不同的阶段,需要用管理学的知识,来解决人员需求复杂的情况。