两大类UML图:
行为图(behavior diagrams)和结构图(structure diagrams)
行为图将引导系统分析员分析且理清“系统该做些什么”?系统分析员在绘制行为图时,可以聚焦在系统多方面的动作,像是系统与用户之间的交互,或者是某种对象因为事件的刺激以至于发生某些反应动作,以及一群对象交互完成某项服务,等等。系统分析员在访谈期间或结束之后,可以通过这些不同功能的行为图,获知系统多方面的行为。
行为图包括:用例图(Use Case Diagram)、活动图(Activity Diagram)、状态图(State Machine Diagram)、序列图(Sequence Diagram)
结构图将引导系统分析员获知“系统的重要组成元素是什么”?通常,通过结构图将引导系统分析员理清业务里(Business)的专有名词,以及专有名词之间的关系,以此作为系统的核心结构。其余,技术面的结构设计就留待设计师去伤脑筋了,这部分并不是系统分析员的工作职责。
系统分析员主要会学的UML图是类图(Class Diagram),属于结构图。
重要的OO及UML概念
OO是一种比较直接的设计思维,在设计软件时,让软件世界里的程序对象对应真实世界里的具体事物,以此来模拟真实世界的运作情况。观察真实世界可以发现,真实世界由各式各样的事物所组成,每种事物都有它特有的结构和行为,而且在联系起不同事物之后,还能够展现出丰富多元的能力。所以,OO软件也由各式各样的软件对象所组成,并且合力提供多样化的服务,以此参与企业运作过程。
OO概念是UML的基础,也就是说,系统分析员在学习使用UML的同时,其实就是在应用OO概念。换个角度来看,UML与OO两者互为表里,系统分析员脑子里运用的是OO概念,但是表达出来的需求文件内容却是使用UML图。
UML最大的特色在于它是图形语言,因此享有图形思考与表达的优势。所以在本书里,我们除了要求系统分析员在编写需求文件时需以UML图为主、文字为辅外,还要求系统分析员在
访谈及讨论会议期间,皆需以UML图引导整个会议进行,并且以生成UML图作为其会议结果。
• 访谈即是绘制UML图。
• 讨论即是修改UML图。
想象一下,系统分析员带着安装了UML工具的笔记本电脑,到用户或领域专家的办公处所进行访谈,访谈的结果就是UML图。系统分析员启动UML工具的同时,就是访谈的开始。系
统分析员开始动手绘制第一张UML图,也同步开始请教用户各项问题,一边绘图一边跟用户澄清认知,以便完成UML图。按照这样的过程,生成一张又一张的UML图。当这些UML图都绘
制并且经过确认之后,系统分析员打印UML图交给用户,并且将UML文件传回给公司,完成此次访谈会议。
在访谈记录正式成为需求文件期间,用户有任何补充或者系统分析员有任何疑问,都切记以手上的UML图为讨论依据。同样地,系统分析员提交文件给设计师之后,如果设计师有任何
疑问,需要开讨论会议的话,也必须以UML图为讨论依据。没有准备好UML图,就不要浪费时间开无谓的讨论会议,与会人员没有修正UML图,讨论会议就不算结束。在了解OO与UML的相关性之后,接下来我们会介绍几项重要的OO概念,当然它们同时也是UML里的重要概念。
对象
真实世界由琳琅满目的事物所构成,但并非所有的事物都适合对应成软件对象(Object)。对于系统分析员而言,候选对象应该同时符合下列两项条件:
1. 在企业运作过程中,业务人员会使用到的专业事物或概念。
2. 而且在信息化时,系统也会用到,或者需要保存。
系统分析员在访谈业务人员时,可以提出类似下述的问句,以便获知重要的对象。如:
• 在执行这项工作时,你们会用到哪些专业概念?(探问对象)
• 你们在执行这项工作时,会需要用到哪些数据?(探问对象)
诸如此类的问句,有助于找到重要的对象。软件公司可以多向资深的系统分析员搜集此类的智慧问句,甚至编写成系统分析员通用的工作手册。
属性与操作
当试图去了解真实世界中任一事物时,有多元的角度可以去探寻。不过,系统分析员并不需要这么样深入了解对象。对于任何一种对象,系统分析员只需要针对下列两项问题
去探寻:
1. 对象需要记录哪些属性(Attributes)?
2. 对象可以提供哪些操作(Operations)?
上述的问题可以说得更白话些,或许系统分析员可以向业务人员作如下的提问:
• 某物会记录什么数据呢?(探问属性)
• 某物可以提供我们哪些数据呢?(探问属性)
• 通过某物,可以让我们查到哪些数据吗?(探问属性)
• 某物可以做什么用呢?(探问操作)
• 有了某物之后,我们可以拿它来做什么事呢?(探问操作)
假设我们要开发基金交易平台,现在来向业务人员进行访谈,期间提到了“基金账户”。想象一下,系统分析员跟业务人员之间的模拟对话,大概会像这样子:
系统分析员问:基金账户会记录什么数据呢?(探问属性)
业务人员答:基金账户里头主要会记录总成本、总现值、总损益、总报酬率。
系统分析员问:有了基金账户之后,我们可以拿它来做什么?(探问操作)
业务人员答:有了基金账户之后,只要里头存有足够的钱,你就可以用它来申购基金,或者赎回基金。
访谈之后,系统分析员便得到了这个项目属性与操作的概貌,如图1-1所示。
针对对象的各项属性,系统分析员还需要进一步了解它在企业里的定义、数据类型(DataType)、可能的范围值或者初始值,更别忘了了解这项属性是怎么跑出来的?或许,系统分析员可以向业务人员作如下的提问:
• 可以请您(业务人员)用简单的一、两句话,解释某属性是什么吗?(探问属性定义)
• 可以请您举个例子吗?(判断属性的数据类型)
• 请问某属性有范围值吗?(判断属性的数据类型以及字段大小)
√ 可被接受的数字,最大最小为何?(数字类型)
√ 可被接受的字符串,最长最短为何?(字符串类型)
√ 预设的项目,有哪几个?项目异动的频率?(枚举类型)
• 请问某属性有初始值吗?(探问属性的初始值)
• 怎样做才能够得到某属性值(Attribute Value)?(探问属性值的获得方法)
√ 请问谁会提供这项属性值?(键入值)
√ 请问可以向哪里查询这项属性值?(查询值)
√ 请问计算公式为何?(计算值)
√ 请问可有独特的编码方式?(流水码或特定编码)
操作与方法
针对对象的操作,系统分析员还必须进一步探问how,了解操作的实现方法(Method)。简言之,操作是对象的what,而方法则是对象的how。然而,在我们用程序实现出对象之前,
对象是死的,它哪会有什么方法来执行操作。所以,我们其实是想获知业务人员惯用的操作方法,然后将人为的操作方法转移给对象,成为对象的操作方法。系统分析员访谈业务人员时,主要得获知方法的执行步骤(Procedure)、所需或者产生的数据、计算公式,以及企业的特殊约束。也许,系统分析员可以参考下列问题,向业务人员提问:
• 您(业务人员)通常都怎么执行某操作的呢?可以告诉我主要的执行步骤吗?(探问执行步骤)
• 请告诉我这些执行步骤会用到什么数据?以及会生成什么数据?(探问数据的输入及输出)
• 请告诉我这些执行步骤会需要使用到计算公式吗?(探问计算公式)
• 在执行某操作时,有没有什么重要的约束需要注意或遵守的?(探问特殊约束)
假设针对基金账户对象的“申购基金”这项操作的执行步骤,系统分析员向业务人员访谈的过程中,可能出现如下述的模拟对话:
系统分析员问:您通常都怎么执行“申购基金”这件事呢?可以告诉我,主要的执行步骤吗?(探问执行步骤)
业务人员答:是这样的,申购基金分为两种:一种是单笔申购,另一种是定期定额申购。
系统分析员问:谁在什么时候会决定是哪一种?还是可以同时包含两种?(判断是否要拆成两项操作)
业务人员答:客户一开始在申购基金时,就得二选一,决定是要单笔申购某档基金,还是定期定额申购。(对于客户而言,单笔申购基金或者定期定额申购基金是两项不同的目的,所以系统分析
员决定将原先的图1-1里的申购基金操作一分为二,改成图1-2的模样。)
图1-2 申购基金操作一分为二
系统分析员问:请您挑比较简单好懂的一种,告诉我您主要的执行步骤?(探问执行步骤)
业务人员答:都很好懂啦,我就先说单笔申购的情况,好了。客户告诉我们单笔申购的基金名称、信托金额以及扣款账号,那我们这边只要确认这档基金有贩卖,然后客户指定的扣款
账号里头有足够的余额可以付信托金额和申购手续费,这样就可以申购了。确认申购之后,我们会从客户指定的扣款账号中,支出信托金额和申购手续费。最后,我们会给客户一个申购交
易的凭证号码,就完成单笔申购了。
系统分析员记录“单笔申购基金”的主要执行步骤如下:
1. 客户告知(基金名称)、(信托金额)以及(扣款账号)。
2. 业务人员确认(该档基金销售中)。
3. 业务人员确认客户指定的(扣款账号)里头有足够的(余额),可以用来支付(信托金额)和(申购手续费)。
4. 确认申购之后,我们会从客户指定的(扣款账号)中,支出(信托金额)和(申购手续费)。
5. 最后,我们会给客户一个(申购交易的凭证号码),就完成单笔申购了。
随后,系统分析员可以请业务人员协助确认这份记录,同时给予补充。但是,对于单笔申购基金的操作方法还没访谈完,系统分析员还得获知并确认输出入数据、计算公式以及特殊
约束。
封装
面对真实世界中的多数物品,我们是“不知”亦能用,多数事件,我们也是“不知”亦能行。当然,我们对多数的事物也不是全然无知,只不过通常是有限度的知。因此,在物品或事
件所蕴含的细节都被封装(Encapsulation)起来的情况下,我们还是可以使用物品、参与事件,毫无困难。
所以,当我们打造软件对象来仿真真实世界里的事物时,也模拟了这种封装特性。由于软件对象的封装性,所以对象之间仅透露足以进行交互的低限信息。对于对象的封装性,系统分
析员要掌握下列要点:
• 已知操作。对象通常仅对其他对象透露自身的操作,彼此之间通过调用(Call)已知的操作来交互。
• 封装属性。每个对象封装属性值,不透露给其他对象。
• 封装方法。每个对象封装方法,仅对其他对象透露操作,但不透露其方法。
因此,系统分析员要特别注意,在分析规划对象的方法时,如果需要与其他对象交互,甚至是使用到对象本身的属性或操作时,切记要严守下列三条:
1. 不得直接提及对象的属性。
2. 也不得假设对象的执行方法。
3. 仅能够使用对象的操作。
从上述可以发现,我们为了保护对象的封装特性,会牺牲掉许多便利性。好比喝冰冻饮料时不能打开杯盖直接畅饮,而非得戳一个小洞,通过吸管小口小口吸取,十分不便。但使用吸
管有一个好处,不小心打翻时,不会溅得四处都是,然后还得花钱再买一罐。严守对象的封装性,有一个好处,当需求发生变化而需要改写代码时,变化会被局限在对象的属性和方法中,不会起涟漪效应,也不会发生牵一发而动全身的连锁反应。由于软件内部的组成对象易于汰旧换新,所以软件的使用寿命延长,后续的维护成本也偏低,企业因此得到高投资报酬率,不过眼前首先要付出的代价是较高的开发成本。