这是工作流式系统的良好设计吗?
我正在设计一个系统,该系统允许我将广泛的任务表示为工作流,并通过 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 派生的对象,它具有子类实现的抽象 Execute() 方法,封装了这些操作的行为。 Execute() 方法在工作流框架中被调用 - 我有一个 WorkflowRunner 类,它枚举 Workflow()、围绕工作项包装前置事件和后置事件,并在事件之间调用 Execute。 这允许使用应用程序在工作项之前或之后执行所需的任何操作,包括取消、更改工作项属性等。
我认为,这一切的好处是我可以用工作项来表达任务的核心逻辑负责完成工作,我可以用一种相当简单、几乎程序化的方式来做。 另外,因为我使用 IEnumerable 以及支持它的 C# 语法糖,所以我可以编写这些工作流程 - 就像使用和操作子工作流程的更高级别工作流程。 例如,我编写了一个简单的工作流程,仅将两个子工作流程交错在一起。
我的问题是——这种架构看起来合理吗,特别是从可维护性的角度来看? 它似乎为我实现了几个目标 - 自记录代码(工作流程按程序读取,因此我知道将在哪些步骤中执行什么),关注点分离(查找低库存项目不依赖于向仓库发送电子邮件),等等。此外,这种架构是否存在我没有看到的潜在问题? 最后,这个以前尝试过吗?我只是重新发现这个吗?
I'm in the process of designing a system that will allow me to represent broad-scope tasks as workflows, which expose their workitems via an IEnumerable method. The intention here is to use C#'s 'yield' mechanism to allow me to write psuedo-procedural code that the workflow execution system can execute as it sees fit.
For example, say I have a workflow that includes running a query on the database and sending an email alert if the query returns a certain result. This might be the workflow:
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 and EmailWarehouse are objects deriving from WorkItem, which has an abstract Execute() method that the subclasses implement, encapsulating the behavior for those actions. The Execute() method gets called in the workflow framework - I have a WorkflowRunner class which enumerates the Workflow(), wraps pre- and post- events around the workitem, and calls Execute in between the events. This allows the consuming application to do whatever it needs in before or after workitems, including canceling, changing workitem properties, etc.
The benefit to all this, I think, is that I can express the core logic of a task in terms of the workitems responsible for getting the work done, and I can do it in a fairly straightforward, almost procedural way. Also because I'm using IEnumerable, and C#'s syntactic sugar that supports it, I can compose these workflows - like higher-level workflows that consume and manipulate sub-workflows. For example I wrote a simple workflow that just interleaves two child workflows together.
My question is this - does this sort of architecture seem reasonable, especially from a maintainability perspective? It seems to achieve several goals for me - self-documenting code (the workflow reads procedurally, so I know what will be executed in what steps), separation of concerns (finding low inventory items does not depend on sending email to the warehouse), etc. Also - are there any potential problems with this sort of architecture that I'm not seeing? Finally, has this been tried before - am I just re-discovering this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
就我个人而言,这对我来说是一个“先买后建”的决定。 在我写之前我会买一些东西。
我在一家相当大的公司工作,可能会在金钱上变得愚蠢,所以如果你是为自己写这篇文章并且买不到东西,我会撤回评论。
这里有一些随机的想法:
我将工作流程外部化为一个配置,我可以在启动时读取该配置,可能是从文件或数据库中读取。
它看起来像一个具有状态、转换、事件和动作的有限状态机。
我希望能够插入不同的操作,以便我可以动态自定义不同的流程。
我希望能够注册不同的订阅者,他们希望在特定事件发生时收到通知。
我不希望看到像电子邮件服务器那样硬编码的东西。 我宁愿将其封装到一个 EmailNotifier 中,我可以将其插入需要它的事件中。 蜂鸣器通知怎么样? 还是手机? 黑莓? 相同的架构,不同的通知程序。
您想包含一个用于人机交互的处理程序吗? 我处理的所有工作流程都是人工和自动处理的混合。
您是否期望连接到其他系统,例如数据库、其他应用程序、Web 服务?
这是一个棘手的问题。 祝你好运。
Personally, this would be a "buy before build" decision for me. I'd buy something before I'd write it.
I work for a company that's rather large and can be foolish with its money, so if you're writing this for yourself and can't buy something I'll retract the comment.
Here are a few random ideas:
I'd externalize the workflow into a configuration that I could read in on startup, maybe from a file or a database.
It'd look something like a finite state machine with states, transitions, events, and actions.
I'd want to be able to plug in different actions so I could customize different flows on the fly.
I'd want to be able to register different subscribers who would want to be notified when a particular event happened.
I wouldn't expect to see anything as hard-coded as that e-mail server. I'd rather encapsulate that into an EmailNotifier that I could plug into events that demanded it. What about a beeper notification? Or a cell phone? Blackberry? Same architecture, different notifier.
Do you want to include a handler for human interaction? All the workflows that I deal with are a mix of human and automated processing.
Do you anticipate wanting to connect to other systems, like databases, other apps, web services?
It's a tough problem. Good luck.
@Erik:(解决有关我的答案的适用性的评论。)如果您喜欢设计和构建自己的自定义工作流程系统的技术挑战,那么我的答案没有帮助。 但是,如果您尝试使用未来需要支持的代码来解决现实世界的 WF 问题,那么我建议使用内置的 WF 系统。
工作流支持现已成为 .Net 框架的一部分,称为“Workflow Foundation (WF)”。 几乎可以肯定,学习如何使用内置库比编写自己的库更容易,正如 duffymo 在他的“构建之前购买”评论中指出的那样。
工作流以 XAML 表示,并由 Visual Studio 中的设计器支持。
工作流程分为三种类型(来自维基百科,链接如下)
维基百科:Windows Workflow Foundation
MSDN:Workflow Foundation (WF) 入门
@Erik: (Addressing a comment about the applicability of my answer.) If you enjoy the technical challenge of designing and building your own custom workflow system then my answer is not helpful. But if you are trying to solve a real-world WF problem with code that needs to be supported into the future then I recommend using the built-in WF system.
Workflow support is now part of the .Net framework and is called "Workflow Foundation (WF)". It is almost certainly easier to learn how to use the built-in library than to write one of your own, as duffymo pointed out in his "buy before build" comment.
Workflows are expressed in XAML and are supported by a designer in Visual Studio.
There are three types of Workflows (from Wikipedia, link below)
Wikipedia: Windows Workflow Foundation
MSDN: Getting Started with Workflow Foundation (WF)