静态建模(类和对象建模)
类和对象模型的基本模型元素有类、对象以及它们之间的关系。系统中的类和对象模型描述了系统的静态结构,在UML中用类图和对象图来表示。
类图由系统中使用的类以及它们之间的关系组成。类之间的关系有关联、依赖、泛化、实现 等。类图是一种静态模型,它是其他图的基础。一个系统可以有多张类图,一个类也可出现在几张类图中。
什么是类
- 类图的核心组成
类:类名,属性,操作
类之间的关系:关联(聚集、组合)、依赖、泛化、实现
多样性(多重性):通常在关联、聚合、组合中使用,代表有多少个关联对象存在。使用数字...星号(数字)表示 - 类分为:
实体类 ,如学生、商品,来自需求说明中的名词;
控制类 ,如增加商品类、用户注册类;
边界类,如对话框、窗体、菜单
如何用UML表示一个类
• 名称:每个类都有一个惟一的名称,通常采用CamelCase(俗称驼峰格式,每个单词的首字母都要大写,其他均以小写字母出现。)格式表示
• 属性:是已被命名的类的特性,它描述该类实例中包含的信息
• 操作:是类所提供的服务,它可以由类的任何对象请求以影响其行为
• 属性名和操作名也通常采用CamelCase 格式表示,只不过首字母通常为小写。
UML对属性的描述
UML中,**描述一个属性的语法**如下:
- visibility~opt~ /~opt~ attribute-name ⌊ : type ⌋~opt~multiplicityopt ⌊= initial-value⌋~opt~⌊ {property-string}⌋~opt~
其中带下标opt或⌊ ⌋opt的部分表示该部分是任选的
------------------------------------------------***类属性的语法(重要)-----------------------------------------------------------
- visibility(可见性):表示该属性在哪个范围内可见(即可使用),见下表
- attribute-name:表示属性名。
- type(类型):用来指明属性值的类型
- multiplicity(重数):用来指出该属性可能的值的个数以及它们的排列次序和唯一性。值的个数写在方括号([ ])中,其形式是:[minimum...maximum]。maximum可以是" * ",表示"无限"。当值的个数是单一值(如值的个数是3)时,可写成[3...3]或简写成[3]。典型的写法有:[0...1],[1](表示[1...1]),[ * ](表示[0... * ]),[1... * ],[1...3]。当重数缺省时,隐含表示重数为1。当一个属性有多个值时,可在值的个数后面指明值元素的排列次序和唯一性,排列次序和唯一性 写在花括号({ })中,可使用的关键字如下表所示,其默认值是set ,即无序且值元素唯一 。
- initial-value(初值):在创建一个类的实例对象时,应对其属性赋值,如果类中对某属性定义了初值,那么该初值可作为创建对象时该属性的默认值。
- property-string(特征字符串):用来明确地指明该属性可能的候选值,如{红,黄,绿}指出该属性可枚举的值只能是红、黄、绿。
属性还可以定义为类属性 (class attribute) ,表示被这个类的所有实例对象共享该属性的值。类属性是这个类的名字空间中的全局变量。类属性用下划线来指明。
UML对操作的描述
- UML中描述一个操作的语法 如下:
visibilityopt operating-name(parameter-list) ⌊ : return-type ⌋opt ⌊ { property-string }⌋opt
操作可见性的含义与属性中的含义相同。
参数表是用逗号分隔的形式参数序列,描述一个参数的语法 如下:
directionopt parameter-name :type ⌊ multiplicity⌋opt ⌊ = default -value⌋opt
其中:direction(方向):用来指明参数信息流的方向
- 类也可以定义类操作(class operation)。通常操作是在该类的对象实例上被调用的,而类操作可以在没有对象实例的情况下被调用,但此时只允许访问类属性.
类之间的关系
- 对象并非遗世独立,对象间存在千丝万缕的联系
- UML中,关注以下几种类型的关系:
- 关联关系(Association)
- 聚合与组合关系(Aggregation and Composition)
- 泛化关系(Generalization)
- 依赖关系(Dependency)
- 实现关系(Realization)
- 关联关系(Association)
- 类图描述类和他们之间的关系
- 关联
关联描述了系统中对象之间或其他实例之间的连接。关联的种类主要有二元关联,多元关联,受限关联,聚集(aggregation)和组合(composition)
- (1)二元关联
- 二元关联表示为在两个类之间用一条直线连接,直线上可写上关联名
- 关联的两端可加上重数(multiplicity) ,表示该类有多少个对象可与对方的一个对象关联
- 重数
在一个类的关联端点附加的重数表示这个类的多少个实例对象可以与另一个类(该关联的另一端)的一个实例相关。 - 允许一个类与自身关联
- 二元关联表示为在两个类之间用一条直线连接,直线上可写上关联名
- (2)多元关联
三个或三个以上的类之间可以互相关联
- (3)受限关联(qualified association):受限关联用于一对多或多对多的关联。限定符(qualifier)用来区分关联"多"端的对象集合,它指明了在关联"多"端的某个特殊对象
(4)聚合
【聚合关系】:是整体与部分的关系,且部分可以离开整体而单独存在 。如车和轮胎是整体和部分的关系,轮胎离开车仍然可以存在。**聚合关系是关联关系的一种,是强的关联关系;**关联和聚合在语法上无法区分,必须考察具体的逻辑关系。
(5)组合(composition)
【组合关系】:是整体与部分的关系,但部分不能离开整体而单独存在。如公司和部门是整体和部分的关系,没有公司就不存在部门。组合关系是关联关系的一种,是比聚合关系还要强的关系 ,它要求普通的聚合关系中代表整体的对象负责代表部分的对象的生命周期。
- 泛化
泛化:是一种继承关系,表示一般与特殊的关系,它指定了子类如何特化父类的所有特征和行为。比如老虎是动物的一种,既有老虎的特性也有动物的共性。具体画法有:有共享表示法和分离表示法两种。
- 泛化共享表示法:多个类共享一个泛化箭头
- 泛化分离表示法:每个类有自己的泛化箭头
- 实现
类与接口的关系,表示类是接口所有特征和行为的实现。
- 依赖
是一种使用的关系,即一个类的实现需要另一个类的协助。
可以简单的理解,就是一个类A使用到了另一个类B,而这种使用关系是具有偶然性的、临时性的、非常弱的,但是B类的变化会影响到A;比如某人要过河,需要借用一条船,此时人与船之间的关系就是依赖。
如何阅读类图
- 先看清有哪些类,然后看看类之间存在的关系,并结合多重性来理解类图的结构特点以及各个属性和方法的含义
- 读出类:图中共有7个类,Order(订单)、OrderItem(订单项目)、Customer(客户)、Consignee(收货人)、DeliverOrder(提货单)、Peddlery(商家)、Prodcut(产品)
- 读出关系:从图中关系最复杂(也就是线最密集)的类开始阅读,本图中最复杂的就是Order类。
1)OrderItem和Order之间是组合关系
2)Order类和Customer、Consignee、DeliverOrder是关联关系。也就是说,一个订单和客户、收货人、送货单是相关的。 - 多重性:用来说明关联的两个类之间的数量关系
- Order类,有两个方法:dispatch()和close(),从名字中可以猜出它们分别实现"分拆订单生成送货单"和"完成订单"。而在DeliveOrder()类中则有一个Close()方法,同理它应该表示"完成送货"。而在OrderItem中有一个stateChange()方法和deliverState,不难猜出它就是用来改变其"是否交给收货人"标志位的
- 先调用Order的dispatch()方法,它将根据其包含的OrderItem中产品信息,来按供应商户分拆成若干个DeliverOrder。商户登录系统后就可以获取其DeliverOrder,并在执行完后调用close()方法。这时,就将调用OrderItem的stateChange()方法来改为其状态。同时再调用Order的close()方法,判断该Order的所有的OrderItem是否都已经送到了,如果是就将其真正close()掉
其他高级概念(自学)
接口与抽象类
• 抽象类是一种不能够被直接实例化的类,也就是说不能够创建一个属于抽象类的对象
• 接口则是一种类似于抽象类的机制,它是一个没有具体实现的类
关联类
• 关联类即是关联也是类,它不仅像关联那样连接两个类,而且还可以定义一组属于关系本身的特性 (Role)
模板类
• 可以根据占位符或参数来定义类,而不用说明属性、方法返回值和方法参数的实际类型
左边的是模板类
主动类与嵌套类
• 主动类的实例称为主动对象,一个主动对象拥有一个控制线程并且能够发起控制活动;它不在别的线程、堆栈或状态机内运行,具有独立的控制期。从某种意义上说,它就是一个线程
• 在诸如Java的语言中,允许你将一个类的定义放在另一个类定义的内部,这就是嵌套类,在Java中也称为内层类。嵌套类是声明在它的外层类中的 ,因此只能够通过外层类或外层类的对象对它进行访问
如何绘制类图
案例1:个人图书管理系统的需求描述
• 小王是一个爱书之人,家里各类书籍已过千册,而平时又时常有朋友外借,因此需要一个个人图书管理系统。该系统应该能够将书籍的基本信息按计算机类、非计算机类分别建档,实现按书名、作者、类别、出版社等关键字的组合查询功能。在使用该系统录入新书籍时系统会自动按规则生成书号,可以修改信息,但一经创建就不允许删除。该系统还应该能够对书籍的外借情况进行记录,可对外借情况列表打印。另外,还希望能够对书籍的购买金额、册数按特定时间周期进行统计
如何识别类
(1)考虑问题域:
可以启发分析员发现对象的因素包括:人员、组织、物品、设备、抽象事物、事件、文件及结构等
- 人员:(a)需要由系统保存和管理其信息的人员,如户籍管理系统中的每个居民:(b)应该在系统中完成某些功能,提供某些服务的人员,如户籍管理员。符合上述情况之一者,应考虑用相应的人员对象来描述
组织:在系统中发挥一定作用的组织结构。如工作班组等
物品:需要由系统管理的各种物品。如经营的商品等。
设备:在系统中动态地运行、由系统进行监控或供系统使用的各种设备、仪表、机器及运输工具等
抽象事物:指没有具体的物理形态,却对用户的业务具有实际意义的逻辑上的事物。
事件:指那些需要由系统长期记忆的事件。
文件:泛指在人类日常的管理和业务活动中使用的各种各样的表格、档案、证件和票据等文件
结构:通过考虑结构可以得到一种启发一一从已经发现的对象联想到其他更多的对象
识别属性
- (1)策略与启发
- 按常识这个对象应该有哪些属性?(例如人的姓名、职业、地址等)
- 在当前的问题域中,对象应该有哪些属性?(例如商品的条形码)
- 根据系统责任,这个对象应具有哪些属性?(特卡人的使用地点)
- 建立这个对象是为了保存和管理哪些信息?
- 对象为了实现操作的功能,需要增设哪些属性?
(例如传感器对象,为了实现其定时采集信号的功能,需要一个"时间 - 对象是否需要通过专设的属性描述其状态
(例如设备对象,在关闭、待命、运行、故障等不同状态将呈现不同的行为需要为其设置一个状态""属性) - 用什么属性表示聚合和关联?
(对于关联,应该在关联一端的类中定义一个属性,来指出另一端的哪个对象与本端的对象发生关联,其数据类型是指向另一端对象的指针或对象标识),
识别操作
区分对象行为的类型
为了明确OOA应该定义对象的哪些操作,首先区分对象行为的不同类型:
(1)系统行为
例:创建、删除、复制、转存
(2)对象自身的行为---算法简单的操作
例:读、写属性值
(3)对象自身的行为---算法复杂的操作计算或监控
发现类
小王 是一个爱书之人 ,家里 各类书籍 已过千册,而平时又时常有朋友 外借,因此需要一个个人图书管理系统 。该系统应该能够将书籍的基本信息 按计算机类 、非计算机类 分别建档,实现按书名 、作者 、类别 、出版社 等关键字 的组合查询功能 。在使用该系统录入新书籍 时系统 会自动按规则 生成书号 ,可以修改信息 ,但一经创建就不允许删除。该系统还应该能够对书籍的外借情况进行记录 ,可对外借情况列表 打印。另外,还希望能够对书籍的购买金额 、册数 按特定时间周期进行统计
筛选备选类
• "小王"、"人"、"家里"很明显是系统外的概念,无须对其建模;
• 而"个人图书管理系统"、"系统"指的就是将要开发的系统,即系统本身,也无须对其进行建模;
• 很明显"书籍"是一个很重要的类,而"书名"、"作者"、"类别"、"出版社"、"书号"则都是用来描述书籍的基本信息的,因此应该作为"书籍"类的属性处理,而"规则"是指书号的生成规则,而书号则是书籍的一个属性,因此"规则"可以作为编写"书籍"类构造函数的指南。
• "基本信息"则是书名、作者、类别等描述书籍的基本信息统称,"关键字"则是代表其中之一,因此无需对其建模;
• "功能"、"新书籍"、"信息"、"记录"都是在描述需求时使用到的一些相关词语,并不是问题域的本质,因此先可以将其淘汰掉;
筛选修选类
• "计算机类"、"非计算机类"是该系统中图书的两大分类,因此应该对其建模,并改名为"计算机类书籍"和"非计算机类书籍",以减少歧义;
• "外借情况"则是用来表示一次借阅行为,应该成为一个候选类,多个外借情况将组成"外借情况列表",而外借情况中一个很重要的角色是"朋友"---借阅主体。虽然到本系统中并不需要建立"朋友"的资料库,但考虑到可能会需要列出某个朋友的借阅情况,因此还是将其列为候选类。为了能够更好地表述,将"外借情况"改名为"借阅记录",而将"外借情况列表"改名为"借阅记录列表";
• "购买金额"、"册数"都是统计的结果,都是一个数字,因此不用将其建模,而"特定时限"则是统计的范围,也无需将其建模;不过从这里的分析中,我们可以发现,在该需求描述中隐藏着一个关键类---书籍列表,也就是执行统计的主体。
得到候选类
• 在使用"名词动词法"寻找类的时候,很多团队会在此耗费大量的时间,特别是对于中大型项目,这样很容易迷失方向。其实在此主要的目的是对问题领域建立概要的了解,无需太过咬文嚼字
关联分析,建模,多重性分析,再建模
职责分析
• 书籍类:从需求描述中,可找到书名 、类别 、作者 、出版社 ;同时从统计的需要中,得知"定价 "也是一个关键的成员变量。
• 书籍列表类:书籍列表就是全部的藏书列表,其主要的成员方法是新增、修改、查询(按关键字查询)、统计(按特定时限统计册数与金额)。
• 借阅记录类:借阅人(朋友)、借阅时间。
• 借阅记录列表类:主要职责就是添加记录(借出)、删除记录(归还)以及打印借阅记录
案例2:网上购物系统
通过相应的网址访问网上购物系统,进入系统后,客户即可通过多级分类目录逐级浏览商品的名称、规格、单价、图片等信息,直至阅浏览某个商品的详细技术指标。浏览过程中,客户可随时将需要的商品放到购物车内,系统可显示购物车内已选购的商品、单价、数量及价格,客户还可随时删去购物车内尚未结账的任何商品。
当客户选择好所需的商品后,可要求结账,此时,系统首先要求客户注册/登录(对新客户需先注册,填写客户信息,然后登录;对老客户只需通过用户名和密码直接进行登录即可),然后根据购物车中所选的商品形成初始的订单,同时选择支付方式,填写相关的派送信息,如送货地址、建议的送货时间段等,此时即可提交订单,系统向客户返回一个订单号。
系统提供网上在线支付和货到现金支付两种支付方式。网上在线支付方式由专门的网上支付系统 实现在线支付,需根据网上支付系统的要求填写相关的账户信息,如账号、密码等,并进行扣款,网上在线支付的结果或者是付款成功,或者是付款失败。货到现金支付方式由送货员 在送达商品时向客户收取现金。客户还可通过订单号查询自己订单的当前状态,如已提交未付款、已发货已付款等,并允许取消尚未发货的订单。
系统业务员将客户提交的订单交由物流系统或快递公司向客户发货,又称派送,物流系统或快递公司送达商品后对未付款的客户收款,并将客户签收单返回给系统业务员,系统业务员负责更新订单的状态,以便跟踪和了解订单的执行情况。
静态建模实例
- 标识候选对象
- 外部实体:客户,系统业务员,网上购物系统,物流系统,网上支付系统,客户信息管理系统,商品信息管理系统
- 需要存储、处理的信息:商品的名称、规格、单价,购物车中的物件,订单的订单项(即选购的商品)、支付信息、送货信息。由此可导出候选对象是商品,购物车,订单
- 筛选候选对象
- 物流系统:未出现在用况图中,删除
- 网上支付系统:仅作为外部执行者完成网上在线支付功能,删除
- 客户信息管理系统和商品信息管理系统:只是作为外部执行者参与创建和维护客户信息和商品信息,本案例并不关心这些外部系统的具体细节,删除
- 系统业务员:在本案例中主要作为修改订单状态的输入者,其自身没有属性,删除
- 网上购物系统:代表本案例的完整系统,所有信息的显示、操作界面等都由网上购物系统来展示,保留,称为"网上商城"
- 客户、商品、购物车、订单:有明确的属性和操作,保留
- 考虑到一份订单可以由多个订单项组成,一辆购物车可以放多件物品,因此增加订单项和物件两个对象
- 标识属性和操作
4.确定类之间的关系
- 网上商城拥有多件商品和购物车,并能从网上商城查到所有的商品信息
- 任意多个客户可以到网上商城订购商品,网上商城能查到所有的注册客户信息
- 一个客户可以拥有多份订单,客户可以查看自己的全部未到货订单
- 一份订单由多个订单项组成
- 一个客户只有一辆购物车
- 一辆购物车可以放多件物件,从购物车可以查到车内所有的物件
- 一个订单项或物件对应一个商品,但一个商品可对应多个订单项或购物车中的多个物件
网上购物系统的类图
总结建立类图的步骤
1.研究分析问题领域,确定系统的需求。
2.发现对象与类,明确它们的含义和责任,确定属性和操作。
3.发现类之间的关系。把类之间的关系用关联、泛化、聚集、组合、依赖等关系表达出来。
4.设计类与关系。调整和细化已得到的类和类之间的关系,解决诸如命名冲突、功能重复等问题。
5.绘制类图并编制相应的说明。
静态建模------对象图
对象的概念与特性
• 对象代表一个单独的、可确认的物体、单元或实体,它可以是具体的也可以是抽象的,在问题领域里有确切定义的角色。换句话说,对象是边界非常清楚的任何事物
• 状态:对象的状态包括对象的所有属性(通常是静态的)和这些属性的当前值(通常是动态的)
• 行为:没有一个对象是孤立存在的,对象可以被操作,也可以操作别的对象。而行为就是一个对象根据它的状态改变和消息传送所采取的行动和所做出的反应
• 标识:为了将一个对象与其它所有对象区分开来,我们通常会给它起一个"标识"
对象 vs 类
• 对象是一个存在于时间和空间中的具体实体 ,而类仅代表一个抽象,抽象出对象的"本质"。
• 类是共享一个公用结构和一个公共行为对象集合
• 类是静态 的,对象是动态 的;类是一般化 ,对象是个性化 ;类是定义 ,对象是实例 ;类是抽象 、对象是具体
对象图的表示法
• 对象名:由于对象是一个类的实例,因此其名称的格式是"对象名:类名",这两个部分是可选的,但如果是包含了类名 ,则必须加上":" ,另外为了和类名区分,还必须加上下划线 。
• 属性:由于对象是一个具体 的事物,因此所有的属性值都已经确定,因此通常会在属性的后面列出其值 。
阅读对象图
• 首先找出所有的类,即在":"之后的名称
• 整理完之后,就可以通过对象的名字来了解其含义
• 按类来归纳属性,然后再通过关联来确定含义
绘制对象图的过程
• 先找出类和对象,通常类在"class"、"new"、"implements"等关键字之后的,而对象名则通常是在类名之后的
• 然后对其进行细化的关联分析,绘制出相应的对象图
• 论证类模型的设计:当设计了类模型时,你可以通过对象图来模拟出一个运行时的状态,这样就可以研究在运行时设计的合理性。同时,也可以作为开发人员讨论的一个基础。
• 分析和说明源代码:由于类图只是展示了程序的静态类结构,因此通过类图看懂代码的意图是很困难的。因此在分析源代码时,可以通过对象图来细化分析。而对于开发人员,对于逻辑较复杂的类交互时,可以考虑画出一些对象图来做补充说明