12.1 面向对象分析设计
客户提供的需求文件经常是 格式不规范,描述也不够准确。如果软件工程师直接依据这些需求文件进行软 件开发 ,很容易 产生运算 和逻辑错误 。为了准确地把客户需求呈现给开发者和使用者 ,需要一种科学有效的需求分析和设计方法。一般软件工程师习惯使用某种软件开发语言 ,而且这种开发语 言决定了他们选择相应的分析 和设计方法。软件开发语言有两大种类: 面向过程开发语言(如 C 语言)和面向对象开发 语言(如 C++ 和 J ava 等)。面向 对象分析和设计( Object Or ie nt edAna lys is and Desi gn , OO AD) 是以建立对象模型为目的分析 和设计方法。通过面向对象分析和设计使建立的对象模型符合 4种要素中的某些要素: CD抽象; @ 封装; @ 模块化; @ 层次结构。注意这里提出的对象建模 4要素与面向对象开发语言的三个基本 特征(封装,继承, 多 态)是不同 的概念。前者是软件的分析和设计目的,后者是面对象开发语言的特征。
初学者可能并没有关注面向对象分析和设计中“分析” 和“设计” 这两个词的差别是什么,似乎它们都是为了建立对象模型。其实在面向对象分析和设计中,这两个词 的目的是完全不同的:分 析是针对软件功能而言的对象建模;设 计 是 针对软件质量而言的对象建模。可以理解为分析模型是软件系统的物质基础,设计 模 型是软件系统的上层建筑。例如,需 要开发一个收银机管理系统软件,首先需要分析这个收银软件都应该具备哪些功能,对这些功能的分析,称为分析建模。它是开发这个软件的“物质 基础"。但是只考虑实现这些功能还不能满足软件开发的需求,还要考虑软件的质量 要求,例如,使用 这个软件的可靠性、安全性、可修改性、便捷性以及易维护等性能。针对于软件的质量需 求所提出设计方案,称 为设 计模 型。 这 也是 软件 开发的“上层建筑”。
面向对象分析和设计方法与软件工程有什么区别? 面向对象分析和设计方法是基于对象建模的分析和设计方法,它的 关 注点在需求分析和软件设计方面,软件工程是基于软件项目开发的管理方法,它包括需求分析和软件设计的使用方法,参与人员 的交流模式,实 施 运行的时间计划,项 目 成 本 控 制和人力资源等管理方法。面向对象分析和设计方法是软件工程管理方法中的子课题。目前比较流行的软件工程理论包 括: Rational Unified Process ( RUP ) , Extreme Programming ( XP ) 和 Agile Process等。
12. 2 分 析 模 型
在分析客户功能需求时,最好 忘 记 自己的软件工程师身份,尽 可能地从客户的角度来理解客户需求,以便减少软件工程师已有的经验对客户需求产生影响。因为在面向对象分析过程中,不是在发明或改进客户的需求,而是在理解和捕获客户需求。客户的真正需求往往隐藏在客户的需求描述中,要通过分析模型把它们展现出来。分析 建模的目的就是要知道客户需要什么,而不是软件工程师设计什么。U ML 提供了很多种分析模型图,其中 在面向对象的分析建模中最常使用的是: 用 例 图 ,交互 图(顺 序图和通信图),概念 类图和设计类图等分析模型。
12.2.1 用例图模型
由于客户所处的行业和经验不同,他们 所描述需求的方式方法也不同。为了有效地归纳分类客户需求中的功能,分 析需求的最好办法是先在纸上把所有的功能圈出来 ,这样在视觉上更突出 ,然后再把这些圈圈用线连接起来,以 便看到它们之间的关联。经过这样的反复推敲、修改 ,最后 形成了由这些圈圈组成的 UM L 用 例图模型。其中每个圈圈是一个用例。例如,下 面是一个关千收款机管理系统的需求描述。

根据收款机管理系统的功能描述,得 出 下 面的用例图模型:如 图 1 2-1 所示的收款机管理系统用例图模型。这个模型把各种功能需求进行分类和归纳处理,每个用例 圈形成了既独立又关联的功能基本单位,为规范化地描述每个用例提供了概念基础,用例图模型帮助软件工程师确定需求功能的外延和内涵。它使对象分析和设计向封装这个目的迈出了第一步。

12.2.2 在用例图模型基础上编写用例
根据收款机管理系统用例图模型中出现的所有用例,选择销售用例作为示范案 例,如图 12- 2 所示。本章的目的是介绍 UML 模型在面向对象分析和设计中的应用, 所以,没有对用例图模型中的所有用例进行规范化描述。描述用例并不属于 UML 建模语言范畴。用例描述属千软件工程需求规范化的知识范畴。为了有效地指导软件 工程师的开发,有必要把客户语言描述的需 求转化为软件工程的规范化语言的描述方式,这 种 规 范的描述方式就是用例。

根据客户的需求描述,转化成如表 12-1 所示销售用例。

12.2.3 顺序图模型和概念类图模型
11.2.2节中已经把客户需求文件通 过用规范化描述转变 为用例需求文件(表12-1 ) ,在这个用例文件中,可以 清楚地看到用例的参与者、发生条件、主要流程和异常事件等。现在的问题是如何根据用例来指导开发软件?由于面向对象开发的基 本程序单位是类( class ) ,那么如何识别用例中的类? 很多人试图发现一些简单的识别类的方法或规律,例如,选取用例中的名词作为类的候选对象等,但是这些规律都很难满足软件开发的分析和设计需求。因为类的定义原则与用例描述的名词或者动词 并无直接关系。为了发现用例中类的候选名单,应该把注意力集中到用例的参与者与 系统互动的行为上,如果发现用例中的某些行为在实现用例时具有不可被替代的作 用,就可以把产生该行为的对象选为类的候选者。如何判断这些对象在用例中的责任(或所有行为)呢?在实际开发过程中 ,需 要通过建立各种 UML模型,对这些对象的行为进行分析,最终确定它的所有行为,并且基于用例中对象行为建立的类模型称为概念类(conceptionclass)。
概念类是实现用例的功能需求的类。概念类与开发程序中所编写的类是不同的, 后 者称为设计类(designclass ) 。概念类是设计类的基础,为了满足软件的质拭要求, 在设计阶段有可能将概念类分解成几个设计类。在面向对象分析建模阶段,建模 的 目的 是 从 用 例 需 求中准确地捕获功能概念,建 立概念类图模型。概念类图模型是由UML 类图 ( class diagra m) 来实现的,在概念类图模型中只展现的概念类的名字和之间的关联,不需要列出每个类的详细方 法(或信息)。建立概念图模型是一个反复 推敲、迭代更新的过程,不可能一次完成。
1 建立销售用例的类获选名单
根据销售用例,先 选出如表 12- 2 所 示概念作为组成这个用例的概念类候选名单。

下一步需要依据 U ML的交互图模型来确定概念 类和它们之间的 相互关联。
2 通过顺序图 模型确定概念类图模型
UML 2. 0 的交互图包含两 种图模型: 一种是顺序图 ,另一种是通信图。无论是顺序图还是通信图都可以 用来帮助我们发现概念类的责任和建立它们之间的关联。如果确定每个概念类的合理责任,那么不仅实现了面向对象分析和设计的封装 目的, 也为软件设 计阶段的松耦合 ( lo o s e co u p l ing ) 目 标奠定了基础。
下面通过建立 销售用例的顺序图模型和概念类图模型 ,对销售用 例中的概念类的责任进行 分析。
1) ) “ 开始交易”的顺序图模型和概念类图模型
该顺序图模 型(见图12-3) 描述由收款员单击系统界面开始一个新的交易后,所触发的一系列系统行为,首先取得收款员ID(员工编号),然后系统使用该员工编号创建交易对象 ,接下来新 产生的交易对象马上创建一个交易的销售项目集合 对象。这个顺序图模 型实际上对用例进行了系统内部行为的分析 。根据图 12-3顺序图模型的分析,可以看到图 12- 4概念类图模型中对象之间的如下关联:
(1 ) 收款机管理 系统对象 含有收款员 对象和交易对象。
( 2 ) 根据交易类概念的理解,交易对象必须含有交易的销售项目集合对象 ; 它们之间的关联是组合式关联,因为没有销售项目 ,交易就失去了存在的意义。


2) ” 录入商 品”的顺序图模型 和概念类图模型
"录入商品”的顺序图模型描述收款员接到客户要买的商品后,开始把这些商品录入到收 款机管理系统 ,管理系统所产生的一系列相应行为。首先,系统根据录入 商品的库存编码(或条形码)到商品目录找到商品的名称和价格等属性;然后,系统在交易 中创建一个针对该商品的销售项目(含有商品名称、型号和价格等信息),并由交易对 象把该销售项目加到销售项目集 合上。收款员按照商品的分类把所有不同的商品录入系统。所以,录入商品 是一个重复性的行为(即循环)。
根据“录入商 品” 的顺序图模型(见图12-5 ) ,可以 在图 12- 6 概念类图模型中建立对象之间的如下关联:


(1 ) 收款机管理 系统对象 含有交易对象,商品 对象。
( 2 ) 交易对象中的销售项目集合是销售项目对象的集合对象; 销售项目集合与销售项目之间是聚合式关 联,销售项目集 合内有可能没有 任何销售项目。
( 3 ) 交易对象创建销售项目 对象,并且把销售对象项目加入到销售项 目集合对象类中,所以,交易对象与销售项目有依赖关系。
3) “完成商品录入"的顺序图模型和概念类图 模型“完成商品录入“顺序图模型中,当收款员提示系统所有商品已经录入完成时,系统只有一个任务就是计算这次交易的总金额(即合计),所以 系统 向交易提出合计值的要 求,交易接下 来向 销售项目集合要求合计值,销售项目集合从其所包含的每个销售项目中获取项目金额小计(这是一个循环过程),然后汇总为该 交易的合计金额。
根据“完成商品录入"的顺序图模型(见图 12- 7 ) ,发现图 12-8 概念类图模型中是
图 12- 6 概念类图 的一部分。
4 ) " 付款"的顺序图模 型和概念类图 模型
"付款“顺序图模型中,收款员所收到的面额可能大于实际交易金额,另外客户 的付款方式可能是现金或信用卡 ,所以在交易对象中需要一个结算的行为 ,这个行为由千付 款方式不同涉及其他行为的发生,所以,需 要付款对象来完成这些任务。


根据“付款"的顺序图模型(见图 12- 9 ) ,建 立图 12-10 概念类图模型。在该模型中,交易对象必须拥有付款对象,所以,交易对象的两个必要组成成分是:销售项目集 合对象和付款对象。
5) “ 打印收据"的顺序图模型和概念类图模型
“打印收据“顺序图模型是销售用例中的最后一个环节,客户付款后,收款员操作管理系统的打印功能打印交易收据,打印收据意味着该交易巳经结束,在打印结束前 还需要做几件重要的事情:第 一 ,执行交易对象的打印行为;第 二 ,从销售项目集合中一个一个地获取出销售项目中的商品存货编码和数扯;第 三,从 库 存 中 减去对应商品的数最; 第 四 ,重复第二和第三步骤,直 到 销售项目集合中的所有销售项目都被取出和减库存为止;第 五,管 理 系统对交易作保存记录。


根据“打印收据"的顺序图模型(见图 12-11) ,获得图 12- 12 概 念 类 图 模 型。在图 12- 12 中 ,管理系统还拥有库存和交易记录对象,但是交易与库存是依赖关系,因 为交易对象并不拥有库存对象 ,但是它使用该对象的方法。


12.3 总 结
通过对 5 个概念类图模 型进行整合 ,得到关 于销售用例的完整概 念类图 模型(见图 12-13 )。现在有两个 常见的问题: 这个概念类模型在软件开发中的意义是什么?可以直接按照这个概念图中的类来编写程序吗?
销售用例的概念类图(见图12-13 ) 描述了解决该用例所涉及的问题的概念类, 对用例中所要解决的问题越明确,对解决该问题的概念类所应承担的责任也就越清 楚 ,所以也就越容易确定 概念类该做什么,不该 做什么。在 OOAD分析过程中确定每个概念类的责任是最重要的任务之一,只 有明确每个类的责任 ,才能最好地实现OOAD的封装理 念。但是,在实际 分析过程中,要弄清楚 每个概念类在用例中到底该承担什么责任并不是件容易的事情,例如,概念类图 12-6中,交易与商品目录没有关联 ,这样做的目的是无论 商品目录的行为发生什么变化并不影响交易的行为。那么是否可以 把图 12- 6改为概念类图12- 15(其顺序图为图 12- 14 )? 当然可以,这在功能实现上是可行的,但是从“交易”所承担的责任方面考虑,这种做法将削弱交 易本身的功能。交易关注的 是商品在付款时所发生的行为 ,如果让交易直接使用商品目录的查询行为,就意味交易行为将受到商品目录行为的制约,如果商品目 录查询行为发生变化,将直接影响交易 的行为。一方面 ,商品目录 提供的查询服务是面向 系统的服务 ,而不是 对交易 的特殊服务; 另一方面 ,交易不应该 承担查询商品目录的 责任 ,它只接收已 经选定的商品进行交易。这个例子说明了一个道理,不该做的事情 就不要 做,做好自 己 本职工作最重要。 所以,我们 没有 采 纳图 12- 15的分析模型。一个好的概念类图是对每个概念类的责任做到了最大程度的分离。
现在已经确定了销售用例的概念类以及每个类的主要行为,按道理讲可以开始编写程序了,但是,这个概念类图实现的只是用例的功能,在实际用例实现过程中, 不仅要分析用例的功能要求,还要考虑用例的质扯要求。所以,概念类图只是用例 功能分析阶段的成果,还需要关于用例质量要求的设计方案,最终是以设计方案类图为依 据开始进行编程的。如何用 UML实现用例的设计模型正是第 13章的内容。




