10事件树

《树型软件工程方法》之系列博文10

事件树


 

 

 

 

 

TREESOFT


                             目  录

10 事件树. 1

10.1 等效处理法.... 1

10.2 高级事件与事件树.... 1

10.3 遍历编程.... 2

10.4 工序关系.... 3

10.5 原子事件的插入与删除.... 5

10.5.1 原子事件的插入.... 5

10.5.2 原子事件的删除.... 7

10.6 精确等效与广义等效.... 8

10.7 等效集的形成理念.... 9

10.8 事件范畴的限定.... 10

10.9 系统及其结构树.... 11

10.10 项目.... 14

10.11 结束语.... 14


中国人为什么不可以有自己的软件工程方法与开发工具平台!

这是介绍《树型软件工程方法》的系列博文,请按文章标题所带的编号顺序阅读,否则你会看不懂本文。

10 事件树

    我们曾讨论过两类结构树,表示任务结构的作业树,和表示事件结构的任务树。本文将要介绍树型软件中的第三类结构树--事件树,它是比事件范畴更大一级、称之为系统的程序模块的结构树。

10.1 等效处理法

    在日常生活中,我们总是将某件大一点的事情分划为几件较小的事情,将较小的事情再分划成更小的事情,直至最后的事情可以直接产生我们所需要的事物。譬如要组建一个公司,自然是要策划相应的管理部门与业务部门。要组建一个工厂,则要策划相应的管理部门与生产车间。我们规范地将“事情”定义为“事件”,将这样处理事件的方法称为“事件的等效处理法”,形式地说:

    设h是一个事件,如果h的处理是通过将其分划成对事件 e1e2,…,的处理来实现的,则称h事件集合E={eii=12,…,nn2}之间存在等效处理关系。h称为高级事件,E称为h的等效事件集,记为h~E

    上面这段叙述称为高级事件的等效处理法,简称等效处理法,描述了单个事件h事件集合E之间存在的等效处理关系。事件处理的等效现象是普遍存在的,辟如顾客购买商品是一个事件{顾客选取商品,顾客付款提货}就是与之等效的事件集。又辟如加工零件A”{车削A,铣削A,电镀A}之间也是等效的。从某种意义上讲,等效处理法也是分治方法,都是采用将“大的”分划成“小的”的方法来“治理”事情。只不过等效处理法没有分治法严格,它并不要求“小事件”与“大事件”同型,也没有反照递归求解的要求。

    这里,等效集E中的元素必须至少有两个。如果E中只有一个元素,则h~E就是h=E,这样的等效处理是没有意义的。这里还要注意,等效关系h~E并不表示E可以替代h,这里是“等效”而不是“等于”。后面将会看到,hE都有各自的功能职责,谁也替代不了谁。

    由等效处理法可知,高级事件是可以被等效处理的。如果等效事件集中还有高级事件,又可以将其进行等效处理。换句话说,对于高级事件的等效处理是递归地进行的,直至最后的等效事件集中没有高级事件。既然等效事件集中的元素都是事件,而且又不是高级事件,说明还存在不能被等效处理的事件,这类事件就是原子事件。原子事件的功能是封闭地加工生成终结数据,这项功能是不可能由多个事件来完成的,所以原子事件是不能被等效处理的事件

10.2 高级事件与事件树

    显然,按照等效处理法递归地处理高级事件,就可形成一棵数学树。由于树中的节点都是事件,故称之为事件树。图10.1是一棵事件树的示意图,事件节点以分为上下两部分的矩形框来表示,矩形框的上半部填写事件简称,下半部填写事件的标识符。图10.1的事件树中存在如下等效关系:

        h0~{h1a3h2}

        h1~{a1a2}

        h2~{a4a5}

    由图10.1可以看出,事件树的叶节点都是原子事件,非叶节点都是高级事件。这个特征是由事件树的形成原理所决定的,凡高级事件都必须被等效处理,不能被等效处理的都是原子事件,当然都是事件树的叶节点。极端情况下,事件树的根节点就是原子事件,意味着相应事件树只含有一个事件。


10.1 事件树示意图

    高级事件等效处理的物理意义是什么?或者说,高级事件等效处理的现实意义是什么?这个问题涉及到用户需求。通俗地讲,高级事件是一个概括性的概念,或称为概括性事件。譬如“顾客购物”就是一个高级事件,他概括了顾客在商场购物的所有行动:“选取商品”、“付款结算”。所以有等效关系:“顾客购物” ~{“选取商品”,“付款结算”}。又譬如“总经理分管的部门”~ {“人事部”,“财务部”,“办公室”}。这样的例子比目该是,后面还会有更详细的例子。这些例子的共同特点是:

    高级事件自身无法生成我们所需要的终结数据,必须逐级等效处理高级事件,及至显露出原子事件才可以计算出终结数据。

    高级事件的结构树也是任务树,如同原子事件的结构树是任务树一样。高级事件是概括性事件,他在事件树中的作用是什么呢?高级事件的基本功能是调度儿子事件的运行。这由上面的例子也可以看出,“顾客购物”先调度 “选取商品”运行然后“付款结算”运行;“总经理”调度“人事部”、“财务部”和“办公室”的工作。在计算机软件系统中,调度也是由数据实现的。调度数据也是由程序加工生成的,高级事件就是生成事件树中调度数据的程序模块。所以,高级事件也是由任务组成的,其结构树当然也是任务树。

    至此,我们就将事件的定义、高级事件的定义、原子事件的定义统一了。高级事件的功能是生成调度数据,原子事件的功能是生成终结数据。调度数据是调度事件运行的,当然不会离开系统,也就不是终结数据。终结数据是用户所需要的数据,俗称生产数据,所以又可以说原子事件是生产性事件。

10.3 遍历编程

    事件树作为计算机程序的一级结构树,各个事件节点都是程序模块。与任务树和作业树相同,遍历事件树就可以将树中的事件模块安排在程序中。事件树遍历编程规则为:

    自上至下、从左向右遍历事件树。每进入一个事件节点,就遍历编程相应的任务树。

    对图10.1的事件树遍历后,就得到下面的事件节点顺序,继而遍历相应的任务树和作业树,最后生成程序。

        //根节点//

        h0(相应任务树的节点排列)

        //高级事件//

        h1(相应任务树的节点排列)

        //原子事件//

        a1(相应任务树的节点排列)

        //原子事件//

        a2(相应任务树的节点排列)

        //原子事件//

        a3(相应任务树的节点排列)

        //高级事件//

        h2(相应任务树的节点排列)

        //原子事件//

        a4(相应任务树的节点排列)

        //原子事件//

        a5(相应任务树的节点排列)

10.4 工序关系

    本节将要讨论事件树中存的一种重要关系事件之间的工序关系。

       (1) 工序关系的定义

    终结数据是生产性数据,是我们所要求解获得的结果数据。在较大一点的系统中,结果数据的生成有的要经过多个原子事件的加工处理,这就涉及到终结数据被加工处理的顺序,亦即工序关系。

    如果原子事件B要读取原子事件A的终结数据加工生成自己的终结数据,则称这两个原子事件之间存在工序关系,记为AB A称为前导(事件)B称为后继(事件)

    工序关系在日常生活中是随可见的。顾客付款提货就必须在顾客选取商品之后才能执行,否则顾客就无法付款提货。又譬如在我们常用的Word系统中,为了“复制”、“剪切”或“删除”某字符串,首先必须将字符串“涂黑”,然后才可以做相关操作,否则相关操作的菜单都会是灰暗不可用的。这里就存在工序关系,“涂黑”原子事件生成涂黑字符串后的画面终结数据,“复制”、“剪切”或“删除”这三个原子事件运行后分别生成相应的画面终结数据,它们将“涂黑”生成的终结数据再加工生成自己的终结数据。日常的工作安排,系统调度都存在这种情况。最为规整严格的如工厂对零件加工工艺的安排,那是以工艺文件的形式将加工次序固定下来的。计算机系统要管理现实世界,事件处理的工序关系就应该在系统中反映出来。

    由工序关系的定义可知,终结数据是在原子事件之间流动的,即在事件树的叶节点之间流动。为了与作业树和任务树一致,这里也规定终结数据自左向右流动。最左的那个原子事件处于工序关系链的源头,他的前导数据是由系统外部输入的。终结数据是产性数据,它在原子事件之间流动,形成了事件树中的生产数据流。注意,原子事件之间可能存在工序关系,也可能不存在工序关系,存在与否是由需求决定的。

       (2) 工序关系的转移

    在事件树中,存在工序关系的原子事件不一定在同一个等效集中,即不一定是兄弟关系。譬如有工序关系:abab都是原子事件。然而ab并不是兄弟,有等效关系:h~{axy}g~{buv}。换句话说,高级事件hg都无法作出安排来实现ab之间的工序关系,因为hg都只能调度自已的儿子。这种情况下,能保证实现工序关系ab的办法只有一个,即令hg。工序关系hg可以由hg的父亲来调度实现,即先运行h子树再运行g子树。这种以事件子树之间的工序关系来实现原子事件之间工序关系的现象,称为工序关系的转移。为此,我们将工序关系的定义修改为:

    在等效事件集内,若要处理事件 b,必须先处理事件 a,称ab之间存在工序关系,a为前导(事件),b为后继(事件),记为a→b

    修改后的定义就没有限定工序关系只能由原子事件的运行来实现,工序关系既可以在原子事件之间标记,也可以在高级事件之间标记,还可以在高级事件和原子事件之间标记,只要它们是在同一个等效集内。然而,无论工序关系在那两个事件之间标志,本质都是为了保证终结数据的加工顺序,工序关系的标志只是为高级事件调度儿子事件提供依据。

        (3) 工序链

    如果说等效关系描述了事件之间自顶(根)向下(叶)的纵向关系,工序关系则描述了兄弟事件之间的横向关系。将工序指明在等效事件集内是很自然的,只要弄清楚了等效集内各事件之间可能存在的工序关系,就等价于获得了整个事件树内各事件之间的工序关系。因为事件树中每一个节点代表的都是一棵子树,两节点之间的工序关系也代表了以它们为根的子树之间的工序关系。

    工序关系与等效关系的最大区别是:除原子事件外,任何高级事件都必定有对应的等效事件集;工序关系则不同,无论是高级事件之间还是原子事件之间,以及高级事件与原子事件之间都可能存在工序关系,也可能不存在工序关系,存在与否要根据实际情况确定。例如一个集团公司的运输产业娱乐产业之间就没有什么工序关系,机械加工厂的模具制造刀具制造之间也不存在工序关系。

    等效集内存在的工序关系一定是单向无循环链接的。

    所谓链接,即借助于有向线表示的前导和后继之间的工序关系。单向无循环链接限定了等效集内的每一个事件至多只有一个前导和一个后继,并且这样的单前导和单后继链接不会首尾相连形成循环链。假定等效集内存在  A→B→C 这样的循环链,意味着这三个事件都在相互等待前导的处理,而这是永远也等到不到的死循环。既然它们都是等效集内的事件,要么它们都是多余的事件可以被去掉,或者就都能被处理而不会形成死循环,否则就不满足等效关系。由此可见,等效集内是不会有工序死循环的,出现循环链就一定不等效。

10.5 原子事件的插入与删除

    在构造事件树的过程中,经常会碰到事件子树的剪接,这也是树型软件系统结构设计的唯一手段。由于对事件子树的剪接算法比较复杂,而且风险比较大。剪去一枝事件子树相当于删除了一大段程序,接上一枝事件子树则相当于转移了一大段程序。所以,我们只讨论原子事件的增删,逐个增删原子事件,同样会实现事件子树的剪接。

10.5.1 原子事件的插入

    在事件树中插入原子事件,肯定要引起树结构的变化。如前所述,原子事件的插入必须维持事件树中的工序关系,以保证事件树的逻辑结构仍满足需求。

    原子事件的插入首先要确定其是属于哪个等效集的,即事件树中原是哪个等效集需要扩充增加这个原子事件。在事件树中,除根节点外,任何事件能且只能属于某一个等效集。若被插入的原子事件不属于树中任何一个等效集,说明其同根节点是平级的,令其同根节点组成一个新的等效集,增加新的根节点作为它们的父亲,这个原子事件就被插入了。一般新插入的原子事件总属于树中的某一个等效集,这就确定了它的父节点及所在子树,然后分下面六种情况插入。

       (1)插入的原子事件无工序要求

    被插入的原子事件与等效集内任何事件之间都不存在工序关系。这样的原子事件插入最简单,将其作为相应父节点最右的儿子即可,如图10.2中的X节点就是新插入的。


10.2被插入的原子事件X无工序要求

       (2) 插入新原子事件后不会引起工序链分叉

    被插入的原子事件有工序要求,但将其插入后不会使原工序链分叉形成两条工序链,有三种这样的插入。

       a) 头插

10.3 新原子事件X插于工序链首

    新原子事件要求插在原工序链的首位,原工序链上的首事件作为它的后继。如图10.3所示,新节点X没有前导,有一个后继B

       b) 尾插

    新原子事件要求插在原工序链的尾端,原工序链上的尾事件作为它的前导。如图10.4所示,新节点X没有后继,有一个前导C


10.4 新原子事件X插于工序链尾

       c) 中插

    被插入的原子事件需插在两个已经存在工序关系的节点之间,且原为前导的现作为其前导,原为后继的现作为其后继。如图10.5所示,新节点X顺序插在BC之间。

10.5 新原子事件X插于工序链中

        (3) 插入引起双前导或双后继

    被插入的原子事件有工序要求,将其插入后上会产生双前导或双后继,使原工序链分叉形成两条工序链,有两种这样的插入。

        a) 插入产生双后继

    被插入的原子事件要作为现有节点的后继,但该节点原来已有后继。如图10.6所示,新节点X要作为C的后继插入,而C已经有后继D,这就是说C要有两个后继XD。增设 F作为XD的父亲,F作为C的直接后继,使得XD在增添的子树中并列作为C的后继。注意,D原有的后继E要一同移动入新增添的子树中,故E的父亲也换成了F

10.6  插入产生双后继引发增设高级事件

        b) 插入产生双前导

    被插入的原子事件作为现有节点的前导,但该节点原来已有前导。如图10.7所示,新节点X要作为D的前导插入,而D原来已经有前导C。这就是说D将有两个前导CX,处理办法同情况5类似,增添 F作为D的前导,XC连同B都是F的儿子,使得XC并列作为D的前导。

10.7  插入产生双前导引发增设高级事件

    可以看出,上述六种情况插入原子事件的处理方法都保持了事件树中原有的工序关系。前面已经讨论过,等效集中存在的工序关系是单向无循环的工序链。因此,原子事件的插入就只有上述六种情况。

    此外,这里只讨论了原子事件的插入,没有提到的高级事件插入。因为高级事件是不会单独被插入的,只有在原子事件插入过程中需要时,才会引起高级事件的插入,如图10.6和图10.7那两种情况。单独插入一个高级事件是没有意义的,也是不允许的。

10.5.2 原子事件的删除

    从事件树中删除一个原子事件的操作并不复杂,但要关注工序关系可能存在的传递,还要关注该原子事件所在等效集的存在价值。

        (1) 中删

    如图10.8所示。原来事件树的等效集{BCDE}中有工序关系B→C→D,删除原子事件C后就形成了该右侧的事件树。所谓“中删”,即将要被删除的原子事件处于工序链的中间,其既有前导也有后继。将这样的原子事件删除后,仍需保持它原来的前导和后继之间的工序关系。

10.8 中删

(2) 侧删

如图10.9所示,将要被删除的原子事件处于:工序链首端(原子事件B),工序链尾端(原子事件D),或孤立无前导与后继(原子事件E)。这三类原子事件可以随意删除,删除它之后并不影响等效集中其它事件之间的工序关系。称这三类原子事件的删除为“侧删”。

 

 

10.9 侧删

    侧删虽然不会影响等效集中的工序关系,但却有可能引起等效集的撤销,进而引起树结构的变化。如图10.10所示。由于等效集{DE}中只有两个事件,删除E之后仅剩下D,以至于出现了高级事件F只有单个儿子D的无意义的等效处理,所以必须以D替代F。出现这种现象主要是因为执行删除的等效集中只有两个元素,如果有三个以上的元素,即便是侧删也不会出现无意义等效。前面看到,实施中删时也不会出现无意义等效,因为执行中删的等效集中至少有三个元素。

10.10 侧删所引起的儿子替代父亲 (图中看不清的是”D替代F“)

    我们看到,图10.10中以儿子替代父亲的结果,等价于删除了父亲这个高级事件,这有点象是原子事件插入的逆向操作。原子事件的插入引起双后继或双前导时,为了保持工序关系必须增设高级事件。所以,不允许也没有必要单独插入和删除高级事件,原子事件的插入和删除会顺理成章地按排高级事件。从原理上讲,高级事件是管理原子事件的,只有原子事件的存在才有可能需要高级事件来管理。

10.6 精确等效与广义等效

    此前,我们定义过作业树和任务树。作业树中节点之间的关系是“同宗延续”,任务树中节点之间的关系是“协作调用”。这两种关系都是按问题求解的算法逻辑建立的,所以作业树和任务树都有规范的设计方法。而且这两种关系都是自上而下的纵向关系,作业树和任务树中节点之间没有横向关系。

    事件树中节点之间存在两种关系:自上而下的等效关系,和从左向右的工序关系。等效关系是单个高级事件与其儿子们组成的集合之间的纵向关系,工序关系则是等效集内兄弟节点之间的横向关系。这两种关系都是由用户需求决定的,与问题求解的算法逻辑无关,再说在构造出事件树之前还没有分划出所要求解的问题。

    等效关系和工序关系的建立完全依赖于用户需求,等效处理是对用户需求的真实描述

    工序关系描述了等效事件集内兄弟节点之间的关系,等效事件集是由等效处理形成的,说明这两种关系之间存在某种关联。由等效处理法可知,关系式h~E(E={eii=12,…,nn2})仅仅指出了高级事件h和事件集合E之间存在等效关系,并没有给出属于集合E的元素ei需要满足的条件。定义了终结数据加工的工序关系后,原子事件之间就必须按工序关系执行运行的先后顺序。任何原子事件都必定属于某一个等效集,所以等效集中就必须体现存在的工序关系。

    工序关系是高级事件调度儿子事件时唯一必需保持的关系,等效处理必须保证工序关系的运行实现。

    上述结论不仅描述了工序关系和等效关系之间的联系,更重要的是给出了建立等效关系必须遵循的原则,亦即给出了构造事件树所必须遵循的原则。

    如果有h~Eeiei+1(E={eii=12,…,nn2}),称hE之间为精确等效,E称为精确等效集。若E中存在一种以上的工序关系,则称hE之间为广义等效,E称为广义等效集。

    什么叫“一种以上的工序关系”?即等效集内有一条以上的工序链。对于既无前导也无后继的独立事件e,我们也认为是一种工序关系。精确等效是说,等效集内的所有事件都在同一条工序链上,没有第2条工序链或独立事件。广义等效是说,等效集内存在多种工序关系,甚至所有事件都是独立的。

    实际上,现实社会中的等效关系大多都是广义的。例如,由各部委组成的集合与国务院之间是等效关系,但各部委的工作之间并不存在工序关系。公司各部门组成的集合与总经理室之间也是等效关系,但各部门的工作之间并不存在工序关系。公司的具体业务之间可能存在工序关系:必须先开发出计算机系统,业务部门才可以用这个系统;必须先制造出模具,塑压车间才能用模具压制出塑料件;商品必须先上架,顾客才能够选取商品;…。构造相应事件树时,就必须保证这些工序关系。由于原子事件是生产性事件,它总处于管理架构(事件树)的底层,所以工序关系也处于底层或由底层转移至高层。由于高级事件是概括性事件,所以管理架构的上层都是高级事件。

10.7 等效集的形成理念

    我们看到,广义等效十分宽松,这有利于我们构造事件树。如前所述,等效关系是对用户需求中业务关系的真实描述,只要保证工序关系,等效集中可以任意增减事件。那么广义等效又是依据什么规则建立的呢?或者说什么样的事件会聚集在一起形成等效集呢?

    事件的功能分类是形成广义等效集的基本理念。

    上面这句话十分简单普通,为什么还要单列且加粗呢?因为这句话十分重要,是我进行需求分析或系统分析所遵循的基本理念。作业树的设计原理是Tq递归处理,十分严谨而有规律;任务的独立规则也很严谨,但“规则”与“原理”相比已经是弱化了;事件树是采用等效处理法形成的,等效集的形成理念是事件的功能分类,“理念”比“原理”和“规则”更为弱化,这是因为我们的软件设计是从用户需求入手,逐级设计出各级模块的结构树,最后编写程序语句,从宽松的整理到严格的编码是符合设计规律的。但无论如何,有了上面这句话就不会随意地将几个事件放在一起组成等效集,而会是有目的下意识地去组建合理的等效事件集。

    “事件的功能分类”是什么意思呢?首先,“事件”在现实生活中是处理事物的“过程”,在计算机系统中是软件“模块”。过程或模块都具有相应的功能,都是由为实现某种目标的操作所组成的操作集合。既然事件都有自已的特定功能,又依据什么来将它们分类呢?依据人们对事件功能的习惯认定。譬如,人们习惯地认为:银行,保险,证券,典当,担保,信托,借贷,等等都属于金融行业。然而,既是习惯认定,就没有严格的规定或准则。譬如,公路、铁路,船运,航空等等都可以属于交通行业,然而我们国家却单列为:交通部,铁道部,船舶总公司,民航总局,交通部实际只管公路交通。一般来讲,人们对事件功能的分类还是有一个基本共识的,餐饮业和零售业的功能区分是很明显的;计算机硬件行业和计算机软件行业的功能区分也很明显;Microsoft Word中的各主菜单栏的功能区分同样明显。其各主菜单下辖的子菜单也是按“事件功能分类”来归属的,当然也并非是严格而不得变动的。譬如,将主菜单“格式”下辖的子菜单“字体”作为主菜单“编辑”下的子菜单也是可以的,认为字体的格式也属于文字编辑。所以,我们在上面的那句话中只说是“理念”,是人们习惯性的认定,既要忠实地描述需求,又是绝大多数人所习惯认定的。

10.8 事件范畴的限定

    此前,我们讨论过作业和任务的作用范畴的限定。至多含有最后一条控制语句的程序段称为作业,这个定义就限定了作业的程序规模。由同宗延续生成的作业树所形成的程序段称为任务,这个定义也限定了任务的程序规模。程序规模的限定等价于限定了其作用范畴,所以认为作业和任务都是规范模块。事件也是规范模块,它的作用范畴也是被限定了的。

        (1) 原子事件的程序规模是以终结数据来限定的

    封闭地加工生成终结数据的程序模块称为原子事件。

    原子事件的显著特征是拥有终结数据。所谓“封闭地加工生成终结数据”,即自读入原子事件外部数据至加工、输出终结数据的全过程,都是由原子事件独立完成的。由此可见,原子事件的规模是被严格限定了的,程序模块的大小完全依赖于生成终结数据的复杂度,确立了终结数据也就可以确立原子事件。原子事件中既不允许有与生成自身终结数据无关的程序语句,为生成自身终结数据所需的全部程序语句也都应该在原子事件中。

        (2) 高级事件的程序规模是由等效事件集来限定的

    调度儿子事件运行的程序模块称为高级事件

    与高级事件等效的事件集中的事件,都是高级事件的儿子。等效事件集中的元素是有限的,调度他们运行的程序语句当然也是有限的。由此可见,高级事件的程序规模是由等效事件集来限定的。不仅仅是等效事件集中的元素多少,特别是对等效事件集中元素的调度算法的复杂度。

        (3) 将兄弟事件接收相同键盘数据的功能提升至父亲事件中

    事件是由任务组成的,而且经常有事件之间的任务复用。任务复用既可以节省人力,也有利于提高系统的可靠性。但是有一类任务应尽量避免复用,那就是“接收键盘数据”任务。譬如事件AB处于同一个等效集中,这两个兄弟事件都要求从键盘输入相同的数据。按照原子事件或高级事件的定义,接收键盘数据的功能可以独立成任务,然后分别由应AB调用。然而,这就意味着操作员将要两次键入同样的数据,这显然是不合理的。解决的办法很简单,将“接收键盘数据”的功能提升至AB的父亲事件中就可以了。如此处理并不防碍“高级事件调度儿子事件运行”的基本功能,也不违背“原子事件封闭地加工生成终结数据”的功能。这样做等于增加了高级事件的一项功能。

10.9 系统及其结构树

    事件是比任务范畴更大的程序模块,比事件范畴更大的程序模块称为系统,本节将要讨论系统的相关概念。我们将会看到,系统虽然也被称为程序模块,但它的范畴却是不受限制的,这是它与规范模块事件、任务、作业显著不同的地方。

    事件树所表示的程序模块称为系统

    与事件和任务类似,系统也是以其结构树来定义的,即事件树是系统的结构树。显然,系统是比事件范畴大一级的模块,即系统可以(等效处理地)分解出事件。极端情况下,系统可以只含有单个事件,这个事件当然是原子事件。

    尽管系统有自己的结构树,但他却不是规范模块。如前所述,规范模块的程序规模是有严格限定的,是可以按限定条件将其分划独立的。事件树的范畴并不受限,系统的规模也就不受限。虽然如此,但在工程实践中对系统的规模还是有限定的,人们通常根据用户需求按照业务分类的原则来划分系统。所以,系统仍可以是一个独立的模块,事件树就这个独立模块的结构树。

    此前关于事件和事件树没有给出过实例,接下来将通过实例来进一步说明事件、事件树和系统等相关概念。系统的概念己经同需求直接相关了,可以举出的例子当然比比该是,所有已开发或待开发的系统都可以用事件树来表示其结构。为了便于理解,这里以人们十分熟悉的“文本编辑工具软件”为例。由于篇幅有限,我们只简略地讨论该工具软件中的“编辑系统”。

10.11 文本编辑工具软件编辑系统的事件树

    图10.11是某文本编辑工具软件编辑系统的事件树。通常将文本编辑工具软件称为文本编辑系统,典型的如Microsoft Word。这里不称之为“系统”而称之为“工具软件”,是为了避免混淆,因为我们将其所辖的每一栏主菜单所包含的功能分别都称为系统,编辑系统就是其中的一个主菜单栏。图10.11所示的编辑系统事件树,只包括了编辑系统的部分功能,实际的系统应该更全面。此外,图10.11的事件树中添加上了表示工序关系的有向线,箭尾是前导事件,箭头所指是后继事件。

        (1) 编辑系统事件树中的原子事件

        1) a1,选取。a1的功能是为后继的复制或删除作准备的。对于需要复制或删除的字符串,将其“涂黑”即完成了选取的功能。“涂黑的字符串”后的画面即为其终结数据。

        2) a2,拷贝。a2的功能是将选取的字符串另行拷贝一份存放于剪贴板(内存缓冲区),为粘贴做准备。“剪贴板内的拷贝数据”即为其终结数据。

        3) a3,剪切。a3是一个特殊的原子事件,它拥有两个终结数据。首先,a3具有a2的功能,将选取对象拷贝进剪贴板,“剪贴板内的拷贝数据”即为其终结数据。其次,a3还具有a5的功能,将选取对象删除,“删除选取对象后的文本”即为其终结数据。

        4) a4,粘贴。a4的功能是将剪贴板中的字符串插入于光标所在位置。“插入字符串后的文本”即为其终结数据。

        5) a5,删除。a5的功能是将选取的字符串从所在文本中删除。“删除选取对象后的文本”即为其终结数据。

        6) a6,查找。a6的功能是在文本中查找出与给定的字符串相同的字符串,并将其涂黑显示于屏幕。“涂黑的字符串”即为其终结数据。

        7) a7,替换。a7的功能是以给定的字符串替代被查找出的字符串。这里a7含有a6的功能,似乎拥有两个终结数据。实际上只有一个终结数据,即“替换后的文本”。至于“查找”到的字符串,需求并不要求将其涂黑,也就形成不了终结数据。

        8) a8,保存。a8的功能是将当前文本保存至磁盘。“写进磁盘的文本”即为其终结数据。

        (2) 编辑系统事件树中的高级事件

        1) h0,编辑。h0是事件树的根节点,他有四个儿子,即有等效关系:

        h0~{a1h1h4a8}

    从需求的角度来讲,h0涵盖(概括)了三项业务:字符串处理,查找替换和保存,所以与h0等效的事件集中应该只有3个事件。现在有4个事件,是因为省去了高级事件“字符串处理”,它应该是a1h1的父亲。之所以这样做,是为了在不影响事件之间工序关系的前提下,尽量减少控制环节,以便提高运行效率。

        2) h1,粘贴删除。由图10.11可以看出,h1有好几层后代。复制粘贴和删除是完全不相同的两项功能,但他们却都要使用事件a1的处理结果,即他们拥有共同的前导a1。为此,增设了高级事件h1,用以管理h2a5

        3) h2,复制粘贴。按照实际操作,必须先复制,后粘贴,即存在工序关系:复制→粘贴,亦即h3a4h2的功能就是要保证该工序关系的实现。

        4) h3,复制。复制有两种:拷贝复制和剪切复制。为此,增设了h3,用来管理a2a3,以保证a2a3都能是a4的前导。

        5) h4,查找替换。如前所述,h4和他的兄弟a1h1a8各自具有不同的功能。因为存在工序关系:a6a7h4的功能就是要保证该工序关系的实现。

        (3) 编辑系统事件树中的工序关系

    图10.11中共有三对工序关系:a1h1h3a4a6a7,这些工序关系都是由业务需求决定的。在软件系统中,实现这三对工序关系的方法很简单:如果前导没有被运行,则令相应后继的运行菜单灰暗不可用。实现该方法的程序则在前导和后继(他们肯定是兄弟)的父节点中,即由父亲来调度儿子们的运行。所以,图10.11的事件树看上去层数比较多,实际上运行效率并不受影响,因为所有高级事件的控制程序都很简单。

    顺便指出,系统菜单也形成一棵树,称为菜单树。菜单树是与事件树直接相关的,每条菜单都对应着在事件树中一个节点(但是,并非事件树中的每一个节点都要形成一条菜单)。至少有三种形式的菜单:文字显式,操作隐式,图标式。图10.11的事件树中:“查找”和“替换”都对应着文字显式菜单;事件“选取”的执行菜单就是操作隐式的,涂黑字符串的操作就等价于运行了该事件;“保存”既有文字显式菜单也有图标菜单。由于篇幅有限,就不在此详细讨论菜单树了。

        (4) 编辑系统事件树中的生产流

10.12 10.11事件树中的生产流

    我们定义:终结数据依工序关系由原子事件加工处理的线路称为生产(数据)流。图10.12所示即为图10.11事件树中的生产流,共有四条。可以看出,生产流都是在原子事件之间流动的,与高级事件无关。但在事件树中画工序关系线时,允许经由高级事件转移工序关系。此外,图10.12中所有生产流的终点都是原子事件a8,但在图10.11的事件树中却没有画出相应的工序关系,这是为了简洁而省略了。

        (5) 编辑系统事件树中的调度流

    如前所述,事件树中的调度信息只能由高级事件产生,原子事件对外不输出数据。所以,事件树中自根节点至叶节点的每一条通路都是调度流。图10.11中有8个原子事件,共有8条调度通路。

10.10 项目

    在树型软件中,范畴最大的模块就是系统,而且是范畴不受限制的模块。但无论系统的范畴有多大,其都可以划分成规范的事件模块,并形成事件树作为其结构树。由于通常的软件开发都是面向项目的,所以本节还是将“项目”这个并不属于树型软件的概念略加讨论,以方便工程应用。

10.13 文本编辑工具软件的系统树

    图10.13是文本编辑工具软件项目的事件树。这棵事件树没有画出全部事件节点,根节点h0的儿子都不是事件,而是相应子系统的简称与标识符。为了方便应用,我们仍称图10.13所示的结构树为“系统树”,其叶节点都称为系统节点。实际上,他并不是名符其实的系统树,虽然其叶节点都代表相应的系统,但其根节点h0却并不代表系统。理论上也无法构造出真正的系统树,因为系统自身的范畴是不受限制的,任何软件包都可以用事件树来表示。最小的项目可以只含有一个系统,最小的系统可以只含有一个原子事件,最小的原子事件可以只含有一项操作,所以最小的项目可以只含有一项操作。

    系统树虽然是一个不恰当的称呼,但却可以方便项目开发。首先,我们可以根据需求将项目划分为若干系统,等效集的形成理念也适用于划分系统,将功能概念上属于同一类的事件形成一个系统。然后构造出各系统的事件树,各事件的任务树,和各任务的作业树。遍历编程时先遍历系统树,遇到系统节点时遍历事件树,遇到事件节点时遍历任务树,遇到任务节点时遍历作业树,最终就可形成项目的程序。

10.11 结束语

    本文的标题是“事件树”,也可以改为“系统结构设计”,事件树本来就是系统的结构树。

    软件设计进入到系统设计阶段,意味着同用户需求直接相关。所以博文“原子事件”和本文“事件树”中都没太多的软件设计理论,而是从现实世界的需求中归纳和总结出具普遍性的规律。事件就是现实世界中时时刻刻都在发生的CASE,是用户需求中普遍存在的,我们将其归纳为软件系统中的一级过程,系统就是由事件过程构成的。等效处理也是现实世界中普遍存在的现象,无论是社会管理,还是工程实施,乃至自然现象,都是将“大系统”分划成“小系统”。“系统是物质存在的普遍形式。自然界的一切物质客体不仅自成系统,而且又互成系统。…大系统中有小系统,小系统中有更小的系统…”( 陈其荣:《自然哲学》,复旦大学出版社,20052)。我们以事件树作为模型,建立起事件之间的联系,上下级事件之间是管理和被管理的关系。以“事件功能分类”作为形成“等效集”的理念,这也是人们对大大小小的“系统”划分归类的理念。

    树型结构已经是一种数学模型,事件树当然也是一类数学树。我们成功地从用户需求中构造出了事件树,等价于将用户需求以数学语言来描述。

    事件树是用户需求和软件系统之间的跨接桥梁,是表示系统结构的通用数学模型

 

转载于:https://my.oschina.net/treesoft/blog/84308

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值