发布者/订阅者使用率下降到有状态

时间:2012-02-15 15:25:21

标签: c#

这是我目前挂断的一般设计问题。这会导致一些心理代码阻塞......我不想继续这样做,如果它只是一个常见的陷阱,但我想继续,如果它被接受使用,因为代码非常干净,解耦(除了交叉信息)。

我在代码中有一个基于列表的发布者/订阅者模式,我用它来允许任意代码段发送未知订阅者可以收听的消息。非常坦率的。

此模式的当前用例之一是启动UI状态指示器,显示应用程序正忙的用户。工作开始前有一条消息,一条重复的进度消息和一条完成消息。看起来很干净,较低级别的代码只发布消息而不关心听众。

起始消息最初驱动UI;它在主窗体的状态栏中显示一个选取框进度条。完成消息会隐藏此进度条。更新消息在标签中表示为文本。

当时没有意识到,我让UI依赖于这些消息的顺序。 UI依赖于开始和完成消息,以便正确反映UI。我所指的“有状态”是在用户端(消息本身不保留任何状态)。

这种用法是针对pub / sub模式的吗?如果是这样,问题是否依赖于消息顺序?如果没有,那么好,我可以继续: - )

3 个答案:

答案 0 :(得分:1)

我分享你的“感觉不对劲”的感觉。

您是否能够在没有涉及UI的情况下执行发布商?我怀疑是这样的。用户界面可能会让事情开始,但我知道发布商内部运作方式 - 发布商处于特定状态“开始”,“中间”和“结束” - 这一事实就是代码气味。

也许UI应该只是另一个订阅者。订阅“主题”(使用pub/sub terminology)将是“processProgress”,并且发布者本身将在特定方法内发送消息,反映出这一点。或some other class that is controlling the execution发布者会调用发布者发送开始/中间/结束消息。

根据收到的消息,UI将决定显示进度条以及要显示的消息。

答案 1 :(得分:1)

在您的示例中,sequential coupling代码气味可能来自您的订阅者,他们对发布者的内部运作方式了解太多(即,当一个人开始时,另一个人开始)。

您可以通过减少消息中的信息或让订阅者不利用消息的时间序列来减少耦合。

例如,让订阅者为开始和进行中的消息执行相同的例程,将消息的分辨率降低到“正在工作”。 UI订户可以根据需要生成对话框,如果已存在则更新它。 UI用户的工作是管理对话框的生命周期,而不是应用程序的生命周期。

然而,这种小气味可能不足以开始在应用程序和UI订阅者之间卷积消息。

或者,无论调用的消息顺序如何,您都可以使您的订阅者足够健壮以执行正确的操作。开始,启动,处理,结束,处理,启动等。订阅者的责任应该是管理进度对话框......无论来自应用程序的疯狂消息是什么,它都能做到最好。

答案 2 :(得分:0)

我认为对于pub / sub模式来说一般都没问题 但是你考虑过如何处理嵌套调用吗?

假设您对发布商有三次调用:

  • 的getFirstName()
  • GetLastName()
  • GetFullName()

如果我理解你,你会在每次通话中抛出begin / inProgress / end消息。如果 GetFullName()在内部调用其他两个调用来构造全名,则消息将为:
开始(全名) - 开始(名字) - 结束(名字) - 开始(姓氏) - 结束(姓氏) - 结束(全名)。
因此,一个GetFullName()调用的进度条闪烁。

你考虑过这种情况吗?也许你可以使用一个计数器,但是那些阻止调用 end 消息的例外是什么......