用于处理撤消和通知的架构
我目前正在设计一个复杂的网站,需要支持 CRUD 操作的撤消和通知。
通过撤消,我的意思是用户可以创建/修改/删除一个项目,然后决定取消他所做的事情(因此删除创建的项目,恢复已修改项目的先前状态,或恢复)已删除的项目)。他可以在执行该操作后短暂地执行此操作(超时时间为2分钟,因为系统相当复杂,用户可能需要一段时间才能注意到修改不正确)。
通过通知,我的意思是,当创建/修改/删除某个项目时,对该项目感兴趣的其他用户将收到现场通知(下次加载新页面时),并且将如果他们要求,还会收到电子邮件或短信通知。
完成任一功能都很简单:撤消涉及保留撤消信息(主要是修改或删除的项目的旧版本),而通知就像将通知对象推送到适当的表中并即时发送电子邮件/短信一样简单。
让它们一起工作会产生很多额外的复杂性,因为通知必须保持静止状态,直到无法撤消为止,而且我对此事没有足够的后见之明,无法以理智的方式设计它。
构建这样的系统时需要避免哪些模式、最佳实践或陷阱?
I'm currently designing a complex website that needs to support Undo and Notifications for CRUD operations.
By Undo, I mean that the user may create/modify/delete an item and then decide to cancel what he did (therefore removing the created item, restoring the previous state of the modified item, or bringing back the deleted item). He can do so for a short while after doing that operation (the timeout is 2 minutes, because the system is fairly complex and it may take some time for the user to notice that the modification was incorrect).
By Notifications, I mean that when an item is created/modified/deleted, other users that are interested in that item will receive an on-site notification (the next time they load a new page) and will also receive an e-mail or SMS notification if they asked for it.
Getting either feature done is simple: Undo involves keeping undo information around (old version of modified or deleted items, mostly) while Notifications are as simple as pushing a notification object into the appropriate tables and sending an e-mail/SMS on the fly.
Getting them both to work together creates a lot of additional complexity because Notifications must remain in stasis until the Undo becomes impossible, and I don't have enough hindsight on the matter to design it in a sane way.
What would be patterns, best practices or pitfalls to avoid when building such a system?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我会考虑使用 命令模式 来撤消
(可能不会持续到超时到期)和通知的观察者模式。EDIT1:重新考虑一下,我可能会立即坚持下去。否则,您会遇到用户会话在超时到期之前结束的问题。
EDIT2:另一种选择是使用 Windows Workflow Foundation 4 (WF4) 和 补偿。将长期运行的持久工作流设置为 WCF 服务。工作流可以只是一个用于启动它的 WCF 接收活动、一个延迟活动和一个用于发送通知的自定义活动;您甚至可能不需要 CompensableActivity (如果延迟尚未过期且通知尚未发送,则无需撤消任何操作)。每个通知请求都会进行 WCF 调用来启动新的工作流实例。如果用户取消,则中止该实例。 (使用 Delay 执行 Pick 活动和另一个在调用时取消通知的 WCF Receive 活动可能会更容易。) 警告:我还没有实现这样的系统。
I'd consider using the Command Pattern for Undo
(possibly not persisting until the timeout expired)and the Observer Pattern for Notifications.EDIT1: Rethinking that, I'd probably persist immediately. Otherwise you have the issue of the user's session ending before the timeout expires.
EDIT2: Another option would be to use Windows Workflow Foundation 4 (WF4) and Compensation. Set up a long-running, persistent workflow as a WCF service. The workflow could just be a WCF Receive activity to start it, a Delay activity, and a custom activity to send notifications; you might not even need a CompensableActivity (if the delay hasn't expired and the notification hasn't been sent, there's nothing to undo). Each notification request makes a WCF call to start a new workflow instance. If the user cancels, abort the instance. (It might be easier to do a Pick activity with a Delay and another WCF Receive activity that cancels the notification if called.) Caveat: I haven't implemented a system like this.
基于思想和代码上的一些实验,我成功地提取了一系列原则。
基于这些原则,我决定在数据访问层之上构建两个不同的层:
这样,操作总是通过基本操作集,从而触发通知,而这些通知是由于取消较早的操作还是手动运行其逆操作而引起的 - 系统通过将它们分组在一起来巧妙地处理有关同一对象的多个通知并让它们互相抵消。
相反,“撤消”工具仅从语义层调用代码,而不需要任何有关所发送通知的知识。
显然,仍然会有少量的耦合,因为有时需要添加语义操作,只是因为它是现有操作的“撤消”逆操作。例如,您可以取消创建讨论,但一旦消息发送就无法删除(因为可能会有回复)。因此,当
deleteDiscussion
不可用时,可能存在cancelDiscussion
函数。我怀疑这种情况很少见,可以安全地接受。Based on a bit of experimenting both in thought and in code, I managed to extract a series of principles.
Based on these principles, I decided to architecture two distinct layers on top of the data access layer:
This way, operations always pass through the basic set of operations and thus trigger notifications that are agnostic of whether they are caused by canceling an earlier operation or running its inverse operation manually — the system cleverly handles multiple notifications about the same object by grouping them together and letting them cancel each other out.
Conversely, the "undo" facilities merely call the code from the semantic layer, without requiring any knowledge about the notifications being sent out.
Obviously, there will still be a little amount of coupling, because it sometimes is necessary to add a semantic operation only because it's the "undo" inverse of an existing operation. For instance, one can cancel the creation of a discussion, but cannot delete the message once it is sent (because there might be replies on it). So, a
cancelDiscussion
function might exist where adeleteDiscussion
is unavailable. I suspect such situations are rare enough to safely accept.