2012-02-15 140 views
2

这是一个我目前挂断的通用设计问题。它导致了一些精神代码块...我不想像这样继续它,如果它只是一个常见的陷阱,但我想继续,如果它被接受的用法,因为代码很干净,去耦(禁止交叉信息)。发布者/订阅者使用情况滑入状态

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

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

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

当时没有意识到,我使UI取决于这些消息的顺序。用户界面依赖于开始和结束消息来正确反映用户界面。我所指的“状态”在用户端(消息本身不保留任何状态)。

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

+0

听起来不可怕,回到你的代码哥们! :) – kenny 2012-02-15 15:36:29

+0

如果消息出现乱序会发生什么? – cadrell0 2012-02-15 19:14:10

+0

@ cadrell0它可能无法启动或一旦显示可能无法关闭...我的质疑解决方案的来源。 – 2012-02-16 08:17:25

回答

1

在您的示例中,sequential coupling代码气味可能来自您的订阅者,因为他们太了解发布者的内部工作原理(即一个启动时,另一个启动时)。

您可以通过减少消息中的信息或使用户不利用消息的时间顺序来减少耦合。

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

但是,这种小气味可能不足以启动应用程序和UI订阅者之间的消息的卷积。

或者,您可以让您的订阅者具有足够的可靠性,以执行正确的事情,而不管被调用的消息的顺序如何。开始,开始,处理,结束,处理,开始等等。订阅者的责任应该是管理进度对话框......以尽最大可能无论发送什么疯狂的消息。

+0

我同意代码气味。我已经意识到耦合启动/停止是问题,并且会将其重构为UI关注点。 – 2012-02-16 08:19:23

0

我认为这是可以的一般的酒吧/子模式。
但你有没有考虑过如何处理嵌套调用?

假设您有出版商三个电话:)))

  • 的getFirstName(
  • GetLastName(
  • GetFullName(

如果我理解你,你会扔开始/ INPROGRESS /每次通话结束消息。如果GetFullName()在内部调用其他两个调用来构造消息的全名:
begin(全名) - begin(first name) - end(first name) - begin(last name) - end(姓氏)​​ - 结束(全名)。
因此,一个GetFullName()调用的进度条闪烁。

您是否考虑过这种情况?也许你可以使用一个计数器,但然后是什么与例外,防止呼叫结束消息...

+0

UI在一系列末尾的最后一次结束呼叫中保留了一个呼叫计数,它隐藏了状态栏。这实际上是我不确定的事情的一个例子。这种对信息链的依赖使我有理由重新思考。目前为了处理异常,消息的发布者确保通过try-finally或using块发布结束消息。 – 2012-02-15 15:46:58

+0

Try-finally听起来不错。如果您在实施该功能时告诉我们您关于该功能的体验,我会很高兴。 – brgerner 2012-02-15 16:03:44

+0

经过反思,我认为对消息模式的依赖比我当前的实现更多的是Message Bus,我选择重构模式依赖关系。 – 2012-02-16 08:21:40

1

我分享你的“东西似乎不对”的感觉。

您是否应该能够在不涉及UI的情况下执行发布者?我怀疑是这样。用户界面可能会启动我想要的事情,但事实上,您知道发布商的内部工作 - 发布商处于“开始”,“中间”和“结束”状态 - 是一种代码味道。

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

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

+0

我同意代码气味。我将根据启动和停止的方式将消息的生命期从消息中分离出来,而不是从UI中完全驱动。 – 2012-02-16 08:18:30

相关问题