65.9K
CodeProject 正在变化。 阅读更多。
Home

工作流基础 –掌握流程

starIconstarIconstarIconemptyStarIconemptyStarIcon

3.00/5 (4投票s)

2007年4月30日

CPOL

8分钟阅读

viewsIcon

38355

构建一个好的工作流与编写好的代码不同。本文讨论了一些关于构建更好工作流的简单技巧。

引言

本文实际上并没有针对 WWF,但它确实为设计运行良好的工作流提供了一些技巧。本文的写作目的不是遵循 WWF 和其他工作流模型对某些词语的特定含义,因此在阅读时请对某些内容持保留态度。

背景

多年前(持续了几年),我曾为一个 UI 流程引擎和其中运行的一些非常复杂的工作流做过一些设计工作。其中大多数工作流都有几百页的文档。在实际设计工作流的过程中,很快就出现了一些关于如何做得更好的简单规则。这些规则主要与用于从用户(或其他人,例如通过工作流与您互动的其他企业)收集信息的工作流有关,但其中大多数规则具有普遍适用性。

工作流规则(用汗水换来的经验)

1. 我们有足够的“桶”来收集所有的“泄漏”吗?

当您的工作流变得复杂时,您可能会遇到一种情况,即存在一些您未曾预料到的、奇怪的边缘情况组合。这些边缘情况可能会从工作流中“泄漏”出去并丢失,尽管实际上,它们更像是“汇聚”在某个未被观察到的地方——可能导致问题滋生。最好确保每个路径都有去向并能实际退出,即使您必须将它们“倒入一个桶中”。

例如,工作流的特定实例可能会永远“暂停”,等待某个永远不会到来的用户交互,因为该用户已经离职去别处工作了。总的来说,您应该考虑所有事情都有可能“堵塞”(就像下水道堵塞一样),尤其是那些 *永远* 不会堵塞的情况,并据此进行规划。在任何地方处理超时都是一种您应该始终准备好的“桶”的特定类型。

2. 快速淘汰

优化工作流的一个简单方法是明确测试所有会导致工作流实例被放弃的条件,并将这些检查放在工作流定义的非常靠前的位置。这样做的目的是避免执行最终不需要的步骤。

3. 不要让他们“悬空”

当您需要从某人那里收集大量信息时(不一定是您的用户,而是您的客户),他们常常会想给一个自由格式的字段,然后让他们自行处理。当目标是尽可能多地为用户提供“完整”信息,或者因为该用户不被认为“值得信赖”时,尤其如此。有时人们会试图“捉弄”提供信息的人,即“给他们足够的绳子让他们自己吊死”。因此,会给他们一两个自由格式的文本字段,之后需要人工解释。

这种方法确实不利于转化为成功的工作流。事实上,从业务角度来看,无论您如何实施(即使使用纸质表格),这种方法几乎注定会达不到其目标。真正的答案是仔细分析所有可能的选项,在每个步骤添加一个“桶”来处理您可能没有想到的任何情况,并仔细引导相关人员做出完整诚实的陈述。当您审查落入“桶”中的内容时,您可以重构您的工作流并逐步改进它。

4. 问吧,你就会得到

关于避免不必要步骤的观点对于总体上掌握工作流设计也很重要。评估工作流中的每个步骤,看看它在那个特定点是否真的有必要。如果不是,就把它移到后面;没有必要仅仅因为您总是这样做而执行某些操作或请求某些信息。这只是浪费。

如果您的工作流正在做类似多次收集相同信息或多次请求同一人批准的事情(想想申报表格),那么 **停止这样做**。只问一次,不再多问。许多基于纸张的工作流会先让某人审批表格,然后将其退回供验证和签署。您不需要这样做。重新设计您的工作流,使其仅在有实质性更改时才需要有人重新审阅。

5. 看见树木,也看见森林

编写代码时,我们常常希望专注于主要功能,并尽可能消除次要部分,至少在后续版本中。这在工作流中也同样适用,但有一些重要的考虑因素。工作流的整个想法通常是捕捉和表达与特定任务如何完成相关的业务知识和领域经验,但如果我们只做到工作的 80%,我们就失去了将其放入工作流的初衷。

例如,我们可能会有一个“桶”太多的流程。有太多情况是我们放弃了工作流自动处理,而是回到了我们本应捕捉的领域经验中来手动填补这些空白。如果我们止步于 80%,我们就没有真正利用工作流的优势。

举个例子,假设您实现了一个工作流,它覆盖了 99.99% 的各种情况(按数量计算)。这很棒,平均每 10000 个才有一个需要干预,而您一周只处理那么多个!如果干预只需要一两分钟就太好了,但通常情况下,边缘情况每次都需要更长的时间来解决,可能需要几个小时到几天。这是巨大的时间浪费。

现在,如果您开始对如何处理这些边缘情况形成一个模式,以便它们不再需要花费那么长时间,那么现在是不是该将这些知识放入工作流中,并捕捉那些稀有但非常有价值的业务知识了呢?

6. 是的,末端确实会影响整体

当您开始添加边缘情况时,您会发现您的工作流定义可能需要进行一些相当大的重构才能容纳所有这些——这是正常的。一些看似微不足道的问题可能会被提升到工作流的靠前位置,因为它们实际上具有高度的辨别力(尽管它们可能仍然显得不重要),或者因为将它们放在那里可以帮助您缩短工作流中的特定路径,这并不罕见。

7. 抽象,抽象,抽象

始终留意出现的任何模式,并尝试开发适合这些抽象模式的工作流。这会真正打开您对您试图描述的过程的思路,并真正使您能够将事物放在工作流中的正确位置。此外,它还有助于减少文档和测试。

8. 数据结构 <> 业务对象 <> 工作流 <> 用户界面

在通过工作流实际收集用户信息的过程中,有些事情是绝对禁止的。我们可以将本节重命名为“不当暴露”,以暗示这些禁忌是什么。

最大的错误之一是将您的业务数据原封不动地展示给用户,或者组织您的工作流,使其不被您模式中的参照完整性问题所干扰。这是将您业务中最深层、最黑暗的秘密暴露给外部世界。更不用说,如果用户输入的内容与您的数据库过于接近,您可能会面临更大的 SQL 注入攻击风险。

那么,业务对象肯定必须是答案吧?答案也是 **否**。

您的工作流是一个流程,而不是一个对象。

抱歉,说了显而易见的事,但这却常常被人遗忘。例如,一个几乎和上面那个错误一样大的错误是,假设您的业务对象对您的用户来说是完全可以理解的,或者即使不完全理解,但大量的培训可以解决这个问题。

试图让您的用户“填满”您的业务对象或数据库表,因为这是您需要获取的信息,这不仅是错误的——这是愚蠢的。这是暴露您业务的秘密,而您所应该暴露的只是一个接口。如果您必须培训用户才能让他们理解他们看到的各个字段的含义,那么您就向他们暴露了您的业务处理方式——如果您的用户实际上是您的竞争对手呢?

您的业务对象应该支持工作流——而不是主导它。

相反,您在用户界面中向用户展示的内容应该对他们来说是有意义的,而这很可能与您存储在数据库或业务对象中的内容不同。您还希望用户给出的答案能够指导工作流,使他们被要求执行的活动序列对他们来说是合乎逻辑的。这是抽象发挥作用的另一种方式(从不同的意义上)。数据库和业务对象是您的领域,不要不必要地将其暴露给用户。相反,抽象掉您系统的具体细节,这样您就可以在需要的时候询问需要询问的内容。

© . All rights reserved.