发布服务器/订阅服务器的使用陷入状态
本文关键字:服务器 状态 | 更新日期: 2023-09-27 18:24:37
这是我目前挂断的一个一般设计问题。它导致了一些心理代码块。。。如果这只是一个常见的陷阱,我不想继续这样做,但如果它被接受,我想继续使用,因为代码非常干净和解耦(排除交叉消息)。
我在代码中有一个基于列表的发布者/订阅者模式,我使用它来允许代码的任意部分发送未知订阅者可以收听的消息。相当简单。
我目前使用这种模式的一个用例是旋转一个UI状态指示器,向用户显示应用程序正忙。在工作开始之前会有一条消息,一条重复消息表示进度,一条消息表示完成。它看起来很干净,较低级别的代码只发布消息,而不关心侦听器。
启动消息最初驱动UI;它在主窗体的状态栏中显示了一个带框的进度条。完成消息隐藏了这个进度条。更新消息在标签中表示为文本。
当时我没有意识到,我让UI依赖于这些消息的顺序。UI依赖于开始和完成消息,以便正确反映UI。我所指的"状态性"是在用户端(消息本身不保留任何状态)。
这种用法是否违反酒吧/酒吧模式?如果是这样的话,问题是对消息顺序的依赖吗?如果没有,那就好了,我可以继续:-)
在您的示例中,顺序耦合代码的气味可能来自于您的订阅者对发布者的内部工作了解太多(即,当一个启动时,另一个启动)。
您可以通过减少消息中的信息或让订阅者不利用消息的时间序列来减少耦合。
例如,让订阅者对开始和进行中的消息执行相同的例程,将消息的分辨率降低为"正在工作"。如果需要,UI订阅者可以生成对话框,或者在对话框已经存在的情况下更新对话框。UI订阅者的工作是管理对话框的生存期,而不是应用程序的生存期。
然而,这个小气味可能不足以开始在应用程序和UI订阅者之间卷积消息。
或者,你可以让你的订阅者足够健壮,无论调用的消息顺序如何,都可以做正确的事情。开始、开始、处理、结束、处理、开始等。订阅者的责任应该是管理进度对话框。。。无论应用程序发出什么疯狂的消息,它都能做到最好。
我分享你的"有些事情似乎不对劲"的感觉。
您是否应该能够在不涉及UI的情况下执行发布者?我怀疑是这样。我想UI可能会让事情开始,但事实上,你知道发布者的内部工作——发布者处于某种状态"开始"、"中间"answers"结束"——这是一种代码气味。
也许UI应该只是另一个订阅者。订阅"主题"(使用pub/sub术语)将是"processProgress",比如说,发布者本身将在特定方法中发送消息,反映这一点。或者其他控制发布程序执行的类会调用发布程序来发送开始/中间/结束消息。
根据接收到的消息,UI将决定显示进度条以及显示什么消息。
我认为对于pub/sub模式来说,这通常是可以的
但是你考虑过如何处理嵌套调用吗?
假设您有三个关于发行商的电话:
- GetFirstName()
- GetLastName()
- GetFullName()
如果我理解你的意思,你会在每次通话中发送begin/inProgress/end消息。如果GetFullName()在内部调用其他两个调用来构造全名,则消息将为:
begin(全名)-begin(名字)-end(名字)-beging(姓氏)-eend(姓氏)-end(全名)
因此,对于一个GetFullName()调用,进度条会闪烁。
你考虑过这种情况吗?也许你可以使用计数器,但除了阻止调用结束消息的例外情况。。。