面向对象已经是程序设计中很基本的一个概念了。一提到面向对象,一些专有名词就会自然的在开发人员脑海中出现,类、对象、继承、多态、抽象、封装等等。至于面向对象的精准定义是什么,也是众说纷纭,开发角度的、哲学角度的。这里并不是对面向对象本质的思考。本文是在先完成一次系统设计后,反过来用面向对象的思想分析进行分析,以期为以后的设计开拓思路。在本文中,首先对所构造的系统作简要介绍。而后再从面向对象的角度来分析这次设计。
下面是该流程设计的功能需求:
1、 可以定义一个处理流程,指定处理流程中每个步骤的可以进行操作的操作者范围,并指定该操作者进行操作的页面,以完成特定的业务操作。当流程达到某个跳转条件时,流程进行步骤跳转。
2、 实例化一个流程,从操作者范围中指定每步的参与人,流程起动。
3、 在流程的每一步,相应的操作者可以进行相关业务操作,同一步中可以有不同的业务操作界面。
4、 根据操作者的操作结果决定流程的跳转状况,流程跳转可以实现从第m步跳到第n步,其中1<=m<=s, 1<=n<=s,s为流程总步数。
而后就是对该功能需求进行系统分析,数据库设计,编码实现。这是一个很普通的基于数据库的应用系统,数据库表的建立对于该系统实现至关重要。数据库表的结构如图一所示。

数据库表设计好后,将每个表映射生成实体类,然后再用代码生成器生成相应的增、删查、改数据库访问类及基本的页面调用,编码添加实现业务类及业务方法,再在页面上对业务进行组合,该系统的开发流程总体是这个样子。面向对象的机制能使代码达到良好的封装,复用性很高,这点也使代码的自动生成更容易实现。
以上所说的开发过程并不是本文的重点,而在图一中表的设计及该设计与面向对象的关系才是需要讨论的。
现在通过对每张表的说明来介绍该系统的运转过程。本次设计选取的数据库是达梦数据库,版本是5.0。
在功能需求的中的第1步,定义流程的功能主要是由FlowType,FlowStep,FlowPage,Business,StepUser五张表构成。

FlowType包含流程类型的基本信息,包括id(流程自增标识)、name(流程名称)、description(流程描述)。

FlowStep包含某个流程类型的具有的流程步骤信息,包括id(流程步自增标识)、flowID(所属流程类型id,关联FlowType的id)、pageID(流程步所在流程页的id,关联流程页的id,流程页是某个流程步中,操作者进行操作的页面)、step(该流程步所在流程的流程步骤数,在一个处理步骤中,有可能存在多个用户在不同的操作页面,故这里一个step中可能对就不同的FlowStep)、ennterType(流程跳转条件,包括所有人已操作跳转、有人操作即跳转、永不跳转,在具体的业务处理中还可以自己强行跳转)。

FlowPage是操作者进行操作的工作页面的信息,包括id(流程页自增标识)、pageName(页面名称,便于在设定时选取流程页面)、url(流程页地址)、inType(传入流程类型,便于定义流程时进行页面筛选)、businessTable(业务表表名,表示每步操作所影响的数据库业务表)。

Business是具体的数据库业务表,这里假设业务很简单,只是记录某个数值的改变。包括id(业务自增标识)、description(业务描述)、state(业务状态)。

StepUser表记录了在每个流程步中进行操作的操作者,包括id(业务自增标识)、userID(用户id),stepID(流程步id)。

User表是用户信息表,包括id(用户自增标识)、userName(用户名)、password(密码)、realName(真实姓名)。
当创建一个流程时,其创建步骤如图二:

图二
流程创建后的实例化运行功能由FlowInstance和FlowUser两张表构成。

FlowInstance记录了实例化一个流程后,流程的运转情况。包括id(流程实例自增ID)、name(流程实例名称)、flowTypeID(流程实例类型ID)、step(流程实例步骤数)。

FlowUser记录了一个流程实例的操作者,FlowUser是StepUser的一个子集。包括id(流程操作者ID)、flowInstanceID(流程实例ID)、stepID(流程步ID)、opState(操作者操作状态,0为未操作,1为已操作,2为已跳过)、realStep(操作者进行实际操作时的流程真正步数,由于流程的进行不一定步进,故flowStep未必是realStep)、addID(添加该操作者的用户ID,用于记录实例跳转过程)、userID(操作者ID)、opInfo(操作信息备注)。
流程实例的运转步骤如图三:

图三
整个系统的运转过程主要是由以上两个大块组成,可以看到这个数据库表及表中的字段并不是很多,但表与表之间的关系比较复杂,理解起来不太容易。但从面向对象的角度来理解就会清晰很多。
在定义流程的部分相当于定义了一个流程类,包括flowType,flowStep,stepUser,flowPage,business几个属性表。并且可以由这几个属性表生成流程实例的运行方法。
当实例化一个流程时,流程实例对象经历了如图四所示的状态变换:

图四
1、初使化时,当某个用户进入系统时看到其可以启动的流程。
(可启动流程:select flowtype.name as flowName, flowtype.id as flowid from flowtype, flowstep, stepuser where flowtype.id = flowstep.flowid and flowstep.step = 1 and stepuser.stepid = flowstep.id and stepuser.userid = 5,这里设userID为5)
2、被操作时,当前用户可以看到轮到自己操作的流程实例,并对具体业务进行操作(business表)。
(可操作流程:select flowinstance.name as instanceName, flowinstance.id as instanceid from flowinstance, flowuser where flowinstance.id in (select flowuser.flowinstanceid from flowuser where flowuser.opstate = 0 and flowuser.id = 5),userID为5)
3、当前进时,当前用户首先要从下一步的stepUser中选择下一步的操作者,当选取好后,进行提交,当前操作者的操作状态(opState)变为1,系统根据流程规则进行跳转(flowInstance.step进行改变),当步数为-1时,流程结束,否则流程回到状态2。假如流程跳转,该步中未操作的操作者,其工作状态变为2。
(可选取的stepUser: select "USER".realname as realname, "USER".id as userid from "USER" where "USER".id in (select stepuser.userid from flowinstance, stepuser, flowstep where flowinstance.flowtypeid = flowstep.flowid and flowinstance.step = flowstep.step and stepuser.stepid = flowstep.id and flowinstance.step = 2),设流程将前进到流程步2)
一般来说,达梦数据库如在建库时选择大小写不敏感时,sql语句的大小写没有要求,所以本文中sql都是本人习惯的小写方式。但对于一些关键字,如”USER”,就需要用双引号括起,强制转换为大小写敏感,以区别user。达梦5.6中对该问题有了不同的处理策略。顺便提一下,达梦5.6的UI界面相对于5.0可以说是发生了质变,很有看头。
以上就是本文所要介绍的流程设计,及面向对象角度的理解方式。Everything is object,采用面向对象的设计方法我们可以很容易的把要解决的问题事物抽象成各种类,一般设计时,数据库每表的设计就是上层的实体类原型。设计时还可以把一个更复杂的事物,如流程、规则、项目进度等,进行面向对象的设计。整个系统的运转,也可以着手于系统状态的变化。
用户评论