📖 前言:快考试了,做篇期末总结,都是重点与必考点。
题型:材料分析题、简答题、看图分析题
课本:
目录
- 🕒 1. 软件生存周期与软件过程
- 🕘 1.1 软件生存周期
- 🕘 1.2 传统的软件过程
- 🕤 1.2.1 瀑布模型(Waterfall Model)
- 🕤 1.2.2 快速原型模型(Rapid Prototype Model)
- 🕘 1.3 统一过程和敏捷过程
- 🕤 1.3.1 统一过程(Rational Unified Process,RUP)
- 🕤 1.3.2 敏捷过程(Agile Process)
- 🕘 1.4 软件可行性研究(Feasibility Study)
- 🕒 2. 结构化分析(Structured Analysis,SA)与设计(SD)
- 🕘 2.1 概述
- 🕘 2.2 数据流图(DFD)
- 🕘 2.3 结构图(SC)
- 🕘 2.4 判定表与判定树
- 🕒 3. 面向对象概述
- 🕒 4. UML
- 🕘 4.1 用例图
- 🕘 4.2 类图
- 🕘 4.3 状态图
- 🕘 4.4 顺序图/时序图
- 🕘 4.5 活动图
🕒 1. 软件生存周期与软件过程
🕘 1.1 软件生存周期
需求分析 → 软件分析 → 软件设计 → 编码(测试) → 交付测试 → 使用维护
- 需求分析
- 明确需要解决的问题(从用户的视角)
- 建立需求模型:功能、性能、约束、接口等
- 软件分析
- 从开发人员的视角对软件进行分析
- 建立分析模型:软件的逻辑模型
- 软件设计
- 确定软件的总体结构和各部件的数据结构和操作
- 建立软件设计模型:考虑实现技术和平台
- 编码
- 用程序设计语言将设计文档翻译成源程序
- 建立软件实现模型:包含现有软件构件包
- 软件测试
- 发现程序中的错误、提高软件质量
- 单元测试、集成测试、确认测试、系统测试
- 运行维护
软件过程:围绕软件开发所进行的一系列活动
软件过程模型
- 把软件生存周期中软件开发活动的有序流程用一个合理的框架来规范描述。
- 软件过程模型是一种软件过程的抽象表示法,它从一个特定的角度表现一个开发过程。
软件生存周期中的阶段和软件过程中的活动是基本一致的。
- 面向对象软件工程:
- 面向对象基本概念:对象+类+继承+消息通信
- OO分析与对象抽取 → 对象详细设计 → 面向对象的编码 和测试
🕘 1.2 传统的软件过程
🕤 1.2.1 瀑布模型(Waterfall Model)
瀑布开发模型是一种基于软件生存周期的线性开发模型,它与软件生存周期的特点是一致的,强调软件文档,每一个阶段必须完成规定的文档,每一个阶段都要复审完成的文档。
特点
- 阶段的顺序性和依赖性
- 推迟实现的观点
- 质量保证的观点
存在问题
- 不适合需求模糊的系统
- 开发初始阶段很难彻底弄清软件需求
🕤 1.2.2 快速原型模型(Rapid Prototype Model)
快速原型模型是一种基于原型的迭代化开发模型。中心思想是先建立一个能够反映用户主要需求的原型(Demo),让用户实际看一下未来系统的概貌,以便判断哪些功能是符合需要的,哪些方面还需要改进。然后将原型反复改进,直至建立完全符合用户要求的新系统。
特点
- “逼真”的原型可以使用户迅速作出反馈
- 循环回溯和迭代:非线性模型
- 使用快速开发工具
种类
- 渐进型:对原型补充和修改获得最终系统
- 抛弃型:原型废弃不用
应防止的偏向:舍不得抛弃,从而影响软件质量
小结:瀑布模型是纸上谈兵,快速原型模型是真枪实干。
🕘 1.3 统一过程和敏捷过程
🕤 1.3.1 统一过程(Rational Unified Process,RUP)
统一过程描述了软件开发中各个环节应该做什么、怎么做、什么时候做以及为什么要做,描述了一组以某种顺序完成的活动。
统一过程将软件开发分为四个阶段:
- 先启:定义整个项目的范围
- 精化:制定项目计划、描述功能、建立体系架构框架
- 构建:构造软件产品
- 迁移:将软件产品移交到最终用户手中
🕤 1.3.2 敏捷过程(Agile Process)
敏捷开发是一种以人为核心、迭代、循序渐进的开发方法,其软件开发过程称为“敏捷过程”
软件过程模型的特点汇总:
开发模型 | 特点 | 适用场合 |
---|---|---|
瀑布模型 | 线性模型,每一阶段必须完成规定的文档 | 需求明确的中、小型软件开发 |
快速原型模型 | 用户介入早,通过迭代完善用户需求,原型废弃不用 | 需求模糊的小型软件开发 |
增量模型 | 每次迭代完成一个增量,可用于OO开发 | 容易分块的大型软件开发 |
螺旋模型 | 典型迭代模型,重视风险分析,可用于OO开发 | 具有不确定性大型软件开发 |
构件集成模型 | 软件开发与构件开发平行进行 | 领域工程、行业的中型软件开发 |
转换模型 | 形式化的规格说明,自动的程序变换系统 | 理想化模型,尚无成熟工具支持 |
净室模型 | 形式化的增量开发模型,在洁净状态下实现软件制作 | 开发团队熟悉形式化方法,中小型软件开发 |
🕘 1.4 软件可行性研究(Feasibility Study)
目的
- 研究项目是否可能实现和值得进行
- 回答 Why to do?
研究的内容:经济可行性、技术可行性、运行可行性、法律可行性
可行性研究的步骤:
- 对当前系统进行调查和研究
- 弄清当前系统
- 导出新系统逻辑模型
- 导出新系统的解决方案
- 设计不同的解决方案
- 提出推荐的方案
- 本项目的开发价值
- 推荐这个方案的理由
- 编写可行性认证报告
- 系统概述
- 可行性分析
- 结论意见
软件风险分析:
- 风险识别:项目风险、技术风险、商业风险
- 风险预测
- 风险发生的可能性
- 风险发生后的后果
- 风险的驾驭和监控
🕒 2. 结构化分析(Structured Analysis,SA)与设计(SD)
🕘 2.1 概述
结构化分析与设计最初系由结构化程序设计扩展而来
- 是瀑布模型的首次实践
- SA与SD的流程
- 结构化分析(工具:DFD、PSPEC) → 分析模型(分层DFD图)+ SRS
- 结构化设计(工具:SC图) → 映射 \stackrel{映射}{\rightarrow} →映射 初始设计模型(初始SC图)
- 初始设计模型(初始SC图) → 优化 \stackrel{优化}{\rightarrow} →优化 最终设计模型(最终SC图)
- 基本任务与指导思想
- 结构化分析
- 建立分析模型(Analysis Model)
- 编写需求说明(Software Requirements Specification,SRS)
- 结构化设计
- 软件设计 = 总体设计 + 详细设计
- SC图须分两步完成:初始SC图、最终SC图
- 细化与分解
- 逐步细化,细化的本质就是分解
- 结构化分析
🕘 2.2 数据流图(DFD)
- 数据流图:指明数据在系统中移动时如何被变换,描述对数据流进行变换的功能和子功能。
- 组成符号
- 圆框代表加工;
- 箭头代表数据的流向,数据名称总是标在箭头的边上;
- 方框表示数据的源点和终点;
- 双杠(或单杠)表示数据文件或数据库
- 文件与加工之间用带箭头的直线连接,单向表示只读或只写,双向表示又读又写
上图含义:现有2个加工(审查并开发票、开领书单),4个数据流(购书单、发票、领书单、无效书单),数据的源点和终点都是学生。在审查购书单和开出发票之前,至少要查阅2个文件:一个文件是各班学生用书表,用以核对学生是否需用这些教材;另一个文件是教材存量表,以确定是否有该学生要买的教材。加工1要从教材存量表中读出数据,以判断有没有可卖的教材;售出教材后又要在原存量中减去售出的数量,把新存量写回教材存量表,所以在加工1与教材存量表之间使用了带双箭头的连线。各班学生用书表只读不写,应用单向箭头连线连接,图中箭头的方向表示从文件读出。
分层数据流图:
绘制步骤:
- 顶层DFD图:顶层图表示系统与外部实体之间的数据交换关系。
①顶层图只包含一个加工(加工名即为系统名);
②顶层图描述系统与外部实体之间的数据流;
③顶层图只有一张。 - 画系统的内部:第二层DFD图(部分教材也称为0层图)
①分解顶层图为若干个加工,系统有几个功能,就分解为几个加工;
②描述加工与外部实体之间、加工与数据文件之间、加工与加工之间的数据流。
③第二层图只有一张, 图中的加工号为“1,2,…,n ”。 - 画更下层数据流图(第3层图、第4层图、…)时,则分解上层图中的加工,直到图中尚未分解的加工都足够简单为止。子图号就是父图中被分解的加工号;子图中加工号由图号、小数点和序号组成。
例1:将上图的教材销售系统扩展为教材购销系统,功能如下:
(1)根据教学计划,向学生供应所需的教材。
①系统接受学生的购书单,检验购书单。若教材库存量充足,进行售书处理,即修改教材存量表,给学生开发票和领书单,学生凭单到书库领书;
②若教材库存量不足,对脱销的教材进行缺书登记。
(2)根据缺书登记表采购所缺的教材,通知学生补购。
①按缺书登记表进行汇总,并按出版社统计缺书,将缺书单发给书库保管员,以便采购。
②待购教材到货后,根据书库保管员发来的进书通知单进行缺书销售,即修改教材存量表,并从缺书登记表中取出缺书单进行售书处理。
解析:
顶层DFD:
第二层DFD:
第三层DFD——销售子系统:
第三层DFD——采购子系统:
例2:某银行储蓄系统功能是:将储户填写的存款单或取款单输入系统。 如果是存款,系统将储户的存款信息(姓名、住址、存款日期、存款类型、存款金额、利率等)记录在帐户文件中,并打印存款清单给储户;如果是取款,系统先查询帐户文件,并打印取款清单给储户。
(1)画出该问题数据流图的顶层图、第二层图和第三层图。
(2)以公式的形式建立数据流条目“存款单”。
解答:(1)
注:第三层图的源点和终点可以不画。
(2)数据流条目
存款单 = 姓名 + 地址 + 存款日期 + 存款类型 + 存款金额 + 利率
【2004年上半年软件设计师下午试题】:某基于微处理器的住宅系统,使用传感器(如红外探头,摄像头等)来检测各种意外情况,如非法进入,火警,水灾等。
房主可以在安装该系统时配置安全监控设备(如传感器,显示器,报警器等),也可以在系统运行时修改配置,通过录像机和电视机监控与系统连接的所有传感器,并通过控制面板上的键盘与系统进行信息交互。在安装过程中,系统给每个传感器赋予一个编号(即id)和类型,并设置房主密码以启动和关闭系统,设置传感器事件发生时应自动拨出的电话号码。当系统检测到一个传感器事件时,就激活警报,拨出预置的电话号码,并报告关于位置和检测到的事件的性质等信息。
(1)数据流图1-1(住宅安全系统顶层图)中的A和B分别是什么?
(2)数据流图1-2(住宅安全系统第0层DFD图)中的数据存储“配置信息”会影响图中的哪些加工?
(3)将数据流图1-3(加工4的细化图)中的数据流补充完整,并指明加工名称、数据流的方向(输入/输出)和数据流名称。
解答:(1)A:传感器;B:报警器
(2)3.密码处理;4.监控传感器;5.显示信息和状态
加工名称 数据流的方向 数据流名称 4.1 显示格式 输出 传感器数据 4.4 读传感器 输入 传感器状态 4.5 拨号 输出 电话拨号 \begin{array}{|c|c|c|} \hline {\text { 加工名称 }} & \text { 数据流的方向 } & \text { 数据流名称 }\\ \hline 4.1 显示格式 & 输出 & 传感器数据 \\ \hline 4.4 读传感器 & 输入 & 传感器状态 \\ \hline 4.5 拨号 & 输出 & 电话拨号 \\ \hline \end{array} 加工名称 4.1显示格式4.4读传感器4.5拨号 数据流的方向 输出输入输出 数据流名称 传感器数据传感器状态电话拨号
🕘 2.3 结构图(SC)
优化结构设计的指导规则 :
对模块划分的指导规则
- 提高内聚,降低耦合后
- 简化模块接口
- 少用全局性数据和控制型信息
保持高扇入/低扇出的原则
- 扇入高则上级模块多,能够增加模块的利用率
- 扇出低则表示下级模块少,可以减少模块调用和控制的复杂度
- 煎饼型不可取,应增加中间层减少扇出,实现塔型结构。
- 设计良好的软件通常具有瓮型结构,两头小,中间大,在低层模块使用了较多高扇入的共享模块。
例3:请把下面的DFD图转换为SC图:
解答:SC图为
🕘 2.4 判定表与判定树
例4:某公司为推销人员制订了奖励办法,把奖金与推销金额及预收货款的数额挂钩。凡每周推销金额不超过10000元,按预收货款是否超过50%,分别奖励推销额的6%或4%。反之若推销金额超过10000元,则按预收货款是否超过50%,分别奖励推销额的8%或5%。对于月薪低于1000元的推销员,分别另发鼓励奖300、200和500、300元。
试分别采用判定表和判定树为DFD图中用来“计算奖金”的加工写出加工说明(即PSPEC)。
解答:
例5:某航空公司规定,乘客可以免费托运重量不超过30公斤的行李。当行李重量超过30公斤时,对头等舱的国内乘客超重部分每公斤收费4元,对其他舱的国内乘客超重部分每公斤收费6元,对外国乘客超重部分每公斤收费比国内乘客多一倍,根据描述将下述判定表补充完整。(在相应的位置画√)
决策规则号 | NULL | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|---|
条件 | 行李重量 <=30 | Y | Y | Y | Y | N | N | N | N |
国内乘客 | Y | Y | N | N | Y | Y | N | N | |
头等舱 | Y | N | Y | N | Y | N | Y | N | |
决策结果 | 免费 | ||||||||
(W-30)*4 | |||||||||
(W-30)*6 | |||||||||
(W-30)*8 | |||||||||
(W-30)*12 |
解答:
决策规则号 | NULL | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|---|
条件 | 行李重量 <=30 | Y | Y | Y | Y | N | N | N | N |
国内乘客 | Y | Y | N | N | Y | Y | N | N | |
头等舱 | Y | N | Y | N | Y | N | Y | N | |
决策结果 | 免费 | √ | √ | √ | √ | ||||
(W-30)*4 | √ | ||||||||
(W-30)*6 | √ | ||||||||
(W-30)*8 | √ | ||||||||
(W-30)*12 | √ |
🕒 3. 面向对象概述
面向对象方法的定义:面向对象方法是以对象为核心的软件开发方法,使软件开发尽可能按照人对客观世界认识的规律和解决问题的方法与过程,以便使描述问题的空间与实现方法在结构上尽量一致。
是把面向对象分析(OOA)、面向对象设计(OOD)和面向对象程序设计(OOP)集成到生存期的相应阶段。
结构化方法 .VS. 面向对象方法:
- 结构化方法
- 以过程为中心构造系统。
- 将现实世界映射为数据流,加工。
- 强调过程抽象和模块化
- 加工之间通过数据流进行通信。
- 被动的数据被主动的加工所操作。
- 面向对象方法
- 以对象为中心构造系统。
- 把世界看成对象的集合。
- 对象将数据和操作封装在一起。
- 对象之间通过消息相互通信。
🕒 4. UML
🕘 4.1 用例图
定义:描述系统和外部环境的关系和系统所能提供的服务。
作用:用例图被用在需求分析阶段,通过系统外部的参与者与系统之间交互过程的描述,来展现系统的功能。
用例之间存在着泛化、包含、扩展关系。
例6:根据你的理解,把下面的用例图补充完整。
解答:
例7:某学校要开发一个网上选课系统。该系统提供以下基本功能:
建立课程:教务人员通过本系统建立课程信息
课程维护:教务人员修改和删除课程信息
安排课程:教务人员安排课程,课程的安排信息包括:
周学时、授课时间、授课老师、教室等信息
调整课程:教务人员对已经安排的课程信息进行调整。
课程浏览:用户可以浏览和查询课程信息
学生选课:学生登陆本系统,选择自己要修的课程。
选课浏览:学生浏览自己选修的课程。
试分析以上问题,并通过用例图描述该系统的功能。
解答:
例8:某城市拟开发一个基于Web城市黄页,公开发布该城市重要的组织或机构(以下统称为客户)的基本信息,方便城市生活。该系统的主要功能描述如下:
(1)搜索信息:任何使用Internert的网络用户都可以搜索发布在城市黄页中的信息,例如客户的名称、地址、联系电话等。
(2)认证:客户若想在城市黄页上发布信息,需通过系统的认证。认证成功后,该客户成为系统授权用户。
(3)更新信息:授权用户登录系统后,可以更改自己在城市黄页中的相关信息,例如变更联系电话等。
(4)删除客户:对于拒绝继续在城市黄页上发布信息的客户,有系统管理员删除该客户的相关信息。
试画出系统的用例图。
解答:
例9:设有一公司管理系统,该系统设有如下行为:雇员可以选择得到报酬的方式(用例Select Payment Method)、可以对雇员进行考勤(用例Maintain Timecard)、雇员可以创建工作报告(用例Create Employee Report),考勤记录和工作报告要包存在数据库中(用例用例Maintain Timecard和Create Employee Report与参与者Project Management DB通信),管理员可以创建、修改、删除系统中雇员的信息(用例Maintain Employee Information),每月的固定时间要通过银行系统给雇员发薪水(参与者(系统时钟)与用例Run Payroll通信),并通过打印机打印出工资单(用例Run Payroll与参与者Printer通信)。
解答:
【经典软考真题】:某电话公司决定开发一个管理所有客户信息的交互式网络系统。系统的功能如下:
(1)浏览客户信息:任何使用Internet的网络用户都可以浏览电话公司所有的客户信息(包括 姓名、住址、电话号码等)。
(2)登录:电话公司授予每个客户一个帐号。拥有授权帐号的客户,可以使用系统提供的页面设置个人密码,并使用该帐号和密码向系统注册。
(3)修改个人信息:客户向系统注册后,可以发送电子邮件或者使用系统提供的页面,对个人信息进行修改。
(4)删除客户信息:只有公司的管理人员才能删除不再接受公司服务的客户的信息。 系统采用面向对象方法进行开发,在开发过程中认定出的类如下表所示。
表 开发过程中认定出的类
编号 类名 描述 1 IntermetClient 网络用户 2 CustomerList 客户信息表,记录公司所有客户的信息 3 Customer 客户信息,记录单个客户的信息 4 CompanyCustomer 公司客户 5 Tntema1Ctient 公司的管理人员 \begin{array}{|c|c|c|} \hline {\text { 编号 }} & \text { 类名 } & \text { 描述 }\\ \hline 1 & {\text { IntermetClient }} & 网络用户 \\ \hline 2 & {\text { CustomerList }}& 客户信息表,记录公司所有客户的信息 \\ \hline 3 & {\text { Customer }}& 客户信息,记录单个客户的信息 \\ \hline 4 & {\text { CompanyCustomer }}& 公司客户 \\ \hline 5 & {\text { Tntema1Ctient }}& 公司的管理人员 \\ \hline \end{array} 编号 12345 类名 IntermetClient CustomerList Customer CompanyCustomer Tntema1Ctient 描述 网络用户客户信息表,记录公司所有客户的信息客户信息,记录单个客户的信息公司客户公司的管理人员
(1)在需求分析阶段,采用UML的用例图描述系统功能需求,如下图用例图所示。请指出图中的A、B、 C和D分别是哪个用例?
(2)在UML中,重复度(multiplicity)定义了某个类的一个实例可以与另一个类的多少个实例相关联。通常把它写成一个表示取值范围的表达式或者一个具体的值。例如,下图中的类InternetClient和 CustomerList,InternetClient端的“0…*”表示:1个CustomerList的实例可以与0个或多个 InternetClient的实例相关联;CustomerList端的“1”表示:一个InternetClient的实例只能与1个 CustomerList的实例相关。
请指出下图中(1)~(4)处的重复度分别为多少?
解析:
(1)A:浏览客户信息 B:修改个人信息 C:登录 D:删除客户信息
解析:题目说明中提到了系统有4个功能:浏览客户信息、登录、修改个人信息、删除客户信息。这也就是4个用例,现在只需把它们对号入座即 可。根据题目说明可以知道,任何使用Internet的网络用户都可以浏览电话公司所有的客户信息,在图中符合这一条件的只有A了,所以A应填“浏览客户信息”。又因为只有公司的管理人员才能 删除不再接受公司服务的客户的信息,所以D应填“删除客户信息”。
剩下就只有“登录”和“修改个人信息”两个用例了,B和C考查的是这2个用例之间的关系。根据“<<include>>
”可知,这里是包含关系。根据常识我们知道,在修改个人信息之前需要登录, 因此,“修改个人信息”包含“登录”表,即B应填“修改个人信息”,C应填“登录”。
(2)因为1个CustomerList的实例可以与0个或多个Customer的实例相关联;而1个 Customer的实例只能与1个CustomerList的实例相关。所有(1)空应填1
,(2)空应填 0..*
。因为Customer是CompanyCustomer的相应的详细信息,所以(3)空和(4)空都应该填写0..1
。
🕘 4.2 类图
定义:类图用来表示系统中的类以及类与类之间的关系。 (例如,关联、依赖、泛化和细化等关系),也表示类的内部结构(类的属性和操作)。类图描述的是一种静态关系,在系统的整个生命期内都是有效的。
示例:
在关联的两端可写上一个被称为重数(multiplicity)的数值范围,表示该类有多少个对象可与对方的一个对象连接。重数的符号表示有:
- 1 表示1个对象,重数的默认值为1。
- 0 …1表示0或1。
- 1 …*表示1或多。
- 0…*表示0或多,可以简化表示为*。
- 2…4 表示2~4。
例10:一个企业可以雇佣多个人员。企业的性质包括名称、住址、电话、简况。人员的情况包括姓名、年龄、性别、住址、电话、简历等。雇佣的信息包括雇佣的开始日期、截止日期,简要说明等。双方要签订雇佣合同。雇佣还涉及到被雇用人员所从事的工作岗位。分析这个问题,提取这个问题所涉及到类,定义各个类之间的关系,并画出类图。
解答:
例11:某绘图系统存在Point、Line、Square三种图元,它们具有Shape接口,图元的类图关系如图所示。现要将Circle图元加入此绘图系统以实现功能扩充。已知某第三方库已经提供了XCircle类,且完全满足系统新增的Circle图元所需的功能,但XCircle不是由Shape派生而来,它提供的接口不能被系统直接使用。代码3-1既使用了XCircle又遵循了Shape规定的接口,既避免了从头开发一个新的Circle类,又可以不修改绘图系统中已经定义的接口。代码3-2根据用户指定的参数生成特定的图元实例,并对之进行显示操作。请在代码补全代码空缺处。
绘图系统定义的接口与XCircle提供的显示接口及其功能如下表所示:
// 代码3-1
class Circle (1) {
private (2) pxc;
public Circle() {
pxc = new (3);
}
public void display() {
pxc.(4);
}
}
// 代码3-2
public class Factory {
public (5) getShapeInstance(int type) { // 生成特定类实例
switch(type) {
case 0: return new Point();
case 1: return new Rectangle();
case 2: return new Line();
case 3: return new Circle();
default: return null;
}
}
}
public class App {
public static void main(String argv[]) {
if (argv.length != 1) {
System.out.println("error parameters!");
return;
}
int type = Integer.parseInt(argv[0]);
Factory factory = new Factory();
Shape s;
s = factory.(6);
if (s == null) {
System.out.println("Error get instance!");
return;
}
s.display();
return;
}
}
解答:
// 代码3-1
class Circle implements Shape {
private Xcircle pxc;
public Circle() {
pxc = new Xcircle;
}
public void display() {
pxc.displayIt();
}
}
// 代码3-2
public class Factory {
public Shape getShapeInstance(int type) { // 生成特定类实例
switch(type) {
case 0: return new Point();
case 1: return new Rectangle();
case 2: return new Line();
case 3: return new Circle();
default: return null;
}
}
}
public class App {
public static void main(String argv[]) {
if (argv.length != 1) {
System.out.println("error parameters!");
return;
}
int type = Integer.parseInt(argv[0]);
Factory factory = new Factory();
Shape s;
s = factory.getShapeInstance(type);
if (s == null) {
System.out.println("Error get instance!");
return;
}
s.display();
return;
}
}
例12:在一个订货系统中,采购员从供货商处订货,双方需要签订订单,一个采购员可以订多个供货商的货品,一个供货商也可以给多个采购员供货。分析这个问题,并用类图对这个问题进行建模。
解答:
例13:根据自己的理解,对下图中不合理之处进行修改。
解答:
🕘 4.3 状态图
定义:描述类的对象可能具有的所有状态,以及引起状态变化的事件,状态变化称作状态转换。
通常,状态图是对类图的补充。实际使用时,并不需要为每个类都画状态图,仅需要为那些有多个状态,且其行为在不同状态有所不同的类画状态图。
例14:用状态图描述一个请假流程:少于等于 3 天的请假申请,辅导员审批就可以了,超过 3 天的请假还需系主任审批。
解答:
例15:传输门是传输系统中的重要装置。传输门具有 Open(打开)、Closed(关闭)、Opening(正在打开)、StayOpen(保持打开)、Closing(正在关闭)五种状态。触发状态的转换事件有 click、complete 和 timeout 三种。事件与其相应的状态转换如图所示。
下面的【Java 代码 1】与【Java 代码 2】分别用两种不同的设计思路对传输门进行状态模拟,请填补代码中的空缺。
// 代码1
public class Door {
// 定义状态变量,用不同的整数表示不同状态
public static final int CLOSED = 1;
public static final int OPENING = 2;
public static final int OPEN = 3;
public static final int CLOSING = 4;
public static final int STAYOPEN = 5;
private int state = CLOSED;
private void setState(int state) {
this.state = state; // 设置传输门当前状态
}
public void getState() {
// 此处代码省略,本方法输出状态字符串,
// 例如,当前状态为 CLOSED 时,输出字符串为”CLOSED”
}
// 发生 click 事件时进行状态转换
public void click() {
if ((1)) {
setState(OPENING);
} else if ((2)) {
setState(CLOSING);
} else if ((3)) {
setState(STAYOPEN);
}
}
// 发生 timeout 事件时进行状态转换
public void timeout() {
if (state == OPEN) {
setState(CLOSING);
}
}
// 发生 complete 事件时进行状态转换
public void complete() {
if (state == OPENING) {
setState(OPEN);
} else if (state == CLOSING) {
setState(CLOSED);
}
}
public static void main(String[] args) {
Door aDoor = new Door();
aDoor.getState();
aDoor.click();
aDoor.getState();
aDoor.complete();
aDoor.getState();
aDoor.click();
aDoor.getState();
aDoor.click();
aDoor.getState();
return;
}
}
// 代码2
public class Door {
public final DoorState CLOSED = new DoorClosed(this);
public final DoorState OPENING = new DoorOpening(this);
public final DoorState OPEN = new DoorOpen(this);
public final DoorState CLOSING = new DoorClosing(this);
public final DoorState STAYOPEN = new DoorStayOpen(this);
private DoorState state = CLOSED;
// 设置传输门当前状态
public void setState(DoorState state) {
this.state = state;
}
public void getState() { // 根据当前状态输出对应的状态字符串
System.out.println(state.getClass().getName());
}
public void click() { // 发生 click 事件时进行状态转换
(4);
}
public void timeout() { // 发生 timeout 事件时进行状态转换
(5);
}
public void complete() { // 发生 complete 事件时进行状态转换
(6);
}
public static void main(String[] args) {
Door aDoor = new Door();
aDoor.getState();
aDoor.click();
aDoor.getState();
aDoor.complete();
aDoor.getState();
aDoor.timeout();
aDoor.getState();
return;
}
}
public abstract class DoorState { // 定义所有状态类的基类
protected Door door;
public DoorState(Door door) {
this.door = door;
}
public void click() {}
public void complete() {}
public void timeout() {}
}
class DoorClosed extends DoorState { // 定义一个基本的 Closed 状态
public DoorClosed(Door door) {
super(door);
}
public void click() {
(7);
}
// 该类定义的其余代码省略
}
// 其余代码省略
解答:
(1) state == CLOSED || state == CLOSING
(2) state == OPENING || state == STAYOPEN
(3) state == OPEN
(4) state.click()
(5) state.timeout()
(6) state.complete()
(7) door.setState(door.OPENING)
【代码一】没有用状态模式,将所有的状态转换代码都写到Door类中,每一个状态对应一个整型常量(状态变量),当Door的click()等方法被调用时,可以实现相应状态的转换,根据状态图,可以完成对(1)、(2)和(3)空的解答,例如当状态变量state为CLOSED或者CLOSING时,调用click()方法,状态将转换为OPENING。同理,当timeout()方法和complete()方法被调用时,某些状态之间也可以发生转换。
【代码二】使用了状态模式,Door类充当环境类,提供了抽象类DoorState充当抽象状态类,其子类,如DoorClosed、DoorOpening等,充当具体状态类。在环境类Door枚举了所有的状态,提供了一个setState()方法用于设置当前状态,此外,在Door的click()方法中调用状态类的click()方法,在Door的timeout()方法中调用状态类的timeout()方法,在Door的complete()方法中调用状态类的complete()方法。因此,(4)、(5)、(6)空用于实现间接调用。第(7)空用于实现状态的切换,当状态为DoorClosed时,如果调用click()方法,那么Door的当前状态将切换到OPENING,因此在第(7)空,将调用door对象的setState()方法,注入一个DoorOpening类型的对象,由于该对象已存在于Door中,无须再重新创建。在C++中,可以通过door->OPENING来获取,而在Java中则通过door.OPENING来获取。在本试题中,状态的切换由具体状态类来完成,由环境类来维护各个具体状态类的实例。
🕘 4.4 顺序图/时序图
定义:显示若干个对象间的动态协作关系,它强调对象之间发送消息的先后次序,描述对象之间的交互过程。
例16:下图是一个通信图,试把该图转换为顺序图
解答:
例17:在顺序图中:Kjosk表示信息亭,BoxOffice表示售票中心, CreditCardService表示信用卡服务。
(1)Kjosk类中的操作有哪些?BoxOffice的操作有哪些 ? CreditCardService类的操作有哪些?
(2)根据对象间的消息顺序,描述该顺序图的含义。
解答:
(1)Kjosk类的操作有showAvailable(seat-list)、DemandPayment(cost)、printtickets(performance,seats)、ejectcard
BoxOffice的操作有Request(count,performance)、SelectSeats、InsertCard(CardNumber)、authorized
CreditCardService的操作有change(cardnumber,cost)
(2)信息亭查询演出的信息
售票中心给出可用的座位表
信息亭选择座位,售票中心给出所需要支付的费用
信息亭插入卡,提供信用卡卡号,进行费用支付
售票中心将信用卡号和费用发送给信用卡服务中心
信用卡服务中心验证有效性,并进行扣款
信息亭确认支付成功后,打印包含演出和座位信息的票,并弹出信用卡。
例18:阅读下面代码,根据代码内容画出相应序列图。
class Client{
Server server;
void work(){
server.open();
server.print("Hello World!");
server.close();
}
}
class Server{
Device device;
void open(){
}
void print(String str){
device.write(str);
}
void close(){
}
}
class Device{
void wite(String s){
}
}
解答:
🕘 4.5 活动图
定义:描述为满足用例要求而进行的动作以及动作间的关系。活动图是状态图的一个变种,它是另一种描述交互的方法。
例19:某教学系统操作员登录过程是:启动该系统,系统给出登录窗口,在登录窗口中需要输入用户名和密码,如果用户名或密码有误,则系统提示错误,操作员重新输入,若连续3次用户名或密码均没有输入正确,则系统拒绝登录。如果输入正确,则进入系统。用活动图描述操作员的登录过程。
解答:
例20:结合每学期选课的流程,画出选课的活动图。
解答:
❗ 转载请注明出处
作者:HinsCoder
博客链接:🔎 作者博客主页