文章目录[隐藏]

  • 一级
  • 第二级
  • 第三级
  • 四级
  • 第5级
  • 6级
  • 7级
  • 8级
  • 第九级
  • 10级
  • 11级
  • 12级
  • 13级
  • 14级
  • 15级
  • 附言

工作流系统(工作流管理软件)

一级

有一天,老板找我,说要做一个简单的工作流引擎。

我查了查什么是全天工作流,然后做了以下版本:

添加任何批准者以形成一个链接列表,最后添加一个结束节点。

记录当前审批人,当审批完成后,审批人将后退一位。

当批准人对应于结束节点时,流程结束。

老板:有点简陋。

第二级

老板又来了:支持会签节点。

我又查了一下什么是会签节点,发现会签节点是一个大节点,里面有许多批准人。当这个大节点中的所有审批人都被批准后,他们可以进入下一个节点。

我想了一个星期,推翻了原来的链表设计:

在结构上,我做了以下调整:

将节点分为两类:简单节点(上图中的矩形)和复杂节点(上图中的圆形)。

用一棵树来表示整个过程,其中所有的叶节点都是简单节点,所有的简单节点都是叶节点。

每个简单节点中只有一个审批者。

复杂节点包含几个子节点。

加入会签节点:会签节点激活后,所有子节点都可以被审核。当所有子节点都被批准时,联署节点就完成了。

加入串行节点:只能从左到右批准子节点。当最后一个子节点被批准时,串行节点就完成了。

中所有工作流的最外层是一个串行节点,它表示整个工作流的完成。

为了控制审批流程,我设计了一些节点状态:

就绪:可以审批的简单节点处于就绪状态。

完成:已批准的节点状态。

未来:尚未到达的节点状态。

等待:只有复杂节点具有此状态,表明它们正在等待子节点的批准。

借助上述规则,带有一次会签节点的工作流审批流程如下:

老板:有意思。

第三级

老板来了:支持并行节点。

我查了一下午什么是平行节点,发现平行节点就是有很多审批人的大节点。如果这个大节点中的任何一个人被批准,这个节点就完成了。

然后迅速加入了平行节点:

并行节点是一个复杂的节点。当节点被激活时,任何子节点都可以被批准,当任何子节点处于完成状态时,该节点是完成的。

添加新状态跳过:

当并行节点的子节点的状态不是(就绪、等待)时,其他兄弟节点及其子节点的状态被设置为跳过。

举个栗子:

老板:这个设计加新节点还是挺方便的。

四级

再次Boss:节点要支持嵌套。例如,会签节点中有一个并行节点,并行节点中有一个复杂节点。应该是可以嵌套任何层的那种。

我:其实我已经支持了~

无限扩展的树形结构可以支持任何复杂的过程。

老板:小伙子有东西!

第5级

老板又来了:支持条件节点。

工作流伴随着一个表单,需要根据表单的内容确定下一步进入哪个分支。

经过几天的冥思苦想,我加入了条件节点:

节点类似于并行节点,只是只有满足条件的子节点才能进入下一个审批。

老板:我看过了。

6级

老板又来了:又多了两类审批人,比如可以从表单中选择下一个审批人,可以根据不同的发起人选择不同的审批人。

经过一番考虑,我将简单的节点分为3类:

第一种:审批人写死了。

第二种:审批人读表。

第三种方法是根据发起人和映射函数计算批准人。比如get_ supervisor(“钱”)获取钱的主管李。

老板:嗯。

7级

老板又来了:节点可以从前到后审批,那么可以从后到前拒绝吗?

我:……

首先实现了对发起方的拒绝功能,相当于从头再来:

只有处于就绪状态的节点有权拒绝。(就像只有处于就绪状态的节点有权批准一样)

老板:你很懒。

8级

老板又来了:先给最后一个审批人否决吧。

拒绝最后一个审批人实际上是一个复杂的逻辑,因为工作流中的节点可以无限嵌套,所以不容易确定哪些审批人处于最后状态。

牺牲了一些头发,终于实现了拒绝下一级的功能:

老板:看。

第九级

老板又来了:实现对任意节点拒绝的功能。

我发现这个需求不难实现:

继续拒绝上一级,直到处于就绪状态的节点包含要拒绝的节点。

老板:嗯。

10级

老板又来了:给共同节点加个时限。如果你没有在规定的时间内完成你的成就,那就说明你超时了。

我:还有这种需求?

但还是实现了。

至此,我明白了,需求和头发是负相关的。需求越多,头发越少。

11级

老板又来了:加个代理功能。比如有一件事要你批,但你对这件事没有把握,那就转给对这件事有把握的人批。

我马上发现这个要求和过去有本质的不同。在过去,工作流的节点关系从一开始就是固定的,即在流程启动之前就已经确定了。

但是现在需要在审批环节进行更改。

无非就是加一些类,掉一些毛,最后设计出以下方案:

代理操作的本质是创建一个新的并行节点作为这个节点的父节点,然后为代理创建一个新的兄弟节点,这样代理和被代理都可以被批准。

代理可以无限嵌套,也就是代理也可以找代理。

12级

老板又来了:能不能加个取消代理的功能?

。。。我已经在做我自己了,就补充一句:

委托书注销是委托书的逆向操作。

如果代理已经被批准,则不能取消代理。

13级

老板又来了:给每个节点加一个前置后置条件。满足前置条件才能进入节点,满足后置条件才能审核节点。

我的心:再见,老板,再见,再见,再见!

我的嘴:好的老板,收到。

后来:后来我真的给每个节点都加了前置和后置条件,同时审批逻辑的相关代码也翻倍了。

14级

老板又来了:现在有些工作流程很复杂,审批时间很长。能否为每个正在进行的工作流计算一个指标:直观显示当前批准的百分比?

我:收到。

事实上,与前面的要求相比,这一条并不复杂,因为它不涉及核心逻辑的改变。本质是输入一个树形结构,然后根据不同节点的状态输出一个整数。

经过测试和思考,最终方案如下:

工作流完成的百分比是指从最右边的就绪节点到最左边的节点的距离/从树中最右边的节点的距离。

15级

老板又来了:能不能给每个节点挂两个可执行脚本,然后在你开始审批节点和完成审批节点之后再执行?

我:对,对。

当然后来我也实现了这个功能。与此同时,我发现我在壮年时已经秃顶了。

附言

老板清华,是毕业的高材生,不然我大概想不到这么多奇葩的要求。后来老板把这套工作流程系统卖给了广*证券等公司,我就去了其他公司各奔东西。当然,那时候,我觉得自己有前途。

当我开始这个工作流程的时候,我刚刚本科毕业。后来离开这家公司,照了照镜子,老了。这件事发生在三年前,现在回想起那些加班换工作流程的日子,我还是心惊胆战。

最后,希望天下所有的同事都无bug,身心健康,攒够钱在一线城市买两套房,过几年有退休金的悠闲退休生活。