《树型软件工程方法》之系列博文9
原子事件
TREESOFT
目 录
9 原子事件. 1
9.1 事件的定义.... 1
9.2 终结数据与原子事件.... 1
9.3 原子事件的实例.... 2
9.4 事物与数据库.... 4
9.4.1 基本事物集.... 5
9.4.2 自变项与因变项.... 6
9.4.3 单纯性与并列性.... 7
9.4.4 共性与个性.... 8
9.4.5 虚事物与实事物.... 9
9.5 结束语.... 11
中国人为什么不可以有自己的软件工程方法与开发工具平台!
这是介绍《树型软件工程方法》的系列博文,请按文章标题所带的编号顺序阅读,否则你会看不懂本文。
迄今为止,我们己经定义了两类规范的模块:至多含有最后一条控制语句的程序段称为作业。由同宗延续生成的作业树所表示的程序段称为任务。从本文开始,我们将要讨论范畴比任务更大的规范模块—事件。
9.1 事件的定义
任务树所表示的程序段称为事件。
与作业和任务的定义类似,事件也是以程序段来定义的,任务树则是事件的结构树。表面上看,任务的范畴有着严格的限定,事件的范畴似乎也就随之被限定了。实际不然,因为任务树的作用范畴并没严格的限定,事件的范畴也就没有被限定。所以,上述定义只能说是定义了事件的结构树是任务树,事件范畴的限定还有待于任务树范畴的限定。由该定义可知,事件是比任务范畴大一级的程序模块。
博文《解一元高次方程的任务树》中图7.7是求解一元高次方程的任务树,遍历这棵任务树所生成的程序模块就对应于求解一元高次方程的事件。换句话说,“求解一元高次方程”是一个事件,这个事件含有Rt、Ini、Fx和Xp四个任务,构成了图7.7所示的任务树。由这个例子可以看出,求解一元高次方程事件的范畴是由其求解目标限定的,为实现该目标所需的程序语句集合就形成了该事件。
如前所述,作业、任务和事件都是规范模块。然而,软件设计是从用户需求入手的,用户需求是用自然语言书写的,与程序模块的概念相去甚远。实际上,事件己经是属于用户需求层面的概念。所以,以程序模块来定义事件不仅用于将事件设计成程序,也用于对用户需求进行分析,从用户需求中确立出事件。事件在用户需求中是什么概念呢?如何从用户需求中确立出事件呢?这是系统分析层面的问题,我们将会逐步找到答案。
事件分为高级事件和原子事件两类。本文先讨论原子事件,下一篇文章再介绍高级事件。
9.2 终结数据与原子事件
在软件系统的运行过程中会产生各种数据,其中有一类数据要被输出至系统外,脱离系统而变成静态数据,称这类数据为“终结数据”。终结数据形式很多,屏幕显示的数据,打印输出的数据,传送输出的数据,写入数据库的数据,等等。实际上,任何形式的终结数据都可以记录在数据库中。譬如一幅图形,一段声音,一张表格,你可以直接显示、打印、播放或传送,也可以先将相应数据写入数据库后再输出。因此,我们又可以称终结数据为数据库数据,数据库模型就是终结数据的模型。
这里是从软件系统的角度来定义终结数据的,现实生活中也都随处可以见到终结数据。购物后的“商品数量与金额”,加工成的“零件型号与数量”,学生考试的“科目成绩”,等等都是现实生活中的终结数据。
封闭地加工生成终结数据的程序模块称为原子事件。
所谓“封闭地加工生成终结数据”,即自接收输入数据至加工输出终结数据的全过程中,所有的程序语句都必须在原子事件中。原子事件是一类事件,其结构树当然是任务树。要生成终结数据至少需要有一个任务,所以原子事件是比任务范畴更大的程序模块。组成原子事件的任务相互协作,共同为生成终结数据作贡献,就形成了任务树。由此可见,原子事件的定义与前面的事件定义是一致的。对于原子事件,有如下两点需要注意:
1) 终结数据是确立原子事件的必要条件。
这个规定指出,只有生成终结数据的程序模块才有资格充当原子事件,但这类程序模块并非一定要被确立为原子事件。是否将其确立为原子事件,要看系统设计的需要。在不影响系统效率的前提下,尽量将其确立为原子事件,这将有利于系统结构的细化。
2) 原子事件可以拥有多个终结数据。
原子事件至少拥有一个终结数据,也可以拥有多个终结数据,这也要看系统设计的需要。有的时候单个原子事件处理多个终结数据可以简化程序提高效率,但多数情况下还应尽量使原子事件只处理单个终结数据。单个原子事件拥有多个终结数据只是现象,实际上也只有一个作为原子事件的目标数据,其它终结数据的生成模块都被视为组成该原子事件的任务,这也满足上一条终结数据是确立原子事件的必要条件。
9.3 原子事件的实例
(1) 解一元3次方程事件
在博文“解一元高次方程的任务树”中,我们用了一个具体的方程:求f(x)=x3-5x2+16x-80=0的根,这只对应于相应原子事件的终结数据的一条记录。现在,我们将该问题普及为“解一元3次方程”问题:求f(x)=a3x3+a2x2+a1x+a0=0的根。显然,对于每一组(a0,a1,a2,a3),都有一个确定的方程,都可以用弦截法求出它的根。于是,就有如下数据库模型:
x0,x1,x2,x3, root
数据项root即为方程的根。这样,以此数据库作为终结数据,解一元3次方程的程序过程就是求解它的原子事件。该事件的任务树如博文《解一元高次方程的任务树》中图7.7所示。
(2) 求立方体的体积与面积事件
设立方体的长、宽、高为a、b、c,则其体积为v=a*b*c,ab边组成的矩形面积为Sab=a*b,bc边组成的矩形面积为Sbc=b*c,ca边组成的矩形面积为Sca=c*a。于是就有数据库模型:
a,b,c,V,Sab,Sbc,Sca
求解该终结数据的程序过程就是一个原子事件,该原子事件由三个任务组成:主任务Cube接收a、b、c后调协作任务,协作任务Vol求体积,协作任务Area求面积。
(3) 录入员工档案事件
这个事件显然是原子事件,终结数据就是员工档案。数据库模型为:
工号,姓名,性别,其它属性…
建立员工档案一般都只有录入的方法,所以事件的程序相对简单,可能是单任务事件,也可能是多任务事件。辟如,令主任务接收数据,协作任校验数据(如不得有相同的员工工号,姓名要限长,等等)。
(4) 录入学生成绩事件
这个事件与“录入员工档案事件”的操作差不多,但终结数据模型却有不同。本原子事件的终结数据模型为:
学号,科目,成绩
这里由“学号”和“科目”组成关键字,两者缺一不可。而员工档案库的关健字只有“工号”单个数据项,而且会有许多属性数据项。这是两类不同性质的数据库,后面会有讨论。本事件也可能是单任务的,也可能是多任务的。
(5) 记录零件加工事件
在工厂的生产线上,工人加工的合格零件需要登记。这涉及到:
生产日期,机床代号,工人工号,零件型号,加工方式,零件数量
显然,这就是“记录零件加工事件”的数据库结构。通俗地讲,这个数据库结构的数据项分别对应于:
时间—生产日期
地点—机床代号
主体—工人代号
对象—零件型号
方法—加工方式
结果—零件数量
上述对应关系可翻译为:在“生产日期”于“机床代号”上,由“工人代号”采用“加工方式”生产了“零件型号”合格品“零件数量”个。这里所谓“加工方式”,可能是:车削,铣削,钻孔,磨削,…。
这里引出的“时间”、“地点”、“主体”、“对象”、“方法”、“结果”,在后面也将会有进一步的讨论。至于组成本原子事件的任务,亦可以有“数据录入”和“数据校验”等任务。
(6) 借书登记事件
读者到图书馆借书,当然要做登记。一般而言,借书登记库由如下数据项组成:
借书日期,管理员代号,读者代号,图书编号,还书日期
上述数据项依次对应于:时间、地点、主体、对象、结果。这里将执行借书的“管理员代号”作为“地点”来对待,似乎有点费解。其实并不难理解,某管理员在某计算机上录入借书记录,显然这是“借书”操作所发生的“地点”。至于是在哪一台计算机终端录入并不重要,是由哪一位管理员借出去的到是需要登记的,所以“管理员代号”就属于本事件发生的“地点”。此外,将“还书日期”作为“结果”似乎也不完善。由于规定每位读者每次借阅某编号的图书只允许借一本,所以不需要“借书数量”数据项。到时读者来还书就登记“还书日期”。由此可见,“借书事件”就是录入一条记录,填写“还书日期”属于“还书事件”的操作。
本事件同样有“数据录入任务”、“数据校验任务”,可能还有“借书规章检查任务”。
(7) 购物登记事件
人们去商场购物,先是挑选商品,然后付款提货。商场的计算机系统会登记所售出的商品及其数量和金额,所以就有数据库结构:
时间,商品代号,数量,金额
该事件可以是单任务的。接收商品代号(读商品上的条码,可以独立为一个任务)和数量,然后计算商品金额=数量*价格。商品价格在“商品属性库”中,不必在这个“购物登记库”中冗余出现。最后写“购物登记库”。
在“购物登记库”中,每一条记录只登记一种商品(商品代号)的数量和金额。要计算顾客“应付款”,还必须将顾客所购全部商品的“金额”累加。这应该是另一个称之为“付款输出”的原子事件,其终结数据是屏幕显示和打印输出的数据,屏幕显示的数据结构为:
已收金额,应付金额,找回金额
现金付款时,应该接收顾客所给钱数(已收金额),然后减去应收金额,就是应找回给顾客的钱数(找回金额)。至于打印输出的小票,上面还应列出顾客所购每种商品的价格、数量和金额,最后是应付款。这里屏幕显示和打印输出的不是同一个结构的数据,说明有两个终结数据。这没关系,同一个原子事件允许拥有一个以上的终结算据,这在上面已做过说明。
这里两个原子事件的处理有先后顺序,“购物登记”在先,“付款输出”在后。它们之间存在数据加工的“工序关系”,相关概念今后还会叙述。
(8) 交易委托事件
股民去证券部或通过网络终端买卖股票,都要递交交易委托数据,这些数据都是由证券营业部传送给交易所,然后在交易所的主机上撮合成交的。这里,作为股票交易的第一个事件就是“交易委托”事件,其终结数据也是数据库,结构一般为:
委托时间,券商代号,证券代号,投资者代码,买卖标志,委托股数,委托价格
上述各数据项中,“委托时间”是由系统生成的,“券商代号”也是自动写入的,“投资者代码”是刷卡输入,其它数据项都是手工录入的。所以,本事件可以是单任务的,也可以分划出一个“读卡”任务。
9.4 事物与数据库
我们看到,原子事件的概念并不新鲜,就是一个程序模块。就原子事件而言,重要的是其拥有的终结数据,建立了终结数据模型,才能确立原子事件。数据库是终结数据的直观表示,数据库的数据项又是事物的信息化表示。接下来,我们将花费相当多的篇幅,来讨论事物和数据库。
由上面的实例可以看出,有六类基本事物参与原子事件的活动,它们分别是:
1) 时间t(time)
事件发生的时间,任何事件的发生总处于某个时间,并且总会在某时刻处理结束。通常都是记录事件处理结束的时间,
2) 地点p(place)
事件发生的地点,任何事件的发生总处于某个地点。一般也是记录事件处理结束时的地点。
3) 主体s(subject)
引起事件发生的事物,没有它事件是不会发生的。所以,任何事件都必定有主体事物参与。
4) 对象o(object)
事件发生过程中主体事物所作用的对象事物。辟如“学生学习功课”的“成绩”,“学生”是主体,他考试“功课”的“成绩”,“功课”是对象。
5)方法m(method)
事件发生过程中,主体作用于对象的方法。方法描述了主体和对象之间的关系,决定事件的性质,相同的主体和对象会因方法的不同而会是不同的事件。辟如,“张三打李四”和“张三和李四做朋友”显然是两个不同的事件。
6)结果R(Results)
事件的发生总会结束,总会产生结果。结果是对事件被处理后的描述。“作家写小说”的成功优劣,“工人车削零件”的合格品个数和废品个数,“顾客购买商品”的价格和数量等等都是结果。
注意,这里所说“参与事件的基本事物”中的“事件”,是指现实世界用户需求中的事件(简称“现实事件”),不一定是上面定义的信息世界计算机系统中的事件(简称“信息事件”)。信息事件的功能是生成和记录现实事件发生后的数据。所以,这两者既有区别又相互依存。辟如“录入学生成绩”是现实事件,它记录相应的现实事件“学生学习功课”的成绩。又辟如“录入员工档案”是信息事件,而现实事件则是“员工形成自己的档案”。人们的人生轨迹当然是人们自已形成的,信息事件只不过是将人们的人生轨迹档案存入计算机。由于这两者是依赖共存的,所以今后经常就不加区分地都说成是事件,只要记住数据库存放的是现实事件的数据就可以了。
实际上,一个现实事件总可以用一个“主-谓-宾”短语来描述。“时间”和“地点”都是状语,“主体”和“对象”分别为主语和宾语,谓语即是“方法”,“结果”即为结果状语。
集合(t,p,s,m,o,R)称为事件的“基本事物集”。这里将结果以大写字母R表示,是因为结果可能是不同类别的事物集合,而其他五类事物都是单纯的该类事物。相关概念后面还会讨论。显然,结果事物是同其它五类基本事物不同的,严格地讲其不属于事件的参与者。可以看出,结果事物同其它五类基本事物之间存在约束与被约束的关系,记为:
(t,p,s,m,o) R
上式是基本事物之间的一个基本关系,(t,p,s,m,o)称为基本事物集的约束元组,R是被动的,其它基本事物才是主动的。对于s,m,o作为约束事物可能比较好理解,它们毕竟是“主-谓-宾”的成分,结果状语就是由它们作用得出的。实际上,t和p也很重要,一旦事件发生了,t和p同约束元组中的其它事物都处于同等地位。辟如“顾客购买商品”这个事件,同一种商品在不同商场(地点)的价格(结果)可能就不一样,不同的季节(时间)价格也会不一样(换季大甩卖)。
总之,就对R的约束而言,约束元组中的基本事物地位是平等的,称约束元组中的事物为约束事物,R中的事物为被约束事物。
定义了事件的基本事物集,将基本事物集与数据库联系起来是很自然的,从中可以得出终结数据的某些特征。我们将会看到,基本事物集与数据库之间还是有很大区别的,关系数据库毕竟要遵循关系代数的要求。
记录原子事件处理结果的数据集合是关系数据库,其关键字是基本事物集约束元组的子集,结果数据项完全函数依赖于关键字。
上述结论描述了基本事物集和关系数据库之间的关系。实际上,以变量表示的基本事物集与数据库已经很接近了,差别在于约束元组中的事物不一定全部都能成为关键字部分的数据项,而所需要的结果事物到是全部都可以成为非关键字部分的数据项。
众所周知,关系数据库模型由两部分数据项组成:关键字部分和非关键字部分。令K代表关键字部分,U代表非关键字部分,显然K和U都有一个以上的数据项。按照关键字的定义,K是能唯一地标识数据库记录的数据项最小元组,用函数依赖关系可表示为:
K U |K|≥1,|U|≥1
即数据模型(K,U)作为一个关系模式,上式就是满足该模式的记录集合上的一个完全函数依赖。通俗地讲,在关系数据库上,K的每一组值都唯一地决定了U的一组值,U可能有相同值,但K决没有相同的值,最终(K,U)(数据库记录)仍不会有相同值。我们称K中的数据项为自变项,U中的数据项为因变项。根据上面的讨论就有:
K (t, p, s, m, o)
U=R 9.1
K U |K|≥1,|U|≥1
上式也可以说成:自变项必定都是约束元组中的变量,结果事物R都是因变项。这里对于R中的变量很好处理,凡认为需要记录下来的原子事件的结果事物,都可以作为因变项放在数据库模型中,有一个算一个。关键是约束元组中事物的裁定,有时可以作为自变项,有时又不能作为自变项,如何来决定呢?约束事物中起不到自变项作用的事物都不能参与组成关键字,结果事物对其是没有函数依赖性。将起不到自变项作用的约束事物去掉,使关键字成为能满足函数依赖的最小元组。但无论如何,不可能将全部约束事物都去掉,总有|K|≥1。此外,被略去的约束事物虽然不能充当自变项,但有的数据库设计者还喜欢保留之,这种情况下就称它们为附属项,因为它们不属于R,也不好称之为因变项。
在上面讨论的基础上,现在要结合事物在数据库中的表现,讨论约束基本事物的单纯性和结果事物的并列性。由于自变项都是约束基本事物,因变项都是结果事物,单纯性和并列性就直接由自变项和因变项来体现。
(1) 约束基本事物的单纯性
如式9.1所示,约束元组中的基本事物都有资格成为关键字的一部分。当约束基本事物参与组成关键字时,组成该约束基本事物的自变项可能不止一个,可能是由多个自变项共同表示的,它们之间的关系是什么呢?
多个自变项的“逻辑与”组合表示同一个约束基本事物,该“逻辑与”的最小组合参与组成数据库的关键字,称之为约束基本事物的单纯性。
上述断语的意思应该是清楚的,尽管有多个自变项表示同一个约束基本事物,但它们之间是以逻辑与的关系共存的。辟如前面“求立方体的体积与面积”事件的数据库结构中,边长a,b,c都参于组成关键字,每一组(a,b,c)都决定了结果(V,Sab,Sbc,Sca)的值。但a,b,c都是主体事物,它们的逻辑与构成了主体基事物。所以不能说有3个主体基事物,只能说有3个事物组成了主体基本事物。是多个自变项表示同一个约束基本事物的形式。所谓“逻辑与”的最小组合,即逻辑与关系式中没有多余的自变项,或者说是去掉了起不到函数决定作用的数据项后的逻辑与关系式。辟如“A·B·C”和“A·B”都能代表同一个主体基本事物,则应该以“A·B”参与组成数据库的关键字。从函数依赖的角度来讲,约束基本事物函数依赖于最小的这种“组合”。现在我们明白为什么总说参与原子事件的是六类“基本”事物,而不简单的称六个事物,就是因为每一类基本事物的表示都可以不止是一个数据项。
将上述情况说成是“约束基本事物的单纯性”,其本质意义是说:尽管表示同一约束基本事物可能会是多个自变项的逻辑与,但参与同一个原子事件的该类约束基本事物还是只能有一个逻辑与表达式,即t、s、b、m和o各自最多都只有一个逻辑与表达式。下面分别来讨论各类约束基本事物的单纯性。
1) 时间t
同一个原子事件不可能在两个时间结束,这是毫无疑义的。但表示时间的自变项可以是多个,如“年月日·时分秒”,“年月日·时分秒·顺序号”等等。这里“年月日”、“时分秒”、“顺序号”都是自变项,它们的逻辑与才能表示原子事件的时间基本事物t。“顺序号”实际是更为微观的时间,当某种场合并不需要真正确切的时间,但却要求记录原子事件发生的先后顺序时,辅之以“顺序号”自变项来表示是很科学的。
2) 地点p
与时间t一样,同一个原子事件不可能在两个空间地点被处理结束。同样,表示空间的自变项也可以是多个,如“国家·省份·城市”,“省份·城市”等都是为了准确地表示“城市”这个空间位置,当相应数据库在一个国家内使用时,用“省份·城市”就可以了,用“国家·省份·城市”则多余了“国家”这个数据项。
3) 方法m
方法约束基本事物有点特殊,对于任何原子事件,表示方法的自变项都只需要一个数据项,不存在几个自变项逻辑与的情况。因为方法m表示的是原子事件的性质,其是一个常量,仅当几个原子事件合用同一个数据库时才需要代表方法的自变项,此时用一个自变项来表示也已经足够了。
4) 主体s
这里关键是要区分“个体”和“群体”的概念。说“顾客选取商品”,主体和对象都是个体;说“旅游团选取商品”则主体“旅游团”就是群体性的主体。尽管这个群体是由“旅游者”个体组成的,但在数据库中的相应数据项却只能是代表这个群体。这里的“群体”同“多个自变项之间的逻辑与”是不同的两个概念,“个体”或“群体”都可以用“多个自变项之间的逻辑与”来表示,也都是原子事件中唯一的那个主体基本事物。
5) 对象o
与主体s类似,也可以由“群体”充任对象基本事物,且也可以用“多个自变项之间的逻辑与”来表示。
(2) 结果事物的并列性
这个小标题中是“结果事物”而不是“结果基本事物”,这两个概念是有区别的。结果事物的全体才是结果基本事物,一个原子事件也只有一个结果基本事物,却会有多个结果事物。因此,只有对“结果事物”才有可能讨论其并列性。
此前,我们一直以大写的R表示结果基本事物,就是因为R是结果事物的集合。在同一约束元组的作用下,原子事件被处理后会产生多方面的结果。辟如“工人车削零件”会产生合格品,也生产废品,还有如材料消耗,动力消耗等等伴随的结果,这些结果对原子事件都是有意义的度量。数据库的作用就是为了记录原子事件被处理后生产的结果,而结果事物在数据库中是以因变项来表示的。那么,这些代表结果基本事物的因变项是否也可以逻辑与呢?回答是否定的。
数据库中的每一个因变项都代表一类结果事物,他们的“逻辑或”代表被记录的结果基本事物,称之为结果事物的并列性。
上述断语正好同前述的 “约束基本事物的单纯性”相反。表示结果基本事物的因变项也可以不止一个,但这些因变项都是各自独立的,他们的逻辑与是没有意义的。所有的结果事物的集合是结果基本事物,而数据库的因变项个数总是有限的,只记录我们感兴趣的那部分结果事物,它们全体组成了结果基本事物。从原子事件产生的结果事物中挑选出一部分来作为数据库的因变项,相当于说“结果事物(因变项)逻辑或”代表了结果基本事物。
上面是从基本事物用数据项表示的一般规律来讨论单纯性和并列性。作为组成关键字的约束基本事物的表示,其自变项逻辑与的关系式愈小愈好。今后,凡说约束事物就是指约束基本事物,因为他们是单纯的;凡说“自变项”就是指“自变项逻辑与关系式”中相应的约束事物;凡说结果事物就是指结果基本事物的一部分,因为他们是并列的。
对于关系数据库,我们已经知道其关键字中的数据项尽在原子事件的约束事物中,非关键字中的数据项则尽在结果事物中。并且,参与组成关键字的约束基本事物都是单纯的,非关键字中的结果事物都是并列的。本节将进一步讨论参与组成关键字的约束事物,并根据它们所起的不同作用,将数据库划分成个性库和共性库两类。
(1) 作用事物
如前所述,原子事件的发生是因为主体作用于对象,如果没有主体s作用于对象o,也就不会有原子事件的发生,通称原子事件的主体和对象为“作用事物”。其他约束事物时间t、空间p和方法m都是伴随原子事件的发生而存在的,结果事物R则是伴随原子事件的处理而产生的。换句话说,没有作用事物的存在,其他各类基本事物也不存在。
(2) 个性库与共性库
数据库的关键字中必定含有原子事件的作用事物。关键字中仅含有一个作用事物的数据库称为个性库,否则就称为共性库。
上述结论的意思是很清楚的:关键字中必须含有作用事物,至少含有一个,最多也只能含有两个。首先我们来说明结论的前半部分,即关键字中必须含有作用事物。假定关键字K中没有作用事物,根据9.1式,K中还可以含有时间t、空间p和方法m,K应该函数决定原子事件的结果事物R,即有(t,p) R。现在只要说明这个函数依赖关系是不成立的,则我们的结论就成立。推翻这个函数依赖关系只要举出一个实例就可以了。试想同一个时间和空间发生的原子事件不计其数,辟如同一天到同一个商场去购物的顾客就有数以百计,而且被购买的商品也是各种各样。这都可以用原子事件“顾客购买商品”来概括,主体是“顾客”,对象是“商品”。如果记录该原子事件结果的数据库关键字中既没有“顾客”也没有“商品”,只有时间和商场代号,那么每条记录中的“数量”和“价格”就弄不清是什么意思,这样的数据库显然是一堆毫无意义的数据集合。又辟如某公司的员工集体去体检,如果记录员工体检结果的档案数据库的关键字中没有代表员工的数据项,这份体检档案也只是废纸一堆。由此可见,任何数据库的关键字中都必须含有作用事物,否则R同K之间的函数依赖关系就肯定不成立。
结论的后半部分实际是关于个性库与共性库的定义,但也需要说明:存在只有一个作用事物的关系数据库。我们也只要举出一个正面的例子就可以了。辟如上面的“员工体检的档案资料”,这个原子事件的现实事件是“员工形成自己的档案”。事件的主体是“员工”,对象是员工“自己”,所以不需要对象事物参与关键字。故相应数据库的关键字中只有主体“员工”这一个作用事物。个性库的例子很多,记录实体事物特征属性的数据库都是个性库。
共性库的例子也很多。辟如“学生学习功课的成绩”,“顾客购买商品的数量”,“工人加工零件的件数”等等,这些原子事件都必须用共性库来记录,主体和对象都必须参与关键字。所谓“共性”,就是说必须由“主体”和“对象”共同决定“结果”,缺一不可。
(3) 个性事件与共性事件
根据终结数据的性质,将原子事件也分为两类。终结数据为个性的称为个性事件,为共性的称为共牲事件。所谓个性事件或共性事件当然都是原子事件,因为只有原子事件才拥有终结数据。这样划分原子事件当然是有道理的,因为现实事件是为了得到作用结果,信息事件则是记录作用结果,即生成终结数椐。
上面把基本事物集与数据库相联系,实际是将现实世界的事物信息化。在计算机软件系统中,对事物的信息化有两种方法。有的事物需要详细地描述其特征属性,辟如“总经理”,多数情况下都要记录其性别、年龄、身高、体重、相貌等等特征。一个具体的总经理必须由一系列必要的特征才能被确定,象这样被信息化的事物我们称之为虚事物。也还有不需要在系统中描述其特征属性的事物,辟如“电话号码”、“颜色”、“长度”、“重量”在多数场合下就是如此,不需要做进一步的描述,称在系统中这样被信息化的事物为实事物。形式地讲:
在计算机软件系统中,需要借助其它事物的描述才能被确定的事物称为虚事物,否则就是实事物。描述虚事物的事物称为虚事物的属性。
这个定义是递归的,是以事物来定义事物。但在系统的应用中,这样的定义已经足够了。我们并不是要真正地去追究事物的虚实,需要的是如何信息化地描述事物。现实世界的事物在信息世界就只分为这两大类,不是虚的就是实的,没有第三类。哲学上称呼的“实体”,应该属于虚事物。
说描述虚事物的事物是虚事物的属性,或者说是虚事物的特征,实际细追究起来也不一定准确。身高、体重是人的特征,但电话号码是身外之物,就不好说其是人的特征,而身高、体重、电话号码都可作为人的属性。还是那句话,我们是为了在系统中能信息化地描述事物,将描述虚事物的事物统称为虚事物的属性就可以了,一种说法而已,别的就不用太在意了。
由定义可知,事物的虚实也不是固定的,要看使用场合。辟如“电话号码”在许多场合下都是以“实事物”的身份出现,但有些场合它却又以“虚事物”的身份出现,需要描述它的“长度”,各位或几位号码组合隐含的“意义”(如“01”是北京的区位号,“0755”是深圳的区位号)等等“特征属性”。原则上讲,现实世界的事物都有自己的特征属性,就看是否需要在计算机系统中描述这些特征属性。
在系统中,表示实事物类只需要一个数据项,描述虚事物类则需要一条数据库记录。数据项的一个值对应于一个实事物,数据库的一条记录则对应于一个虚事物。
事物的标识符是由计算机能识别的符号串组成的,其能唯一地标定该类事物。
标识符是一个符号串,连续函数中的变量就是事物标识符的一类应用。标识符出现在数据库中又被称为数据项,出现在其它地方时则称为变量。实事物是不需要借助其它事物描述的,故实事物的标识符可以唯一地标识其自身。虚事物需要借助其它事物来描述它,要用一个数据库来存放描述它的事物,因此真正标识虚事物的是数据库记录。
虚事物也需要一个标识符,其实际是作为虚事物属性全体的代表,是名义上的标识符,称这样的标识符为虚事物的标识码。
最常用的标识码是字符/数字编码,例如员工代号、学生代号、身份证号、零件代号、汽车牌号等等,字符/数字编码总是可以做到无重码的,其也就具备了作为标识码的资格。
标识符(标识码)是符号串,其所表示的实际是一个事物类,其取值的定义域是根据所代表的事物类来决定的,这类事物的集合就是相应标识符的定义域。由此可见,具有相同属性类(或都没有属性)的事物形成一个事物类,其用同一个标识符,标识符的每一个值对应一个具体的事物。
9.5 结束语
本文的标题是“原子事件”,然而却花了大量的篇幅去叙述事物和数据库。有关事件的概念,在后续的博文中还会有进一步的叙述。而原子事件的终结数据,是确立原子事件的关键。数据库可以规范地代表终结数据,确立了数据库结构,就可以确立原子事件。
这里一再强调要“确立原子事件”,因为原子事件是构造系统结构树的基石。将系统划分成事件后,接下来的工作就是设计算法和编码,都是软件专业的规范工作,况且我们还规范成了任务树和作业树。所以,对于较大系统的软件开发,最难的就是构造出系统结构树,而确立原子事件则是构造系统结构树的关键。
如前所述,确立原子事件的关键是建立数据库(终结数据)模型。那么,数据库模型又是从何而来呢?从用户需求中来。于是就涉及到系统分析,要由用户需求建立数据库模型,任何软件工程方法的需求分析或系统分析都是从这一步开始的。辟如UML分析方法“类图”的主要成份就是数据库模型。又辟如ER方法,也是先建立数据库模型,理出实体之间的关系。所以,本文关于事件和数据库的内容,对树型软件的系统分析十分重要。