转自:http://www.guodanpi.com/zblog/post/21.html
今天几乎没有再看关于工作流的一大堆规范,而是看了一下国人的PowerStone开源工作流实现(其实之前几天也花了些时间来研究),毕竟对他用的那个套路比较熟(spring+hibernate),大体上能了解他想干什么,但是还是不懂,第一步还是分析了他所使用的数据库,遗憾的是终究还是没有找到我想看到的东西。同时他的说明里面提到实现了WfMC的1、2、5接口,由于对WfMC没什么兴趣,所以也就不管它,只是想弄清楚他考虑的和我所想的有什么差距。
事实上是我以前接触过一个Fatwire公司(在google里面搜索contentserver,它排第一,以前可真是名不见经传)的contentserver,我还是比较赞同它里面的搞法,通过web页面+dbms来定做工作流,并自动生成工作流的最终图形给用户验证是否正确,而不是输入一个xpdl这种东西。
多少给我的收获在于它对工作流和实际操作的数据的结合部分,也是我以前从来没有想到过的结合方式,通过记录每一个state的输出和输入参数来与数据交互!好像这也是wfmc的一个通用数据库设计。不敢说他设计的不好,只是总觉得这样设计有点别扭。
还是先看一下真实使用工作流时,业务数据在“流动”的过程中可能碰到的操作结果:
通过、退回、取消、取回
这些也就是概念上的东西,对应到真实世界操作简直太容易了。
如果说if..else..、for..和顺序执行能构成完整的程序的话,工作流应该也不例外,关键或者说难点在于将一些条件、一些业务数据如何与工作流互交,或者说如何让工作流能够识别前面提到的fromCondition和toCondition,这一点的设计估计要留到最后了。
不管工作流将要处理的对象有多复杂,有多少属性,应该有一个表用来记录唯一的标示这些对象的表(暂且称之为实体,也正是因为想在PowerStone中找到这个表未果,所以充满疑惑):
class WorkflowEntity {
Long id;
String targetId;//或者直接是某张表的id
String targetType;//或者直接是某张表的表名
Workflow workflow;
}
只要拿到entity的id,自然可以得到它所对应的操作对象(table+id完全可以定义到某一条数据),也能知道当前所使用的工作流。这一点有需要考虑的地方,是否需要(targetId+ targetType)的唯一索引,这样才能比较好的处理。
也需要记录该实体的当前状态信息
class Task{
Long id;
State currentState;
WorkflowEntity wfEntity;
}
明显我们可以看到现在为止所设计的表中都没有“人”这个东西的出现,想想我们几乎每一步都离不开人,自然需要修改上面的State,加入人的信息,这一点确实很矛盾,因为“人”有多种的表现形式,有“组织”、“团队”、“角色”,这些全部可以包含人的信息,那么具体应该采用哪一种比较合适?(还没想好),姑且先放进去再说。
那现在实际上已经可以把这个实体“流动”起来了,但是太粗糙了!没有细致的没一步的规则定义,也许fromCondition和toCondition应该是一个规则(Rule),那么定义如下:
class Rule{
Long id;
//其他未知
}
class State{
Long id;
Workflow workflow;
Rule fromRule;
Rule toRule;
String actor;
}
实在有很多东西没有想明白,先记录下这些现在的糊涂想法,再慢慢改进,估计要真正想明白了再接着写了。