本文我们结合某省邮政局的个性化邮件系统的一些典型用例的实现作一番探讨。
一、 个性化邮件系统需求概述
个性化邮件系统(以下简称Y系统)主要是市邮票公司提供给市民的特种邮票服务,它能把客户的个人照片印在特定版面的邮票上,使之具有一种特别的纪念意义。而邮票公司所提供的两种款式分别是“岁岁平安”和“太阳神鸟”可供客户不同的喜好选择。
经过公司的业务分析和系统分析人员的流程优化后,共同定义了如下的全部页面流程:
1 首页,款式展示和流程说明。
2 授权书。
3 客户录入基本信息并上传身份证.。
4 客户下单,输入所选款式、数量并上传相片,系统自动汇总计算订单金额。
5 显示客户信息和订单明细信息。
6 确认订单。
7 显示订单号和金额。
8 确认付款。
9 输入帐号。
10 申请成功,提示领取信息。
总的说来,整个流程就是:
1 客户下单
2 支付
3 审核
4 投递或自取
从业务逻辑上看来,如果我们把提供的款式看成产品,每件款式的单价是确定的,而数量是需要客户下达的,只是由于业务特点的需求,它的商品“原材料”实际上是由客户上传的。“麻雀虽小,五脏俱全” ,Y系统(即前文提到的“个性化邮件系统”)规模不大,但是已经涵盖了企业客户、订单、生产(服务)、发货全部的运营流程。从Y系统的业务需求看,它比较类似于购物车的需求实现。从企业运作流程看,Y系统就是一个迷你版的ERP销售系统。
二、 重点用例
按照基于用例的开发流程,原始业务需求一旦确认,我们则进入了确定和提炼用例阶段。最终,我们给出了如下的对业务起着决定意义的用例。
1. Use Case ID: 创建订单(Create Order)
主题 : UC01 创建订单
相关主题 : Create Order
需求ID : R01
- 目的
使用例参与者能确保创建和提交订单并能够添加相关产品(上传照片)到订单行。 - 描述
参与者想通过订单购买一种或多种产品(服务)。在受理网站上, 参与者通过类似于购物篮的形式,完成产品的添加和订单下达, 一旦产品被添加到订单,订单将即时更新订单总金额。 - 前提条件
1) 参与者已经登陆到本系统网站,系统首页已能让参与者受理个性化邮票业务。
2) 参与者必须选择至少一件产品给订单,即必须上传一张照片。 - 参与者
1)客户
2)管理员 - 基本流程
第1步:当参与者决定下达订单,本用例即开始。
第2步:参与者注册客户信息, 系统通过其身份登记和认证。
第3步:参与者创建订单, 系统返回其订单创建信息。
第4步:系统处理参与者的创建订单请求,直到客户完成该订单。
a. 参与者选择一种产品款式(此处可以作为单独用例UC 08 查看款式目录)。
b. 参与者键入订购数量。
c. 参与者添加商品即上传照片给订单。
d. 系统更新订单行资料,包括数量、款式、商品和总金额。
第5步:参与者确认已完成订单。
第6步:参与者验证并确认订单和客户明细信息, 系统反馈该参与者的提交的订单详情 。
第7步:参与者验证并确认订单付款信息, 系统反馈订单编号和付款总金额。
第8步:参与者确认订单付款,系统调用相关付款接口完成付款流程 (此处可以作为单独用例UC 09 订单付款)。
第9步:本用例结束,当系统成功返回给参与者该订单付款情况,并提示参与者相关订单发货信息。 - 附加流程
1)如果付款或投递被延迟进行,则第7步到第9步将被跳过,本用例在订单被确认和保存时结束。
2)如果订单已经存在(was previously deferred):
a. 当先前下达的订单被选择时本用例开始。
b. 第2步则为系统显示之前创建的订单。
c.第3步到第9步遵循基本流程的步骤。
3) 如果客户键入了错误的付款信息,系统将通知参与者,然后本用例应从第7步继续。 - 内涵/扩展
None - 实施需求
None - 使用频率
经常 - 特别需求
ID
款式
照片
数量
1 岁岁平安 1 2 太阳神鸟 1 - 问题
无 - 决策点
无 - 未来需求
无 - 修改版本
Date
Author
Description
- 用例模型
2. Use Case ID: 审核订单(Approve Order)
主题 : UC02 审核订单
相关主题 : Approve Order
需求ID : R02- 目的
使用例参与者能查看所有订单并根据具体情况做出审核决定,如果审核不通过发出通知给客户。 - 描述
参与者审核客户已经付款的订单。在受理网站上, 参与者通过各种形式将审核结果通知到客户。 - 前提条件
1) 参与者已经登陆到本系统网站。
2) 参与者必须选择一份订单进行审核动作。 - 参与者
1) 管理员
2) 客户 - 基本流程
第1步: 当参与者“管理员”开始审核已经付款的订单,本用例即开始。
第2步: 参与者“管理员”发出查询订单的请求,系统安装订单日期倒排显示订单清单。
第3步: 参与者“管理员”按照逐一审核各订单。
a. 查看订单基本信息。
b.查看订单产品照片是否合格。
c.“管理员”发出审核动作,系统将作出该订单的审核状态提交。
d“管理员”键入审核意见,系统将保存该订单的审核意见。
第4步: 订单审核完成,本用例结束。 - 附加流程
1) 第3步, 如果该订单不能通过审核,“管理员”写明审核意见,并点击发送按钮,系统将发送短信息通知相关参与者“客户”。用例从第4步继续。 - 内涵/扩展
无 - 实施需求
无 - 使用频率
经常 - 特别需求
ID
款式
照片
数量
1 岁岁平安 1 2 太阳神鸟 1 - 问题
无 - 决策点
无 - 未来需求
无 - 修改版本
Date
Author
Description
- 用例模型
三 用例实现
目前我们已经把握了重点用例,现在则要“实现”用例。用例的实现指的是对每个用例所进行的详细系统过程的说明,在这个过程中,我们以UML的方法给出了类图设计、顺序图、状态图,甚至包括UI设计和E-R设计等等,目的是为系统进一步的详细设计提供概念上的依据和设计参照。
1 “创建订单”用例
图1: Stamp DIY Physical Object Model
图1中的业务关系类图,我们有如下描述:
a. 订单Order和订单行OrderDetail是组合关系。订单Order和OrderDetail构成上下级别的一对多关系,它们拥有着一致的生命周期。
b. 产品目录Catalog和目录项Catalogitem也是组合关系,拥有一致的生命周期。
c. 客户Customer和Order 形成关联类,二者构成强制关系, 即客户类Customer不存在的情况下,订单类Order是不存在的。
d. 客户Customer从本质上是一种角色Role,所以客户Customer可以视为Role角色的子类,Customer继承了Role的属性。
我们在设计域类通常会遵循一些基本的设计准则,如下:
封装——封装是一种设计准则,规定了数据和程序逻辑包含在一个独立的单元中。
导航可见性——是一种设计准则,指一个对象可以看到另一个对象并与之交互。
设计的任务之一是说明哪个对象对哪个对象有导航可见性,它可以是单向或双向的。如图1,一个Customer对象可以看见一个Order对象,它意味着Customer对象可以知道客户发出了哪些订单。在程序里,Customer类通常会用一个变量或数组来指向这个客户的一个或多个Order对象。在设计类图中,导航可见性用类之间的箭头表示,箭头指向可见的类。
耦合——它来自于导航可见性,如图一,Customer对Order是可见性的,则它们是耦合的,同样,Order对OrderDetail也具导航可见性,它们也是耦合的。
耦合是对设计类图中的类与类之间连接关系的紧密程度的定性的度量。一种比较容易理解耦合的方法是看设计了类图的导航箭头的个数,比如Customer对Order是耦合的,Order对OrderDetail是耦合的,这些是正常的设计。但如果把Customer加入到对OrderDetail的导航可见性则是强耦合的类型,这样的设计会降低系统的维护性。
通常,有经验的分析员会尽量简化耦合,并减低对新系统设计的影响。
聚合与任务分解——指的是一个类中各种功能的一致性,它是对一个类中目的单元或主题的定性度量。
我们需要的是高聚合的类设计, 因为低聚合的类不容易维护,重用度低。在图1中,我们把客户,订单和购物车分解成几个高聚合的类.为解决低聚合的类通常采用的分成几个高聚合类的方法是为任务分解,它是另一个面向对象设计的准则。
图2: DB Schema如图2的数据E-R设计,我们可以得出如下描述:
-
客户Customer和Order形成一对多关系,一个Customer表可以对应零到多个Order表。
-
订单Order和订单行OrderDetail构成了一对多的关系。
键是E-R设计的重要角色,主键惟一地表示了数据模型内一个实体的各实例,而通过外键则把各实体连接在一起。
在图2中,Order表的主键是OrderID,它是自增型整数序列ID,它的外键是CustomerID,映射到了Customer表;而OrderDetail表的主键则是通过组合键(Composite Key)的OrderID和DetailLineID来定义的;而Categories表的主键是GUID,一种唯一性的全球标识码。
从图2中,我们已经看到了数据表的定义主键的几种基本方法。
图3: “创建订单”顺序图对于图2的“创建订单”顺序图 ,我们有如下描述。
开发交互图是面向对象设计的核心,实现用例的过程就是通过确定哪些类通过发送消息与其他类交互协作的过程,顺序图是交互图的一种。顺序图用于描述进出自动系统的信息流,一个系统顺序流记录了输入和输出并且标识了参与者和系统之间的交互。在图3中,已经形象地描述了参与者如何通过数据和获得输出数据来和系统进行交互地。
图3中,由下划线对象和一个矩形框组成的是整个系统的各个对象,按照对象出场先后顺序排列,它们是Customer、Website、Account、Product、Order、Order LineItem、Authoriy。
一旦对象已经确定,我们需要给出的是贯穿每个对象生命周期和连接各个对象交互的消息,对于每一条消息,我们有必要列出消息源对象和目的对象。如图3所示,Customer作为系统参与者,先后给WebSite、Account、Order等对象发送了消息,而各个对象也各参与者的Customer返回了消息,这样地消息循环最终完成了用例所描述的流程。
比如Customer在本用例中先后发送了如下消息完成了与系统的整体交互过程:- Browses To : 原始消息,从Customer到Web Site,Web Site返回了消息“ Request Credentials” 。
- Provide Credentials: 从Customer到Web Site,Web Site返回了消息“ Display homepage” 。
- Create Orders: 从Customer到Order。
- Find Product : 从Customer到Product.的内部消息开始,引发了从Product到Order的系统主要消息“Add Product to Order”,接着通过发送源于Order的“Add Order Item:”这一消息的发送到Order Line Item更显顺理成章,从而完成了用例基本流程的第4步。
- Modify Quantity : 从Customer到Product 。
- Enter Payment Info:从Customer到Order。
- Submit Order:到此Customer已经完成了最后一个消息的发送, 通过本顺序图的完成也以黑匣子的角度模拟了系统的流程。
现在让我们探讨顺序图的设计规则:
a) 接受每个输入消息并确定由这个输入消息产生的所有内部消息。
确定消息的目标。需要什么消息,哪个类(即目的地)需要这条消息,以及哪个类(即消息源)提供这条消息。这种分析有助于理清内部消息、源对象和目的地对象。
b) 在处理每个消息的时候,要辨别出受之影响的类的完整集合,即从域类图中找到需要的所有对象。在用例的前提条件和后续条件中罗列的任何类都应该包含到设计中去,即被创建的类、创建用例对象的类、用例期间更新的类,以及提供用例需要信息的类。
c) 充实消息的结构,添加迭代、正/误条件、返回值和传递参数。传递参数应该参考域类的属性。返回值和传递参数可以是属性,也可以是类中的对象。
本文行文至此,基本完成了用例“创建订单”的实现,同时探讨了交互设计应当遵循的准则,希望给读者有所参考和帮助。 - 目的