软件工程第五章 面向对象分析与设计.ppt

上传人:explodesoak291 文档编号:389406 上传时间:2018-10-14 格式:PPT 页数:147 大小:796.50KB
下载 相关 举报
软件工程第五章 面向对象分析与设计.ppt_第1页
第1页 / 共147页
软件工程第五章 面向对象分析与设计.ppt_第2页
第2页 / 共147页
软件工程第五章 面向对象分析与设计.ppt_第3页
第3页 / 共147页
软件工程第五章 面向对象分析与设计.ppt_第4页
第4页 / 共147页
软件工程第五章 面向对象分析与设计.ppt_第5页
第5页 / 共147页
亲,该文档总共147页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

1、软件工程,1,软件工程 第五章 面向对象分析与设计,5.1 需求获取 5.2 面向对象分析 5.3 面向对象设计 5.4 系统设计 5.5 对象设计,软件工程,2,5.1 需求获取,需求获取的目标是确定用户“需要”什么样的软件产品,就是说,新的软件必须能够做什么。 没有专业的系统分析人员,用户很难了解到需要开发什么相关信息和功能;另一方面,没有与用户的交流,系统分析人员也很难弄清客户真正需要什么。 发现用户需求的过程称为需求获取。一旦提出了最初的需求,进一步推敲、细化和扩充的过程称为分析。,软件工程,3,需求获取的第一步是理解应用领域,即目标软件的应用环境。如银行、电信公司、书店等。 一旦系统

2、分析人员对该领域有了充分了解,就可以建立一个业务模型,描述用户的业务过程,确定用户的初始需求。然后通过迭代,更深入了解应用领域,回过头来推敲业务模型。 这种迭代过程直到双方对需求的理解达到共识。 需求获取的结果是导出用户可理解的系统规格说明。,软件工程,4,开发用户需求的典型过程,软件工程,5,5.1.1 与用户交互,1) 需求的来源 不同类型应用能从人员处获取需求的比例:,软件工程,6,所谓限制,是指受客观物理规律的限制。如导弹制导系统更多地受物理运动定律的限制,而非人的决策。视频游戏的大部分需求依赖人,因为它是一个相像出来的产品。 应用受到的限制越少,能从人们那里获得的需求比例越大。 2)

3、 识别利益相关者(stakeholder) 对项目承担风险和享有利益的人即为利益相关者。他们是应用的“客户”。如公司高层、项目经理、最终用户、系统开发人员等。,软件工程,7,不同利益相关者之间的利益冲突会导致需求不一致。如果需求冲突不能调和,项目就会陷入困境,最后往往会被取消。 即使所有利益相关者的需求一致,也可能由于实现代价高昂,需求不能得到完全满足。 3) 了解客户的需求 一般客户希望得到一个产品,他们需要系统开发人员帮助,明确自己的需要。 例如,有一个客户愿望框架:“Encounter是一个角色扮演游戏,它能模拟被扮演人物的全部或部分活动,应对人们具有相当吸引力。”,软件工程,8,完整的

4、客户要求应当记录在需求文档的“概述”部分。但需求中还有一些问题需要由系统分析人员与客户商量,以明确这些需求。 例如游戏是否只允许玩家扮演一个角色还是可以同时控制多个人物?当两个人相遇时会发生什么事情?游戏是否可以联网对战等。 4) 访谈和文档记录 大部分需求获取是人与人沟通的活动,这些活动经过精心组织,以准确获得最好的效果。 准备和访谈客户的过程如下:,软件工程,9,访谈之前 列出访谈的“客户”对象,并划分客户优先级 最有可能决定项目成败的人 安排访谈日程,设定开始和结束时间 系统开发人员至少有两人参加访谈 准备录音设备 访谈中 注意倾听 不要处于被动状态:启发和鼓励 理解客户的需要并探索要求

5、 采用用例?或数据流图?状态图?,软件工程,10,记录全部访谈内容 安排补充会议 访谈之后 根据标准模版撰写软件需求规格说明(SRS),打客户需求草稿 通过电子邮件征求客户意见对于不同类型的应用,用例方法是一种获取和表达需求的有效方法。 某些需求需要通过数据流图或状态图与用户沟通。,软件工程,11,5.1.2 描述客户需求,需求可以看成是应用与应用的外部代理(如用户)之间的交互。可利用用例作为表达工具。 用例描述了系统外的参与者(Actor)与应用之间的交互情况。主要注重用户对系统的看法。 描述客户需求的过程如下: 1) 标识参与者 标识目标系统将支持的不同类型的用户,可以是人、事件或其他系统

6、。 2) 标识场景 用场景描述目标系统典型功能的活动细节,并与用户沟通,加深开发人员对应用领域的理解。,软件工程,12,3) 标识用例 当双方确定了一组场景后,开发人员从该场景抽象出一组用例,描述所有可能的情况。用力表达了系统的范围。 4) 求精用例 细化每一个用例。引入带有出错处理或带有异常处理的用例,描述系统的行为,保证需求的描述是完全的。 5) 标识用例之间的关系 描述用例之间的依赖关系,提取相同功能,建立用例模型。 6) 标识非功能需求 包括系统性能上的约束、文档、使用资源、安全性和质量等需求。,软件工程,13,需求获取期间,开发人员需要访问一些不同的信息资源: 客户提供的与应用领域相

7、关的文档和手册。 将被目标系统替代的遗留系统的技术文档。 最终用户和客户本人。 以“图书管理系统”为例,首先标识参与者: Librarian 图书管理员:创建、修改、删除借阅者信息;添加、编辑、删除馆藏图书信息;添加、编辑、删除流通图书信息。 Borrower 借阅者:借阅、预约、归还流通图书,以及取消图书预约。,软件工程,14,流通图书(Book)是指某种馆藏图书(Title)的某一流通中的复本。例如“数学分析教程第二册”的 5 本馆藏复本中的第 3 本。 识别用例: BorrowBook:借阅流通图书 ReturnBook:返还流通图书 RecerveTitle:预约某种馆藏图书 Canc

8、elReservation:取消预约 MaintainBorrowerInfo:维护借阅者信息,包括创建、修改、取消借阅者账户 MaintainTitleInfo:维护馆藏图书信息,包,软件工程,15,括添加、修改、删除馆藏图书信息 MaintainBookInfo:维护流通图书信息,包括添加、修改、删除流通图书信息 Login:登录 识别参与者与用例之间的关系(场景) Borrower执行BorrowBook、ReturnBook、ReserveTitle、CancelReservation等用例。 Borrower是通过Librarian完成上述用例的工作。则Borrower与Librar

9、ian存在依赖关系。 Librarian还与MaintainBorrowerInfo、Main- tainTitleInfo、 MaintainBookInfo交互。,软件工程,16,Librarian还需要与用例Login交互。 画出用例图,软件工程,17,用例BorrowBook的规格说明 1.1 前置条件:在此用例开始之前,Librarian必须登录到系统中。,Librarian,Login,MaintainTitleInfo,MaintainBookInfo,MaintainBorrowerInfo,软件工程,18,1.2 后置条件:如果此用例执行成功,在系统中建立并存储一条借阅记录,

10、必须时需要删除预约记录。如果执行不成功,系统状态不变。 1.3 事件流 基本流 当Borrower借阅馆藏图书,且Librarian选择“借书”,则此用例启动。 提供馆藏图书和借阅者信息。 检索馆藏图书(E-1)。 确定该馆藏图书的物理复本(流通图书)是否在架(E-2)。,软件工程,19,检索借阅者(E-3)。 将流通图书交给借阅者。 创建并存储借阅记录。 删除预约记录。 候补流 E-1:若该种图书不存在,系统显示提示信息,用例终止。 E-2:若该种图书都已解出,系统显示提示信息,用例终止。 E-3:系统中不存在该借阅者,系统显示提示信息,用例终止。,软件工程,20,5.1.3 与用户沟通的其

11、他工具,1) 数据流图 某些需求可以很自然地表述为处理元素之间的数据流。 顶层图即为系统与外部实体的交互。 2) 状态图 有时把应用看作是几个状态下的应用,而在某一确定时刻的应用始终明确地处于某个状态中。这种状态划分对理解系统比较有益。 状态的具体内容到实现阶段会有确切的定义。,软件工程,21,借书过程的数据流图,外部实体、数据流和数据存储都为候选对象,软件工程,22,还书过程的数据流图,系统与外部实体、系统与数据存储的交互,构成系统的接口。相应数据流构成接口数据。,检验错误,还书信息,图书,软件工程,23,馆藏图书(对象)的状态图,软件工程,24,图书管理员借书操作的状态图,软件工程,25,

12、5.1.4 草拟用户界面和其他接口,建立初始用户界面,是原型方法的一种,目的是快速与客户沟通。 客户通常在看到应用的图形用户界面(GUI)才能相像到这个应用未来的样子。 开发用户界面的步骤如下: 1) 了解客户 深入了解最终用户的想法。根据用户的层次,提供多种用户界面。 知识和经验层次:计算机素养、系统经验、使用类似应用的经验、教育水平、阅读水平、打字技能等。,软件工程,26,用户的生理特征:年龄、性别、左右手习惯、生理障碍等。 2) 理解业务功能 根据应用的整体意图来理解特定用户界面的目的。功能界面出现的顺序通常可以反映用户处理日常业务的方式。 用户的任务和工作特征:应用的使用方式、使用频率

13、、雇员的流动率、任务的重要性、任务的重复性、对培训的期望、工作类型等。 用户的心理特征:工作态度、能动性、认知方式等。,软件工程,27,3) 理解优秀界面设计的原则 目的是加强视觉效果。 确保应用的各个界面之间风格的一致性:习惯、步骤、视觉和感觉、位置等。 揣测用户通常开始操作的地点 导航系统尽量简捷 使用分组和分层来强调重要性级别 4) 选择合适的窗口类型 五类窗口: 属性窗口:展示实体的属性 对话窗口:完成特定任务或命令的信息,软件工程,28,消息窗口:提供信息 面板窗口:展示一组控件 弹出窗口:突出显示信息 5) 制作系统菜单 为用户提供一个稳定的、易于理解的使用环境,可以方便地搜寻需要

14、的选项。 提供一个主菜单 显示所有相关选择(仅局限于此) 将菜单结构与应用要完成的任务对应起来 尽量减少菜单的级数,软件工程,29,6) 选择合适的基于设备的控件 提供给用户,向系统发送指示的实际手段,包括鼠标、键盘、触摸屏、绘图板、轨迹球、麦克风等。 7) 选择合适的基于界面的控件 即出现在屏幕上的符号。用户通过这些符号向系统提出他的输入和操作意图,包括图标、按钮、复选框、单选框等。 8) 组织和安排窗口布局 多窗口的排列规则,如平铺、层叠等。 9) 选择合适的颜色 尽量保持简捷和低调。颜色需要和谐。,软件工程,30,5.2 面向对象分析,分析建模的目的是对来自客户的需求形式化。形式化可以导

15、致新的洞察和发现需求错误。 1999年NASA损失了一颗价值数亿美元的气象卫星,据调查是因为列在度量表中的控制数据出了问题。不巧的是这个缺陷在灾难发生几天之前才刚发现,如果在需求分析阶段就被识别出来就可避免损失了。 避免需求错误或遗漏的第一道防线就是把所有的需求细化,建立分析模型。,软件工程,31,分析模型由三个独立的模型构成:由用例和场景表示的功能模型;用类和对象表示的分析对象模型;由状态图和顺序图表示的动态模型。 在需求获取阶段得到的用例模型就是功能模型。据此可导出分析对象模型和动态模型。 需要注意,这些模型代表的是来自客户的概念,而非实际软件类或实际构件。如数据库、子系统、会话管理器、网

16、络等,不应出现在分析模型中,因为这些概念仅与实现相关。 分析中的类可以看作是高层抽象,在后续阶段将使用更多的细节实现。,软件工程,32,在分析对象模型中有实体对象、边界对象和控制对象等三种类型。 实体对象表示系统将跟踪的持久信息;边界对象表示参与者与系统之间的交互(接口);控制对象负责用例的实现 。可用UML提供的衍型机制,区分不同类型对象。,软件工程,33,具有两个按钮的手表的分析类,使用实体对象、边界对象和控制对象等概念对系统建模时,常常需要提供一些简单的启发式规则来指导开发人员使用这些概念,可以使用相应的类来跟踪。,软件工程,34,分析建模活动包括以下步骤。 标识实体对象 自然语言分析法

17、 利用Abbott启发式准则,将语言成分映射为模型成分。,软件工程,35,自然语言分析法主要关注用户术语。限制有 识别质量高度依赖人们的书写风格; 可能会出现许多无关词汇,或同义词。 检查每一个用例,标识候选对象 用例中的连续名词(如借阅事件); 系统需要跟踪的现实世界中的实体(如借阅记录、馆藏图书信息); 系统需要跟踪的现实世界中的活动(如紧急情况操作预案); 数据源或数据潭(如借阅者、管理员)。,软件工程,36,2) 标识边界对象 在用例图中,每一个参与者至少要与一个边界对象交互。边界对象收集来自参与者的信息,将它们转换为可用于实体对象和控制对象的表示形式。 边界对象对用户界面进行粗略的建

18、模,不涉及如菜单项、滚动条等可视方面的细节。 标识边界对象的启发式准则如下: 标识用户所需初始用例的用户界面控制; 标识用户需要键入系统的数据表格; 标识通知和系统用于响应用户的消息;,软件工程,37,当用例中有多个参与者时,根据构想的用户界面来标识参与者的行为; 不要使用边界对象对接口的可视方面建模,应使用用户原型对可视用户界面建模; 使用用户的术语来描述接口,不要使用来自设计和实现的术语。 3) 标识控制对象 控制对象负责协调实体对象和边界对象。 控制对象没有在现实世界中具体的对应物,它通常从边界对象处收集信息,并把这些信息分配给实体对象。,软件工程,38,图书管理系统中的对象,Borro

19、wer:借阅者。他们可以借阅、返还、预约和取消预约。因为名字可能重复,可用借阅证号码识别。 Title:馆藏图书。它表明某一种书,通过馆藏号码识别。 Book:流通图书。它表明某一种书的具体复本,通过馆藏号码识别。 Loan:借阅记录。同一个人关于不同图书的借阅记录是不同的。 Reservation:预约记录。,软件工程,39,图书管理系统中的边界对象,mainWindow:主窗口。有借书、还书、预约、取消预约、添加书种、修改书种、删除书种、添加借阅者、修改借阅者、删除借阅者、添加图书复本、删除图书复本等操作。 BorrowerDialog:借阅者对话框。有添加借阅者、修改借阅者、删除借阅者等

20、操作。 FindBwrDialog:弹出对话框。有根据借阅者ID号码查找借阅者的操作。 TitleDialog:馆藏图书对话框。有添加书种、修改书种、删除书种等操作。,软件工程,40,FindTDialog:弹出对话框。根据图书的馆藏号查找馆藏图书。 BorrowDialog:借书对话框。根据馆藏图书的馆藏号和借阅者信息,执行借阅动作,创建和保存借阅记录。 ReturnDialog:还书对话框根据流通图书的馆藏号和复本号,执行还书动作,删除借阅记录。 ReserveDialog:预约对话框。根据馆藏图书的馆藏号和借阅者信息,执行预约、取消预约动作。 MessageWindow:显示提示信息窗口

21、。 LoginDialog:输入用户名和密码的窗口。,软件工程,41,4) 使用顺序图将用例映射为对象 顺序图将用例与对象联系起来,直观地描述了用例(场景)行为在其参与对象之间是如何实施的。 顺序图对用例中各参与对象之间的交互序列进行建模。每一个消息从一个对象(或参与者)发送给另一个对象(或参与者)。消息的接受就触发了一个操作。 通过顺序图,将责任以操作集合的形式分配给每一个对象。如果一个对象参与到多个用例,则其操作应为这些用例共享。,软件工程,42,画顺序图的启发式准则如下: 顺序图第一栏对应激活该用例的参与者; 顺序图第二栏是边界对象; 顺序图第三栏是管理用例中其他参与对象的控制对象; 通

22、过边界对象来初始化用例,并创建控制对象; 通过控制对象可创建其他边界对象; 实体对象允许边界对象和控制对象访问; 试题对象不能访问边界对象和控制对象;,软件工程,43,借书用例的顺序图,软件工程,44,还书用例的顺序图,软件工程,45,5) 使用CRC卡片对对象之间的交互建模 CRC是类、职责和协作的缩写。每一个类可用一张CRC卡片表示。 建立CRC卡片有以下几个步骤: 识别类和职责: 首先识别类或对象,然后从客户需求说明中寻找有关行为的描述,以发现职责。 将职责分配到类 :记录在相应的卡片上。 找寻协作者:依次检查每一类承担的责任,看是否需要其他类的帮助,找寻与每个类协作的伙伴,并记录在相应

23、卡片上。,软件工程,46,软件工程,47,细化:模拟在执行每个基本功能时系统内部出现的场景,以此推动细化工作的进行。 在模拟一个场景的过程中,每当一个类开始“执行”时,它的卡片就被拿出来讨论,当“控制”传送到另一个类时,注意力就从前一张卡片转移到另一张上去了。不同的场景,包括例外和出错状况,都应逐一加以模拟。 在这个过程中可以验证已有的定义,不断发现新的类、职责以及伙伴。 在模拟不同的场景中会发现某些职责需要重新加以分配。这些都导致进一步的开发工作。,软件工程,48,6) 标识关系(结构) 使用类图,能够表示对象之间的关系。 关联表示了两个或多个类之间的关系。标识关联的启发式准则如下: 检查指

24、示状态的动词或动词短语; 准确地命名关联和角色; 尽量使用常用的修饰词标识出名字空间和关键属性; 消除可导出其他关联的关联; 在关联集合稳定之前不必关心重复性; 过多的关联使得一个模型不可读;,软件工程,49,建立系统的包图(主题) 建立包图是为了降低复杂性,目的是控制可见度及指引读者的思路。 对于面向对象分析模型,主题表示此模型的整体框架。可以是一个层次结构。 通过对主题的识别,可以让人们能够比较清晰地了解大而复杂的模型。,软件工程,50,建立边界类的类图 标明类之间的关系,包括关联、泛化等。,软件工程,51,建立实体类的类图 这些类与数据库相关,为了操作方便,以它们为子类,建立一个持久类(

25、Persistent)作为它们的父类,共享与数据库相关的操作。,软件工程,52,建立边界类与实体类之间关系的类图,软件工程,53,1,1,01,*,1,1,软件工程,54,标识属性 对象所保存的信息称为它的属性。类的属性所描述的是状态信息,每个实例的属性值表达了该实例的状态值。 标识属性的启发性准则如下: 每个对象至少需包含一个属性; 属性取值必需适合对象类的所有实例; 出现在泛化关系中的对象所继承的属性必须与泛化关系一致; 系统的所有存储数据必须定义为属性;,软件工程,55,对象的导出属性应当略去。例如,“年龄”是由属性“出生年月”导出,它不能作为基本属性存在。 8) 对每一对象的与状态有关

26、的行为建模 对象收到消息后所能执行的操作称为它可提供的服务。 对每个类的增加、修改、删除、选择等服务有时是隐含的,在图中不标出,但实现类和对象时有定义。 其它服务则必须显式地在图中画出。 首先标识在每个类中封装的服务;,软件工程,56,再比较服务与类的属性,验证其一致性。所标识的类属性,它必然关联到某个服务,否则该属性就形同虚设,永远不可能被访问; 画出对象之间的消息通信路径,协调系统的行为。 自底向上方法:找出每一对象在其生存周期中的所有状态。每一状态的改变都关联到对象之间消息的传递。从对象着手,逐渐向上分析。 自顶向下方法:一个对象必须识别系统中发生或出现的事件,产生发送给其他对象,软件工

27、程,57,的消息,由那些对象作出响应。所以对象应具有能够接收、处理、产生每个消息的服务。它是从系统行为着手,然后逐渐分析到对象。 使用顺序图或协作图,标识和描述对象之间的相互通信,并进行运行走查。 10) 分析模型评审 有关模型正确性的问题: 对实体对象的分类,用户是否能够理解? 抽象类是否对应到用户层的定义? 是否所有的描述均符合用户的定义?,软件工程,58,是否所有的实体对象和边界对象都使用了有实际含义的名词短语进行了命名? 是否所有的用例和控制对象都使用了有意义的动词短语进行了命名? 是否所有的错误用例都已经描述和处理? 有关模型完备性的问题: 每一个对象是否有用例用到它?创建、修改或删

28、除该对象的用例是哪些? 每一个属性的类型是什么?它应进行修饰吗? 每一个关联何时被用到?其重复性的选择原则是什么?该关联使用那一种连接?,软件工程,59,每一个控制对象是否具有必要的关联,以连接到用例中相关的其他对象? 有关模型一致性的问题: 是否有多个类或多个用例同名? 名字相近的实体(如类、对象、属性)能够相互区别吗? 在同一泛化层次是否存在相似属性和关联的对象? 有关模型可实现性的问题: 在该系统中性能需求和可靠性需求是否满足? 在选定硬件上运行原型是否可以确定需求?,软件工程,60,5.3 面向对象的设计,面向对象设计分两个阶段进行:系统设计和对象设计。 系统设计的主要活动是: 标识系

29、统目标:标识并区分各种质量属性的优先实现次序。 子系统分解:根据用例和分析模型,将系统分解为一系列子系统。 子系统细化:对各子系统不断分解求精,直到所有的设计目标都能满足为止。,软件工程,61,对象设计主要是追加一些与实现有关的对象,以及对已有对象进行细化。设计原则1:分治 软件系统分解为子系统 分布式系统可以分解为客户机和服务器; 系统可以分解为一系列子系统; 子系统可以分解为一个或多个包; 包可以分解为类;,创建良好设计的原则,软件工程,62,类可以分解为方法。 设计原则2:尽可能增加内聚 不同内聚类型:优先级从高到低排序 1) 功能内聚:构件只执行单一计算并返回结果,没有副作用。如函数过

30、程。 2) 层内聚:相关服务放在一起,并有严格的层次结构,高层服务可访问低层服务,反之不可。如分层结构。 3) 通信内聚:访问或操作同一数据的过程放在一个类中,这些过程可以互相通信。如某个,软件工程,63,类设计。 顺序内聚:存在一系列过程,其中一个过程向另一个过程提供输入,这些过程放在一起,形成顺序内聚。如消息序列。 5) 过程内聚:几个一次调用的过程放在一起,形成过程内聚。如调用结构。 时间内聚:程序执行过程中同一阶段内完成的操作放在一起,达到时间内聚。 实用程序内聚:逻辑上不能纳入其他内聚类型的相关实用程序放在一起,形成实用程序内聚。如可复用的过程或类。,软件工程,64,设计原则3:尽可

31、能降低耦合 模块间存在相互依赖关系即为耦合。不同耦合类型从高向低排列有: 内容耦合:一个构件修改另一个构件内部的数据,应始终避免。 公共耦合:一组构件使用全局数据,就产生公共耦合。应通过封装降低公共耦合。 控制耦合:一个过程通过标志、开关或命令显式地控制另一个过程的动作,就产生控制耦合。降低的方法是采用多态操作。,软件工程,65,标记耦合:在一个操作的参数表中将类作为参数,就产生标记耦合。可以改用传递简单变量或使用接口做参数降低耦合。 数据耦合:在一个操作的参数表中用简单变量或简单的类(如string)作为参数,就产生数据耦合。应通过减少参数个数降低耦合。 例程调用耦合:一个例程(或类操作)调

32、用另一个例程,就产生例程调用耦合。如果出现例程调用序列,降低的方法是编写一个例程将这个调用序列封装起来。,软件工程,66,类型使用耦合:类将实例变量或本地变量声明为另一个类的实例,就产生类型(嵌套)使用耦合。可将变量的类型声明为包含所需操作的最通用的类或接口。 包含/引入耦合:一个构件引入(import)一个包时就产生引入耦合,一个构件包含(include)另一个构件时,就产生包含耦合。 外部耦合:模块对外部系统,如操作系统、共享库或硬件有依赖关系时就产生外部耦合。可通过信息隐蔽减少这种依赖关系。,软件工程,67,设计原则4:尽可能提高抽象层次 设计应隐藏或推迟考虑细节以降低复杂性。 类是包含

33、过程抽象的数据抽象。 使用泛化关系(父类)和接口,可进一步提高抽象层次。 类中公有操作越少,抽象程度越高。 类中所有变量都是私有的,抽象程度达到最高。 抽象可确保在设计时不必关心不必要的细节,能把握问题的本质并做出重要的决策。,软件工程,68,设计原则5:尽可能提高可复用性 可以在算法、类、过程、框架和完整应用程序的级别上创建可复用性。 复用构件的机制包括过程调用和继承父类。设计原则6:尽可能复用已有的设计和代码 复用已有的设计是对可复用性设计的补充。通过复用可从以往对可复用构件的投资中获益。设计原则7:灵活性设计 积极预测将来可能在实现和功能上的变化,并,软件工程,69,采取相应措施。 在设

34、计中引入灵活性的方法有: 降低耦合并提高内聚(易于提高替换能力) 建立抽象(创建有多态操作的接口和父类) 不要将代码写死(消除代码中的常数) 抛出异常(由操作的调用者处理异常) 使用并创建可复用的代码设计原则8:预计过期 积极预测将来可能在技术和运行环境上的变化,并为此采取相应措施。,软件工程,70,在设计中应遵循的预计过期的规则有: 避免使用早期发布的技术 避免使用针对特定环境的软件库 避免使用软件库中未编档的或很少使用的功能 避免使用小公司或可能不提供长期支持的公司提供的可复用构件或特殊硬件 使用众多厂商支持的标准语言和技术设计原则9:可移植性设计 可移植性设计的主要目标是让软件在尽可能多

35、,软件工程,71,的平台上运行。实现可移植性的规则有: 避免使用特定环境的专有功能 使用不依赖特定平台的程序设计语言 小心使用可能依赖某一平台的类库 了解其他语言可能依赖特殊硬件结构的功能和文本文件的差异设计原则10:可测试性设计 设计时采取措施使得测试易于进行。 可测试性设计的最重要的方法是保证代码的所有功能都能脱离图形用户界面执行。,软件工程,72,设计原则11:防御性设计 为提高可靠性,应确保不引入任何缺陷,能够处理其他代码不适当使用构件引起的问题。 按契约设计是防御性设计技术,其核心思想: 被调用操作为正常执行必须满足的前置条件(precondition):调用操作在调用一个操作时有责

36、任确保该操作的前置条件成立。 被调用操作正常执行所得到的结果即为后置条件 (postcongdition):要求被调用操作在返回前有责任保证这些后置条件成立。,软件工程,73,被调用操作在执行时确保不会被修改的不变量(invariant)。 前置条件、后置条件和不变式都是布尔表达式,其计算结果为假,表示有错误发生。 可以使用断言机制。在重要构件的边界(如层)应始终保留严格的断言检测。,软件工程,74,系统设计的主要活动是进行子系统分解,并在此基础上定义子系统构件之间的接口。 为此,首先根据子系统可提供的服务来定义子系统(以后在对象设计中再根据子系统能提供的操作来定义子系统的接口),然后对子系统

37、细化,建立层次结构。要求对子系统的分解尽可能做到高内聚、低耦合。5.4.1 系统设计的概念,5.4 系统设计,软件工程,75,1) 子系统和类 在应用领域,为降低其复杂性,用类进行标识。在解答空间,为降低其复杂性,将系统分解为多个子系统,这些子系统又由若干表示解答空间的类构成。 还可以把子系统分解为更小的子系统。,软件工程,76,在Java和Module 2中显式地提供了子系统的构造。在Java中采用了“包”,在Modula 2中采用了“模块”。C+没有显式地提供子系统的构造,可按问题需要对类分组。 2) 服务和子系统接口 一个服务是一组有公共目的的相关操作。而子系统的特征是由该子系统提供给其

38、他子系统的服务来刻画。 供其他子系统调用的某个子系统的操作集合就是子系统的接口。子系统的接口包括操作名、操作参数类型及返回值。,软件工程,77,系统设计注重每个子系统提供服务的定义,即枚举所有的操作、操作参数和行为。 当编写子系统接口的文档时,不应涉及子系统实现的细节,其目的是减少子系统之间的依赖性,希望一旦需要修改子系统实现时,降低由于子系统变更而造成的影响。 3) 子系统分层和划分 子系统分层的目的是建立系统的层次结构。每一层仅依赖于它下一层提供的服务,而对它的上一层可以一无所知。 如图,是一个三层的系统结构。,软件工程,78,在层次结构中,子系统A、B、E构成了一个称之为垂直切片的系统分

39、解子集。而D、G则不能。 如果每一层只能访问与其相邻的下一层,则称之为封闭体系结构;如果每一层还可访问,软件工程,79,比其相邻下一层更低的层次,则称之为开放体系结构。 封闭体系结构的例子就是开放系统互联参考模型(OSI模型),它由七层构成。每一层负责执行一个已预先定义好的协议功能。每一层都为其上一层提供服务,使用其低层的服务。,软件工程,80,封闭体系结构的子系统之间满足低耦合,但产生速度和存储管理的问题,会导致某些非功能属性难以满足。 开放体系结构的一个例子是Java的Swing用户接口包。它允许人们绕过高层直接访问低层接口以克服性能瓶颈。,软件工程,81,划分是将系统分解为独立的子系统,

40、每个子系统负责某一类服务。 例如,一个车辆管理所的管理信息系统分为车管所组织机构管理、车辆管理、车主管理和法律事件管理等 4 个子系统。每一个子系统对其他子系统的依赖度很低。 分解子系统时,首先进行划分,将一个系统分成几个高层的子系统,每个子系统负责一种功能,或运行在某特定的硬件节点上。再将各子系统分层处理,分解成层次更低的小子系统。 过度分解会导致子系统之间接口的复杂化。,软件工程,82,5.4.2 系统设计的目标,明确设计目标,是系统设计的第一步。 有一些设计目标是从用户那里得到,更多的设计目标是从非功能需求或应用领域中抽取出来。 设计目标可以从以下 5 组设计准则中选择。其中性能、可靠性

41、和最终用户准则往往从需求中明确地获取,也可以从应用领域中获取;而成本和维护准则由客户和供应商提出。 将设计目标清楚地陈述,可以根据设计准则,做出重要的设计决策。,软件工程,83,性能准则,可靠性准则,软件工程,84,成本准则,最终用户准则,软件工程,85,维护准则,软件工程,86,在定义设计目标时,希望开发一个既安全可靠,又廉价的系统是不现实的,因此开发人员应当对所有可能的设计目标进行权衡,对必须的设计目标赋予优先级别。 一旦有了清晰的设计目标,就可以开始系统的初始分解。,软件工程,87,软件工程,88,5.4.3 子系统分解,软件体系结构设计的第一步是做子系统分解,从而搭建软件体系结构的架构

42、。 在系统设计中寻找子系统,与在分析过程中寻找对象的情况类似。在面向对象分析中介绍的Abbotts启发式准则,同样适合于子系统的识别。 初始子系统应该从需求的功能模型(用例模型)中导出。这方面有多种分解方案。 例如,Coad & Yourdon基于MVC模型,将系统大致分为问题领域、人机交互、任务管理、数据管理等 4 个子系统。,软件工程,89,5.4.4 问题领域子系统,首先复制分析模型为设计模型中的问题领域部分,然后根据设计目标,对该部分进行修改。 可复用的设计编程方面的类 根据需要,从类库选择可复用类、商业外购构件和遗留构件,把它们增加到问题解决方案中去。 标明复用类或构件中不需要的属性

43、和操作。 增加从复用类(构件)到分析类之间的泛化关系,继承复用类(构件)的属性和方法。,软件工程,90,把分析类中因继承复用类(构件)而成为多余的属性和操作标出。 修改分析类的结构和连接。 加入泛化类以建立类间协议 有时某些分析类要求一组类似的服务。此时,以这些分析类作为子类,定义一个父类。该父类定义为所有这些子类共用的一组服务名,作为公共的协议,用来与数据管理或其他外部系统部件通信。这些服务都是虚函数。在各个子类中定义其实现。 对泛化关系进行调整,软件工程,91,在分析模型中可能包括有多继承关系,但实现时使用的程序设计语言可能只有单继承,甚至没有继承机制,这样就需变更问题领域部分中类的层次结

44、构。 针对单继承语言的调整 把子类对象看做是父类对象所扮演的角色,通过关联关系把多继承的层次结构转换为单继承的层次结构。 把多继承的层次结构平铺,成为单继承的层次结构。在这种情况下,有些属性或操作在同层的子类中会重复出现。,软件工程,92,针对无继承语言的调整 当使用无继承的编程语言时,必须把具有泛化关系的类层次平铺开,成为一组对象。,多继承关系,通过关联关系 分解多继承,平铺为单继承,软件工程,93,修改设计以提高性能 提高执行效率是系统设计的主要目标之一。有时必须改变问题领域的结构以提高效率。 如果类之间经常需要传送大量消息,可合并相关的类,使得通信成为对象内的通信,而不是对象之间的通信,

45、或者使用全局数据作用域,打破封装的原则,以减少消息传递引起的速度损失。 增加某些属性到原来的类中,或增加低层的类,以保存暂时结果,避免每次都要重复计算造成速度损失。,软件工程,94,为提高性能,在对分析模型进行大规模的改动之前,应考虑下面一些问题: 不要认为象C+之类的OOPL就一定效率不高。事实表明,非OOPL的紧凑代码的效率比OOPL的效率高近10倍,但用非OOPL编程会令程序员非常疲劳,容易出错。 提高一个现存系统的工作效率比重新设计一个高效的系统要容易。一开始应当建立一个原始的简单的设计,实现和调试不会太困难。如果对设计有性能要求,只需加入少量的工作就可以了。,软件工程,95,通常系统

46、80%的开销都集中在20%的代码段上。与其为了尽量处处节省系统开销而破坏完善的系统结构,还不如找出系统开销最集中的地方,只对那部分做优化。 预测软件开销集中在什么地 方是困难的。 进行优化最有效的方法是在系统运行时使用性能监测工具对系统进行观测。一些像继承、动态绑定、消息传递等处理虽然看起来简单,但需要大量的系统开销。在代码复杂性与运行的低效之间没有相关性。 提高性能最好的方法是采用好的解决方案,而不是拼命地去节省几个微秒、几个字节。,软件工程,96,电梯控制系统ECS的问题领域子系统,决定使用一个中央控制器(电梯控制器)控制和协调电梯的所有动作,包括解决电梯每到一个楼层减速问题。 增加“电梯

47、监视器”,用一个独立的对象来执行监测功能(性能、安全性等)。在提交给实现者的规格说明中,将这个类放在一个 与ECS的主处理器分离的处理器上. 每个类增加服务Self Test来增强每个类的性能。在运行时执行有必要验证其功能的操作,并向电梯监视器报告。,软件工程,97,软件工程,98,5.4.5 人机交互子系统,设计一个良好的用户界面是成功地实现一个软件系统的关键。在开发分析模型时,有意避开了如窗口、屏幕等依赖于实现的细节,目的是让系统规格说明独立于实现。 而人机交互子系统在系统行为和用户交互的实现之间架起了一座桥梁。 例如,可用 GUI 实现系统的用户界面。但当用户提出来改用语音对答式交互时,

48、应当使这种改变尽可能容易。为此,只需将 GUI 式人机交互子系统替换成语音对答式人机交互子系统即可,系统其它部分都应保持不变。,*,软件工程,99,例如,某杂志发行系统SBSS的人机接口,设计用户界面 SBSS的用户界面是一个传统的GUI。其中有许多窗口对象。但在用户与系统进行交互期间,只能有一个窗口呈现在用户面前。 通过使用聚合关系,窗口对象可以进一步分解为各种文本域、选择按钮、图符等。 如果使用某种 GUI 构筑软件包,只需对软件包输入合适的参数,该软件包就能提供所有的文本域、选择按钮、图符等,将这些细节作为窗口的属性就可以了。,软件工程,100,软件工程,101,只要描述清楚所需要的窗口

49、,这些窗口的导航细节,详细的窗口成分,我们就可以用现有的技术和工具来实现它们。 其他描述人机交互模型的工具 在描述复杂的菜单系统(GUI窗口)的拓扑结构时,常使用状态图或菜单树。 用于SBSS的单层状态图: 每一个状态是GUI的一个窗口 每一个迁移代表了窗口之间的切换 与每个迁移相关联的是一个条件 / 动作对 条件代表了用户选择,它导致迁移的发生 动作代表了迁移发生时产生的请求,软件工程,102,软件工程,103,菜单树可以让用户直观地看到如何在界面上巡航。用菜单树表示人机交互的基本结构,有助于全局用户界面的可视化。例如,可以了解有多少种不同的方式能够访问“地址”的窗口。 用户界面可尽量采用清

50、真寺式的结构:在界面的上层,希望扇出大于扇入,表明用户可以有多个可供选择的选项。在界面的低层,希望扇入大于扇出,表明一个单独的界面可以被多个双亲使用。,软件工程,104,软件工程,105,人机交互子系统的设计过程 1) 用户分类 按技能层次分类:外行初学者熟练者专家 按组织层次分类:行政人员管理人员专业技术人员其它办事员 按职能分类:客户职员 描述人及其任务的脚本对以上定义的每一类用户,列出对以下问题做出的考虑:谁、目的、特点、成功的关键因素、熟,软件工程,106,练程度以及任务脚本。在OOATOOLTM 中有一个例子: 谁:分析员 目的:要求一个工具来辅助分析工作 (摆脱繁重的画图和检查图的工作)。 特点:年龄: 42岁;教育水平: 大学;限制:不要微型打印,小于9个点的打印太小。 成功的关键因素:工具应能使分析工作顺利进行;工具不应与分析工作冲突;工具应能捕获假设和思想,能适时做出折衷;应能及时给出模型各个部分的文档。,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 教学课件 > 大学教育

copyright@ 2008-2019 麦多课文库(www.mydoc123.com)网站版权所有
备案/许可证编号:苏ICP备17064731号-1