Presentation is loading. Please wait.

Presentation is loading. Please wait.

第十章 面向对象 (2).

Similar presentations


Presentation on theme: "第十章 面向对象 (2)."— Presentation transcript:

1 第十章 面向对象 (2)

2 第十章内容概要 面向对象方法学概述 UML基础 面向对象的需求提取 面向对象分析 面向对象设计的准则 启发规则 软件重用 面向对象系统设计
面向对象对象设计

3 Use Case Use Case的引出(Why Use Case?) Use Case是什么:
了解需求→分析典型用例→ 不自觉、随意、潦草→ Jacobson提出Use Case分析法→ OO技术进入第二代; Use Case是什么: 本质上,一个Use Case是用户与计算机之间为达到某个目的的一次典型交互作用; 作为结果,Use Case代表的是系统的一个完整功能。

4 Use Case Actor: Actor是与系统交互的外部实体;
Actor是具有构造型<<Actor>>的类,所以谈论Actor时考虑的是其角色,而非角色的实例; Use Case总是由Actor启动的; Actor与Use Case间是多对多的关系。

5 Use Case Actor有助于获取Use Case 处理Actor与Use Case的关系

6 Use Case Use Case的描述: Use Case的名字:唯一标识 参与的Actor(s):标出其中的主动Actor
出口条件:完成后应满足的条件 特殊需求:非功能性需求

7 Use Case示例: 要编写“报告紧急情况”Use Case

8

9 场景(Scenario): 场景示例: 场景是Use Case的真实例子; 场景通过举例说明情况,帮助理解问题域,进而归纳Use Case;

10

11 Use Case间的关系:包含、扩展、泛化
扩展:将常规动作放在一个基本Use Case中,将非常规动作放在其扩展Use Case中。 泛化:对一般性Use Case做特殊化、细化。 包含与扩展的区别

12 Use Case Use Case的获取分两步: 要获取Actor,请对用户/客户提问:
谁使用系统的主要功能(Primary Actor)? 谁需要系统支持他们的日常工作? 谁来维护、管理系统(Secondary Actor)? 系统需要控制哪些硬件? 系统需要与其他哪些系统交互? 对系统产生的结果感兴趣的是哪些人或事物?

13 Use Case 要获取Use Case,请对Actor提问: Actor要做的是什么、要求系统提供哪些功能?
Actor必须提醒系统的事件有哪些?怎样把这些事件表示成Use Case中的功能?

14 Use Case 还可以考虑两个问题: 若直接总结Use Case有困难,用场景帮忙: 系统需要何种输入输出?它们从哪里来往哪里去?
现存的系统究竟有什么主要问题,以至于要换掉它? 若直接总结Use Case有困难,用场景帮忙: 基于场景和Use Case的需求提取:现实场景→想象场景→快速、小型原型→系统描述→ Use Case形式的需求定义。

15 基于Use Case的需求提取活动 确定Actor (确定场景) 确定Use Case 改进Use Case:错误、异常→ 全面完整
确定Use Cases间的关系:减少复杂性 确定参与对象:从Use Case迈向对象 确定非功能性需求

16 确定参与对象 确定每个Use Case的参与对象; 参与对象对应于问题空间的主要概念→形成术语表; 参与对象的确定产生了最初的分析模型:
对象的描述、属性可由用户评审; 作为整个分析模型与用户/客户衔接的部分,通常不会用完整的分析模型“烦恼”用户。

17 确定参与对象的试探法 开发人员或用户为理解Use Case所必须阐明的术语; Use Case中的常用名词(如,事件);
系统需要跟踪的现实世界实体(如,现场工作人员、资源); 系统需要跟踪的现实世界过程(如,紧急操作计划); Use Case本身(如,报告紧急情况); 数据来源或数据接受器(如,打印机); 接口产品(如,工作站); 总要使用的应用域的术语。

18 确定参与对象示例 针对前面举例的事故管理系统中的“报告紧急情况”用例,最初可能确定出以下参与对象: 报告紧急情况用例的参与对象见下表:
调度员、紧急情况报告、现场工作人员、事件 报告紧急情况用例的参与对象见下表:

19

20 第十章内容概要 面向对象方法学概述 UML基础 面向对象的需求提取 面向对象分析 面向对象设计的准则 启发规则 软件重用 面向对象系统设计
面向对象对象设计

21 从需求提取到分析 需求提取→Use Case和场景形式的需求说明→细化描述、规范和形式化→形成分析模型。
分析模型要:准确、完整、一致、可检验。它其实对应着传统的需求规约文档,但同时它也包含系统高层设计的起始部分。

22 分析概述 分析模型包括: 分析的活动: 功能模型:Use Case图表示 对象模型:类图、对象图表示 动态模型:顺序图、状态图表示
提取“分析类”(也叫“分析对象”); 转述Use Case或场景; 整理“分析类”;

23 “分析类”的含义 “分析类”是概念层的内容,从它们可捕获系统对象模型的雏形; “分析类”相当粗略,并且,不要往其中添加技术细节。

24 “分析类”的划分 划分原则:要尽量减小需求变化的影响——“高内聚、低耦合”。 实体类:系统要记录和维护的信息;
边界类:系统和外部要素间交互的边界; 控制类:Use Case中行为的协调;

25 “分析类”的表示 可以用构造型表示:<<entity>>、<<boundary>>、<<control>>; 也可以用特殊图示表示:

26 “分析类”的例子 如前面简单手表例子中: 时、分、秒是实体类; 按钮和液晶屏是边界类; 改变日期是控制类,代表通过组合按钮改变时间的活动;

27 实体类的含义 实体类描述必须存储的信息,以及与这些信息直接相关的操作; 实体类与系统外部环境以及特定Use Case的控制逻辑要弱耦合。

28 边界类的含义 边界类描述系统外部环境与内部运作之间的交互; 主要负责内容的翻译、形式的转换,并表达相应结果;
边界类把系统其他部分(实体类、控制类)与外部环境隔离; 注意这是概念层,不是要做具体界面。

29 控制类的含义 控制类描述一个Use Case特有的事件流中的控制行为,起协调人作用;

30 提取“分析类” 实体类:从参与对象中选取。 边界类:通常,一个Actor与Use Case之间的通信关联对应一个边界类。

31 标识实体对象的试探法 为理解Use Case,开发人员或用户需要阐明的术语; Use Case中反复出现的名词(如,事件);
系统需要一直跟踪的现实世界的实体(如,现场工作人员、资源); 系统需要一直跟踪的现实世界的活动(如,紧急操作计划); Use Case本身(如,报告紧急情况)数据源点或终点(如,打印机); 总是使用的用户术语。

32 针对前面举例的事故管理系统中的“报告紧急情况”用例,在进行第一次检查时,通过使用领域知识以及与用户交流,可能标识出以下实体对象:
调度员、现场工作人员、紧急情况报告、事件 注意:紧急情况报告这个名字并没有在该用例中直接提到,但用例第3步出现了“现场工作人员提交的信息”这样的语句。与客户讨论后,发现这个信息通常是用来指紧急情况报告,于是决定把相应对象命名为“紧急情况报告”。 报告紧急情况用例的实体对象见下表:

33

34 标识边界对象的试探法 确定用户需要将数据输入系统的窗口或表格(如,紧急情况报告表单,报告紧急情况按钮);
确定系统对用户的响应或消息(如,确认通知); 不要用边界对象对界面的可视方面建模(用户模型更适于做这件事); 总是使用用户的术语而不是实现技术的术语来描述界面。

35 一个用例中,每个Actor至少与一个边界对象进行交互;
注意,系统对用户的响应或消息是一类边界对象; 报告紧急情况用例的边界对象见下表:

36

37 注意:事件表单并没有在报告紧急情况用例的某一处明显提及,但可以观察到调度员需要一个接口,用来浏览现场工作人员提交的紧急情况报告,并返回一个答复。因此标识出了这个对象。

38 标识控制对象的试探法 为每个Use Case标识一个控制对象,如果Use Case比较复杂并且能分解成更短的事件流,则为该Use Case标识多个控制对象; 为Use Case中的每个Actor标识一个控制对象; 一个控制对象的生命周期应该是对应Use Case的范围或一个用户界面的范围。如果很难确定一个控制对象活动的开始和结束,则表明对应的Use Case可能没有一个明确定义的入口和退出条件。

39 在报告紧急情况用例中,对每个Actor分别设立一个控制对象:对现场工作人员用报告紧急情况控制对象,而对调度员用管理紧急情况控制对象,见下表:

40

41 在对报告紧急情况用例建模时,使用实体、边界和控制对象对同一个功能建模。通过从事件流观察角度转移到结构性的观察角度,增加了描述的详细程度,并选择了标准术语来引用问题域和系统的主要实体。
下一步要用报告紧急情况用例和已经给出的对象来构建顺序图,顺序图将用例与对象捆绑在一起,表示用例所描述的行为是怎样在它的参与对象间分布的。

42 转述Use Case或场景 把文字描述的Use Case表述为UML的交互图。
协作图:“分析对象”间的“连接”关系。

43 顺序图的试探画法 第一列对应Use Case的主动Actor; 第二列是主动Actor对应的边界对象;
边界对象被控制对象创建; 实体对象被控制对象和边界对象访问; 实体对象从不去访问控制对象和边界对象。

44 典型的顺序图对象布局 顺序图明确了对象的“职责”——应该响应的消息;

45 报告紧急情况用例的顺序图(从现场工作站启动)

46 报告紧急情况用例的顺序图(调度站)

47 报告紧急情况用例的顺序图(现场工作站上的答复)

48 在报告紧急情况用例的顺序图(调度站)中,发现了在第一次检查报告紧急情况用例时忘记的实体对象“确认”。这个确认对象与确认通知边界对象不同,它保持与一个确认相关的信息,并在确认通知对象之前创建;
当描述到确认对象时,也会发现最初的报告紧急情况用例是不完整的。它仅提到了确认这回事,并没描述与之相关的信息; 这种情况下,开发人员要向客户/用户了解情况,从而定义需要在确认对象中出现的信息。之后,确认对象被加入到分析模型中,而报告紧急情况用例通过加入这条内容而得到了补充:

49 新发现的报告紧急情况用例的实体对象: 改进的报告紧急情况用例: (接下页)

50

51 整理“分析类” 根据前面得到的一系列交互图,总结出各“分析类”间的关系,最后得出“参与类图”(View of Participating Classes)。 这个过程主要是确定“分析类”的职责和关联关系。 “职责”是响应“消息”的能力。“消息”被要求者提出,“职责”由响应者承担。

52 “参与类图”的含义 “职责”和“属性”属于某一个特定的“分析类”。“分析类”之间的关联关系所涉及的范围则不局限于某一个“分析类”。“参与类图”是表述这些关联关系的方式。“参与类图”中包含一组类和它们之间的关系,这组类参与特定用例的动态交互内容,即特定用例的交互图组所反映的内容。 “参与类图”的主要目的是从用例中挖掘出参与类间的关系。

53 整理“分析类” “消息”作为单元将Use Case描述的需求场景分解成细小的颗粒:
“消息”本身将映射成为“分析类”的“职责”; “消息”的传递路径将初步映射为“分析类”之间的关联关系; 这是分析到设计在微观层面的映射; “分析类”各自的职责和它们之间的关联关系将构成高层设计方案的雏形。

54 从动态图到静态图 “分析类”的一条职责有可能响应多条消息; “分析类”间的关联关系有可能为多条消息提供传递路径;
动态图一点一滴地为静态图收集着素材,而静态图则是动态图的综合和结晶; 系统在这个从动态到静态的过程中不断充实; 这种过程一般需要选择某种辅助建模工具软件来支撑,否则不易实用。

55 “分析类”的属性 承担“职责”的“分析类”应具备相应的能力,这种能力主要依赖两方面的知识: “分析类”本身具有的信息就是“分析类”的属性;
一方面是“分析类”本身具有的信息; 另一方面是“分析类”能够找到的其他“分析类”。 “分析类”本身具有的信息就是“分析类”的属性; “分析类”用于找到其他“分析类”的知识是该“分析类”指向其他“分析类”的关联关系。广义上,关联关系也可算作“分析类”的属性。

56 “分析类”的属性 这里讨论的“属性”是狭义的属性,即“分析类”自身具有的简单信息。因而,属性的类型是简单数据类型,例如字符串型、整型、布尔型等。 在分析的这个阶段,“分析类”是粗略的,因而,“分析类”的属性也是相对粗略的,目的是在逻辑上支撑“分析类”所承担的“职责”。

57 确定“分析类”的职责 “职责”是“分析类”实例响应消息并完成特定任务的能力,包括为外部(其他对象)提供必要的服务和维护自身的信息。职责在后续的设计活动中将演化为“设计类”的一个或多个操作。确定“分析类”的职责,主要包括两个动作:

58 确定“分析类”的职责 第一步,找出“职责”。
鉴于“职责”和“消息”的简明对应关系,转述Use Case或场景的过程既是用“消息”分解和转述需求的过程,也是找出“职责”的过程; “消息”和“职责”并不是一回事,所谓找出“职责”是根据“消息”的要求定义“职责”,即用“职责”满足“消息”提出的要求; 不需要针对每一条消息定义一个新的职责,很多时候,利用已有的职责即可满足消息的要求;

59 确定“分析类”的职责 第二步,简要描述“职责”。
为了获得简明的图示,“职责”的名称通常比较简短,“职责”的实例将取代“消息”出现在顺序图或协作图中。建议给“职责”附加简要的文字说明,描述该“职责”可能对应的操作逻辑以及该“职责”被调用之后将返回何种结果。

60 确定“分析类”间的关联关系 “分析类”之间的关联关系通过参与类图(VOPC)直观地表达出来。确定“分析类”之间的关联关系,主要有两步:

61 确定“分析类”间的关联关系 概念上,特定用例的“参与类图”中,“分析类”之间的完整的关联关系要根据所有事件流中对象间的“连接”加以归纳,这是一个典型的动态向静态映射的过程; 由于多张协作图对确定“分析类”关联关系的贡献在很多时候是重叠的,可以从基本事件流的协作图入手,通过其他事件流的协作图加以验证和补充; 如果基本事件流的协作图中涵盖了所有参与类的实例,那么VOPC在外观上与该协作图相似。

62 参与类图(VOPC)

63 确定“分析类”间的关联关系 注意,“参与类图”中的关联关系应该能在对应用例的事件流中找到相应根据,而不是来自主观的臆断。另一方面,可以将一些显而易见的事实反映在“参与类图”中,例如明确的聚合关系或组合关系。

64 确定“分析类”间的关联关系 标识关系的试探法: 检查动词短语; 准确命名关系和角色; 尽可能经常地使用限定词来标识名字空间和关键属性;
消除任何能从其他关系衍生出来的关系; 直到所有关系稳定后再考虑多重性; 太多的关系会使模型不易理解。

65 确定“分析类”的属性 属性是“分析类”的基本内容,属性的取值使得“分析类”的实例具有必要的“知识”,从而履行其承担的“职责”。在分析阶段的任务中,确定属性的工作主要围绕实体类展开,也包括两个动作:

66 确定“分析类”的属性 首先,找出属性。属性的基本来源是用例的事件流描述,并通过“分析类”的职责来间接地获取。如果对“分析类”的“职责”的简要描述比较明确,属性比较容易获取; 然后简要描述属性。属性名称应当是一个简短的名词,说明其保存的信息。分析活动中,属性应该是粗线条的,通常没必要在属性的数据类型和相关细节上耗费过多精力。为了使模型易于理解和沿用,通常建议给含义相对复杂的属性附加必要的上下文说明。

67 确定“分析类”的属性 标识属性的试探法: 检查所有格短语; 把存储的状态表示为实体对象的属性; 描述每个属性;
不要把一个属性表示为对象,而是使用一个关系来替代; 在对象结构稳定之前不要浪费时间来描述细节问题。

68 下面开始整理报告紧急情况用例的“分析类”:
首先将描述该用例的顺序图中的“消息”映射成对应“分析类”的“职责”,例如

69 本例中,“职责”的名称基本还是沿用“消息”的名称,因为用例和顺序图还是处于很简略的阶段,这阶段的“消息”和“职责”并没出现什么差异;
“职责”还不是类的操作,故用“//”为其前缀作为表示形式; 然后,绘制报告紧急情况用例的VOPC,以确定各“分析类”间的关联关系,见下图:

70 报告紧急情况用例的VOPC

71 下一步,如果可能,确定一下“分析类”的属性,主要依据各“分析类”自行承担的“职责”;
以实体类紧急情况报告为例,它所对应的职责很简单,只有“创建自己”这条,不过根据用例的事件流中的描述,创建紧急情况报告对象时,需要它包括一些基本信息,由此可以初步给出一些属性:

72 检查分析模型 分析模型用渐进循环方式构建。在第一次构建中,分析模型很少是正确的,甚至是不完整的;
在分析模型形成一个正确的说明、从而能被用来进行后面的设计和实现之前,与客户和用户间的多次循环是必要的; 一旦分析模型变得稳定,应该首先由开发人员检查它,然后是开发方与客户的联合检查。检查针对的目标就是确保需求说明的几种特性:正确性、完整性、一致性、可测试性、现实性等。

73 分析阶段的注意事项 标识实体对象时,要考虑到分析模型处于不断变化中,不必花费太多时间来处理对象或其属性的细节。如果它们是显而易见的,应该记录下来,否则,对每个对象进行试验性的命名和简短描述即可。然而,一旦分析模型稳定下来,每个对象的描述就应该尽可能详细。

74 分析阶段的注意事项 标识边界对象时,是对用户界面的粗略建模,它并不详细描述用户界面的可见方面,那些工作应放在用户模型去做。用户界面的设计将不断演化,甚至在系统的功能性说明稳定下来以后仍会变。如果分析模型和界面的可视部分的变动互相影响,将耗费很多时间在它们间做协调。

75 分析阶段的注意事项 控制对象通常在现实世界没有具体的对应部分。控制对象通常在一个用例的开始被创建,当用例终止时它就不复存在。若很难确定一个控制对象活动的开始和结束,则表明对应的用例可能没有一个定义明确的入口和出口条件。

76 分析阶段的注意事项 注意实体类与属性的差异:
类的属性和独立的实体类有所不同。但是,客观地讲,它们之间的界限并不十分清晰。在以下两种情况下,通常将特定客体(信息)建模为独立的实体类: 客体具有比较复杂的自身行为; 客体具有独立标识(Identification),有可能被多类对象共享或传递。 相反,在以下情形,通常将特定客体建模为类的属性: 客体除了非常简单的取/赋值操作(set,get等),不具备更多其他行为; 客体不需要独立标识,仅供一类对象使用。

77 分析阶段的注意事项 有些时候,建模形式的选择不容易一步到位。例如,在分析和设计的演进过程中,如果发现之前定义的实体类A几乎没有行为并且仅仅被另外一个类B使用,那么可以将类A转换成类B的一项属性a。相反地,如果类X的某个属性y越来越显现出复杂的行为特征,则可以考虑将该属性建模为一个独立的实体类Y。

78 分析阶段的注意事项 当模型逐渐清晰时,应检查各“分析类”间的关系: 这些是试图减少关系的数量、降低复杂性的手段,但是要注意:
把一对多、多对多的复杂关系尽量变为受限的一对一关系; 把“分析类”体现的概念组成层次,即从特殊到一般的“归纳”,即泛化。 这些是试图减少关系的数量、降低复杂性的手段,但是要注意:

79 分析阶段的注意事项 泛化(generalization)不等同于继承;
继承是一种复用(即重用)属性和行为的机制,即使继承的类之间不存在归纳关系,比如,把散列表类改进成集合类的这种“继承”; 在分析中仅仅关注把概念组织成泛化关系,而不能用复用的形式来解释。继承层次结构将在对象设计中重新构建,虽然它最初是从归纳关系中衍生出来的。

80 分析总结 需求活动是高度循环和渐进的: 从功能模型(Use Case)向动态模型(交互图组、状态图)过渡的过程中,既可能发现遗漏的对象,又可能因此而充实、扩充用例; 从动态模型向静态模型(对象图、类图)过渡的过程中也可能发现需要修改用例的地方; 检查模型的阶段当然也存在修改用例的可能性; 并且,这些还都不包括客户方随时可能对需求做出的变动。

81 面向对象分析阶段活动总结 软件工程 第十章 面向对象(2)

82 分析总结 一旦模型到达大多数修改都是修饰性的程度,即模型进入稳定期,就应考虑进行系统设计了;
何时由分析进入下一阶段,是一个“度”的把握。若没有更多的信息使你能发现模型存在有问题或需要进行改动,就可以往下走。让每个细节都正确代价会很高,经过下一次变更,其中的一些细节会变得无关紧要。


Download ppt "第十章 面向对象 (2)."

Similar presentations


Ads by Google