【问题标题】:Is this good design of a workflow-esque system?这是工作流式系统的良好设计吗?
【发布时间】:2009-01-16 00:54:25
【问题描述】:

我正在设计一个系统,该系统允许我将广泛的任务表示为工作流,通过 IEnumerable 方法公开它们的工作项。此处的目的是使用 C# 的“yield”机制来允许我编写工作流执行系统可以根据需要执行的伪过程代码。

例如,假设我有一个工作流程,其中包括在数据库上运行查询并在查询返回特定结果时发送电子邮件警报。这可能是工作流程:

public override IEnumerable<WorkItem> Workflow() {
    // These would probably be injected from elsewhere
    var db = new DB();
    var emailServer = new EmailServer();

    // other workitems here

    var ci = new FindLowInventoryItems(db);
    yield return ci;

    if (ci.LowInventoryItems.Any()) {
        var email = new SendEmailToWarehouse("Inventory is low.", ci.LowInventoryItems);
        yield return email;
    }

    // other workitems here
}

CheckInventory 和 EmailWarehouse 是派生自 WorkItem 的对象,WorkItem 具有子类实现的抽象 Execute() 方法,封装了这些操作的行为。 Execute() 方法在工作流框架中被调用 - 我有一个 WorkflowRunner 类,它枚举 Workflow(),围绕工作项包装前后事件,并在事件之间调用 Execute。这允许消费应用程序在工作项之前或之后执行它需要的任何操作,包括取消、更改工作项属性等。

我认为,这一切的好处是,我可以用负责完成工作的工作项来表达任务的核心逻辑,而且我可以用一种相当直接、几乎程序化的方式来完成它。另外,因为我使用的是 IEnumerable 和支持它的 C# 语法糖,所以我可以组合这些工作流——比如使用和操作子工作流的更高级别的工作流。例如,我编写了一个简单的工作流程,它只是将两个子工作流程交错在一起。

我的问题是——这种架构看起来合理吗,尤其是从可维护性的角度来看?它似乎实现了我的几个目标 - 自我记录代码(工作流程按程序读取,所以我知道将在哪些步骤中执行什么),关注点分离(查找低库存项目不依赖于向仓库发送电子邮件),等等 - 这种架构是否存在我没​​有看到的任何潜在问题?最后,以前有没有尝试过 - 我只是重新发现了这个吗?

【问题讨论】:

    标签: c# workflow


    【解决方案1】:

    就我个人而言,这对我来说是一个“先买后建”的决定。我会在写之前买东西。

    我在一家相当大的公司工作,可能会因为金钱而愚蠢,所以如果你是为自己写这篇文章并且买不到东西,我会收回评论。

    这里有一些随机的想法:

    我会将工作流程外部化为我可以在启动时读取的配置,可能从文件或数据库中读取。

    它看起来像一个具有状态、转换、事件和动作的有限状态机。

    我希望能够插入不同的操作,以便即时自定义不同的流程。

    我希望能够注册希望在特定事件发生时收到通知的不同订阅者。

    我不希望看到像电子邮件服务器那样硬编码的东西。我宁愿将它封装到一个可以插入到需要它的事件中的 EmailNotifier 中。蜂鸣器通知呢?还是手机?黑莓?相同的架构,不同的通知器。

    您想包含一个用于人机交互的处理程序吗?我处理的所有工作流程都是人工和自动化处理的混合体。

    您是否希望连接到其他系统,例如数据库、其他应用程序、网络服务?

    这是一个棘手的问题。祝你好运。

    【讨论】:

    • 这个东西的范围非常有限——它是针对个人项目的,所以买东西是对的。我不需要工作流本身的构建后配置,尽管工作项的配置是必要的。就电子邮件服务器、数据库等而言 - 它们是 -...
    • ... 只是为了举例。我主要是在尝试解决一个本质上是模块化的问题,但是一旦我确定了工作流程本身,它就不会改变,除非需求发生变化。人机交互将仅限于取消或暂停整个工作流程,而不是 -...
    • ... 让工作流通过界面或任何东西与用户交互。就状态机而言,我从这种模型开始,但后来意识到我正在重写轮子——C# 在编译返回 IEnumerable 和 yield 语句的方法时使用状态机。那是-...
    • ...我是如何得出这个结论的。尽管如此,还是感谢您的输入,这很有帮助。 =)
    • 哦 - 详细说明一下它的用法 - 这是我正在开发的一款应用程序自动化软件,它有一个特定的应用程序和目标任务。
    【解决方案2】:

    @Erik:(针对我的答案的适用性发表评论。)如果您喜欢设计和构建自己的自定义工作流系统的技术挑战,那么我的回答没有帮助。但是,如果您尝试使用未来需要支持的代码来解决现实世界的 WF 问题,那么我建议您使用内置的 WF 系统。

    Workflow 支持现在是 .Net 框架的一部分,称为“Workflow Foundation (WF)”。几乎可以肯定,学习如何使用内置库比编写自己的库更容易,正如 duffymo 在他的“构建前购买”评论中指出的那样。

    工作流以 XAML 表示,并由 Visual Studio 中的设计器支持。 工作流分为三种类型(来自维基百科,链接如下)

    • 顺序工作流(通常是流 基于图表,从一个阶段开始 到下一个并且不后退)
    • 状态 机器工作流程(进展自 'State' 到 'State',这些工作流程 更复杂并返回到 如果需要,上一点)
    • 规则驱动的工作流程(已实施 基于 Sequential/StateMachine 工作流程。规则规定了 工作流程的进展)

    维基百科:Windows Workflow Foundation

    MSDN:Getting Started with Workflow Foundation (WF)

    【讨论】:

    • 呃什么?这是如何回答问题的?
    • Erik 以“我正在设计一个允许我将广泛范围的任务表示为工作流的系统”作为他的问题的开场白。然后,他详细介绍了本土 WF 解决方案。我指出有一个内置的 WF 解决方案。这对我来说似乎是一个很好的答案,
    • 是的 - 这是一个有效的答案,虽然不是我想要的。我目前不考虑在这个项目中使用 WF(至少在 WF4 之前)。我不需要它提供的功能,我自己构建的系统很简约,但提供了我需要的所有功能。
    • 我只是想知道随着时间的推移,它是否看起来是一个稳定且可行的系统 - 可维护性。
    • @Erik。它看起来像一个优雅的解决方案,而且,单独来看,这听起来是可维护的。但是,如果我是另一个面临维护它的人,我可能会想知道为什么我要学习自定义 WF 技术,而不是学习可以在职业生涯其他地方使用的“标准”WF 技术。
    猜你喜欢
    • 1970-01-01
    • 2016-10-06
    • 2010-09-09
    • 2012-05-19
    • 2017-01-09
    • 2011-03-08
    • 2019-03-08
    • 2022-01-04
    • 1970-01-01
    相关资源
    最近更新 更多