【问题标题】:Implementation patterns to avoid infinite loops with events避免事件无限循环的实现模式
【发布时间】:2011-06-09 11:07:23
【问题描述】:

MVC 的幼稚实现会导致无限循环。

示例:Model 是带有 Worksheets 的 Workbook,View 是带有 Tabs 的 Tabbar

  1. 用户与 Tabbar 交互以创建新选项卡
  2. Tabbar 将事件 onTabAdded 发送到 Controler
  3. 控制器调用 Workbook.addWorksheet()
  4. 工作簿发送事件 onWorksheetAdded to Tabbar
  5. Tabbar 添加 Tab 并将 onTabAdded 发送到 Controler -> 2) 无限循环!

或者,可以通过编程方式启动循环 通过宏添加工作表。 或者,可以通过自动化 UI 测试以编程方式添加选项卡。

似乎你拥有的组件越多,耦合就越松 (被认为是好的设计),越有可能出现无限循环。

你知道如何避免这种无限循环的实现模式吗? 评估此类模式的优缺点?

我特别感兴趣的是富 JavaScript 客户端的解决方案。

以下问题的答案并不是真正的实现 等级:

【问题讨论】:

  • 我不明白为什么当使用更新的模型将页面刷新为“onTabAdded”显然是响应用户交互时,您的“标签栏”会引发“onTabAdded”事件,而不是显示刷新。我认为您不了解如何使用 MVC 模式,我会花一些时间来看看一些实现。
  • @Lazarus:好吧,也许你可以解释一下我的示例可以如何修改以避免循环,可能通过遵守 MVC。
  • @amadeus :视图有一个按钮,当单击时,该按钮会触发控制器中的命令以添加新的选项卡/工作表。该命令相应地修改模型并指示控制器呈现相同的视图,但使用新修改的模型。视图像以前一样呈现模型(现在包括 n+1 个选项卡)。由于它是一个视图,因此不会从标签栏发送其他消息,它只显示您给它的内容。你的模型过于复杂了。
  • @Lazarus:所以在您的解决方案中,视图不是增量的,因为它总是对模型进行完全重新渲染。在上面的例子中(标签不多),这可能是最好的解决方案。
  • @Lazarus 和第一条评论:在 UI 交互和 API 调用之后,onTabAdded 应该始终触发。 Tabbar 不知道谁在听。

标签: javascript design-patterns architecture


【解决方案1】:

您通常会编写如下代码(伪代码):

boolean inEventProcessing = false;

processEvent(event){
    if inEventProcessing return
    inEventProcessing = true
    doProcessEvent(event)
    inEventProcessing = false
}

另一种方法是通过构造确保不会发生循环。这是概念上更简洁的方法,但如果你一开始不想出它就很难做到。一种方法是只允许 Observers 为 Observables 的构造函数提供参数。这样就不可能构造循环。但它是一个极其刚性的结构,可能会导致各种不同的问题。

我确实怀疑这些问题的解决方案会导致一个非常漂亮和干净的架构,或者导致一个完全和极端的混乱,这取决于与之合作的团队。

【讨论】:

  • 编写代码以避免需要这些方法不是更好吗?除非你是多线程的,否则这是绝对必要的吗?
  • @Jens:您必须在 doProcessEvent 周围添加一个 try/finally。这使得很多样板。最好在一个通用的 EventGuard 中抽象出来。那么你的就是一个可行的解决方案。
  • @amadeus 当然应该将所有这些抽象出来并需要处理异常,但是如何做到这一点在很大程度上取决于所使用的语言,而且我不知道足够多的 javascript 来正确地做到这一点.
  • @Lazarus 这与多线程的东西没有任何关系。想象一个具有属性的模型。一个文本框绑定到该属性。每当更新时,文本框都会对其内容进行一些格式化。如果模型做了类似的事情,你可能会以无限循环结束。正如答案中所说:如果您可以避免它,那就太好了,但通常很难以简单而安全的方式避免它。
  • @Lazarus 不管那个设计有多糟糕。这是一个非常普遍的问题。这是一个非常务实的解决问题的方法。
猜你喜欢
  • 2012-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-01
  • 2022-01-15
  • 1970-01-01
  • 2012-03-22
相关资源
最近更新 更多