1用例驱动的面向对象分析与设计用例建模:建立用户的需求模型,由用例图体现具体过程:定义系统、确定参与者、确定用例、描述用例、确定用例之间的关系、评审用例模型对象建模建立系统的分析模型,由类图体现具体过程:理解用例、识别类和类的属性、识别类的操作、确定类与类之间的关系、评审模型2UML的构成4种事物4种关系9种图3UML的构成——关系关联泛化依赖实现聚合组合UML图用例图协作图构件图部署图对象图状态图顺序图类图活动图模型动态行为功能静态结构物理架构5第十次课面向对象设计(第十章)6内容提纲回答两个问题:1)对于大型系统如何进行设计?2)概要设计完了之后,系统的详细设计做什么?3)在确定类与类之间关系的过程中,有没有更好的指导方法?概要设计:包括如何把整个系统分解为子系统、子系统的软硬布局等策略性决策详细设计:根据具体的实现策略,对分析模型进行扩充,包括了对象设计和对象持久化设计设计评审:对所设计的系统和系统设计规格说明报告逐一进行严格审查,检查是否达到系统设计功能要求系统设计一般包括:概要设计主要是对系统的体系结构进行设计系统体系结构也称为系统架构,是指一个或一组结构,它包含组成系统的软件元素、这些元素对外可见的性质以及它们之间的关系概要设计系统架构是最高层次的系统分解,包括软件体系结构设计和硬件体系结构设计两部分;软件系统体系结构设计通过系统的层、包、主要框架、类、接口和子系统的组织方式来描述;硬件系统体系结构设计描述了进程分配和网络配置。体系结构设计的两部分体系结构设计的常见策略:分层在分解复杂的信息系统时,用的最多的技术之一就是分层;在采用分层架构时,下层组件负责对上层组件提供服务,上层组件可以使用下层组件定义的服务,但下层组件对上层组件一无所知;层与层之间通常是不透明的,每一层都具有独立的职责。分层结构描述的是设计元素在概念上的组织,是一种逻辑结构,而非物理上的部署,对于不同的层,可以部署到不同的机器上,也可以部署到同一机器上。在信息系统中软件架构通常采用典型的三层结构:表示层――用户界面业务层――业务处理流程数据层――持久化存储数据层在业务层中是可见的,业务层在表示层中是可见的,反之则不可见三层架构职责的分离业务逻辑块业务逻辑块业务逻辑块数据数据表现层业务逻辑层数据层职责分离三层架构以上三层是基本的层次结构,具体如何分离取决于问题的复杂程度;必须遵守一条关于层间依赖的普遍原则:业务逻辑层和数据存储层绝对不要依赖于表现层;当业务逻辑变得越来越复杂时,可以根据系统的实际情况或设计需求,进行进一步的分解,基本的三层结构可以扩展为四层、五层或更多。四层架构Web层:表现层,完成人机交互BLL层:业务逻辑层DAL层:实现数据库相关的所有操作Model层:用于向Web层、BLL层、DAL层提供数据模型支持14包(package)是一种逻辑分组手段,可以取UML模型中的任何一种事物,将相关成分聚在一起,以构成更高层的组织单元最常用的方法是将类以包为单位进行分组,比如三层结构中的每一层中的所有类组成一个包一个包可以包含其它的包,高层包被分成若干子包,子包又可以分成更小的包软件体系结构的建模工具:包包图包图用来描述包及其依赖关系,用来标识一个完整系统的主要部分在包图中只使用两个符号:一个包的标识符,一个虚线箭头,虚线箭头表示依赖关系,箭头的尾部表示被依赖的包,头部是独立的包。包依赖关系可以是直接的,也可以间接的,依赖关系可以传递;每层对应一个包:用户界面包、业务处理包、数据访问包,再把各层中的一些公共部分提出来:权限管理包、异常处理包权限管理错误处理数据访问业务处理用户界面三层架构的包图用户界面输入、输出数据校验发送业务处理请求用户界面包业务处理包业务处理实现各种业务逻辑或处理算法权限管理数据访问包数据访问实现数据的持久化操作实现事务处理权限管理验证请求者的请求权限提供请求者的权限列表权限管理包异常处理包异常处理汇报运行时的详细异常信息记录异常处理日志指出系统中的类和对象涉及的具体程序或进程。指明系统中配置的计算机和其他硬件设备。指明系统中各种计算机和硬件设备如何进行相互连接。明确不同代码文件之间的相互依赖关系。硬件体系结构设计硬件体系结构设计:部署图并不是所有的系统都需要建立配置图,一个单机系统只需建立包图或构件图26内容提纲回答两个问题:1)对于大型系统如何进行设计?2)概要设计完了之后,系统的详细设计做什么?3)在确定类与类之间关系的过程中,有没有更好的指导方法?主要包括对象设计和对象持久化设计(数据库设计)对象设计:概要设计相当于大楼的建筑平面图,规定了每个房间的用途,以及房间与房间之间、房间与外部环境之间的连接机制。对象设计着重于每个房间的内部细节对象持久化设计:解决对象数据的存储和检索详细设计银行内转账校验密码客户银行间转账其它银行账户管理系统账户管理系统管理员报表生成开户存款include取款include注销include银行职员转账银行储蓄账户管理系统回顾:面向对象分析开户用例描述用例名称:开户用例编号:UC-1参与者:银行职员,客户前置条件:一个合法的银行职员已登录到该系统事件流:1.银行职员在系统主页,点击开户按钮;2.系统弹出开户页面,并显示提示输入客户信息的消息;3.银行职员输入客户信息(姓名、地址、身份证号等);4.系统在开户页面显示给客户分配的账号;5.系统提示客户输入密码;6.客户输入密码;7.系统提示客户再次输入密码;8.客户再次输入密码;9.系统检测客户输入的两次密码是否一致,如果不一致则回到第4步,否则继续;10.系统在账户库中添加新账户;11.用例结束。后置条件:在账户库中增加了一个新账户,得到一张新存折分析类的识别示例用例名称:开户……事件流:1.银行职员在系统主页,点击开户按钮;2.系统弹出开户页面,并显示提示输入客户信息的消息;2.银行职员在开户页面输入客户信息(姓名、地址、身份证号等);3.系统在开户页面显示给客户分配的账号;4.系统提示客户输入密码;5.客户输入密码;6.系统再次提示客户再次输入密码;7.客户再次输入密码;8.系统检测客户输入的两次密码是否一致,如果不一致则回到第4步,否则继续;9.系统在账户库中添加新账户;10.用例结束。边界类边界类实体类控制类控制类控制类对“开户”用例分析之后所得到的系统应实现的类1.银行职员在系统主页,点击开户按钮;2.系统弹出开户页面,并显示提示输入客户信息的消息;3.银行职员在开户页面输入客户信息(姓名、地址、身份证号等);4.系统在开户页面显示给客户分配的账号;5.系统提示客户输入密码;6.客户输入密码;7.系统再次提示客户再次输入密码;8.客户再次输入密码;9.系统检测客户输入的两次密码是否一致,如果不一致则回到第5步,否则继续;10.系统在账户库中添加新账户;11.用例结束:银行职员:系统主页:开户页面:账户:账户库1:onOpenAccount()2:popPage()3:onSubmitCustInfor(姓名,地址等)8:onSubmitPass(密码)10:show(请输入密码)11:onSubmitPass(密码)4:setCustInfor(姓名、地址等)5:genAccoutNo()6:show(生成的帐号)7:show(请输入密码)9:setPass(密码)12:setPass(密码)13:check()14:addAccount()对用例“开户”进行分析之后得到的类图对属性和操作进行建模属性建模:确定属性的类型和数据结构、可见性等将所有属性的可见性设置为private仅通过set方法更新属性仅通过get方法访问属性在属性的set方法中,实现简单的有效性验证,而在独立的验证方法中实现复杂的逻辑验证操作建模:确定操作的可见性、参数、返回值、算法等设计实现服务的算法。定义内部类和内部操作详细设计:对象设计关注的是对象数据如何存储数据存储管理的一般模式文件管理模式关系数据库管理系统面向对象数据库管理系统详细设计:对象持久化设计关系数据库与面向对象中的概念存在一定的对应对象持久化设计的方法:基于关系数据库存储永久类的存储设计永久类一般都是实体类,对应的是系统中涉及的数据每一个永久类映射为一个关系表,表格的列或字段对应类的属性,而行或记录对应类的实例(对象)关联的存储设计1:1关联:在一个类对应的表中用外键隐含管理1:n关联:在n端类对应的表中用外键隐含关联n:n关联:转换成1:n管理,然后按照上面的方法进行转换基于关系数据库的对象持久化设计1:1关联1:n关联41内容提纲回答两个问题:1)对于大型系统如何进行设计?2)概要设计完了之后,系统的详细设计做什么?3)在确定类与类之间关系的过程中,有没有更好的指导方法?对用例“开户”进行分析之后得到的类图单一职责原则开放-封闭原则接口隔离原则Liskov替换原则依赖倒置原则面向对象设计原则一个类只完成某一类功能(职责)尽可能避免出现一个“复合”功能的类——在同一个类中完成多个不同的功能1、单一职责原则EmployeecalculatePay()calculateTaxes()writeToDisk()readFromDisk()createXML()parseXML()displayOnEmployeeReport()displayOnPayrollReport()EmployeeXMLEmployeeToXML()XMLToEmployee()EmployeeDBwriteEmployee()readEmployee()EmployeeReportEmployeecalculatePay()calculateTaxes()PayrollReport开放−封闭原则:软件实体类(类、模块、函数等)应该是可以扩展、但是不可修改的基本思想:不用修改原有类就能扩展一个类的行为2、开放−封闭原则什么是不封闭、不开放如下的模型可以处理月薪制和时薪制职工工资,如果还要增加一种职工类型,其计酬方式不同(如提成制),则必定要修改Employee类publicdoubleEmployee::calculatePay(){if(employeeType==SALARIED)/*calculatecode*/else/*calculatecode*/}EmployeeEmployeeTypecalculatePay()Timecard如何改进利用抽象机制封闭:Employee及其子类是封闭的开放:可以派生新的子类,实现新的需求EmployeecalculatePay()SalariedEmployeeHourlyEmployeeTimecardLiskov替换原则:子类应当可以替换父类并出现在父类能够出现的任何地方核心思想:子类型必须能够替换它们的基类型,该原则能够知道设计人员正确地进行类的继承与派生3、Liskov替换原则一个违反Liskov原则的例子正方形是长方形的一种特例RectanglesquareclassRectangle{public:voidSetWidth(doublew){itsWidth=w;}voidSetHeight(doubleh){itsHeight=h;}...private:doubleitsWidth;doubleitsHeight;}正方形有独特的行为方式通过覆盖父类的有关方法来实现子类行为RectanglesquareclassRectangle{public:virtualvoidSetWidth(doublew){itsWidth=w;}virtualvoidSetHeight(doubleh){itsHeight=h;}voidSquare::SetWidth(doublew){Rectangle::SetWidth(w);R