我目前正在实现发布 - 订阅模式,以便在将来的应用程序中使用。现在我无法找出设计模式消息部分的“最佳”方法。我有几个想法,但请告诉我是否有更好的方法。
想法1:每条消息都是一个实现简单标记接口IMessage的对象。
创意2:每条消息都表示为一个数组,其中第一个索引是消息类型,第二个索引包含有效负载。
这些中的任何一个“比其他”更好吗?如果是,为什么?如果这看起来像是一个愚蠢的问题,请原谅。
答案 0 :(得分:1)
您的第一个想法更有意义,请使用标记接口或不显眼的消息定义来查看消息传递模式的NServiceBus github实现。
本质上,发布/订阅场景中的消息是一个事件,它的名称应描述该事件,并具有与此事件相关的数据的相关引用。
HTH
答案 1 :(得分:0)
这两种方法都很有用。第一个在处理应用程序中的消息时很有用。如果您通过网络接收原始消息数据并且必须确定如何对其进行反序列化,则第二个非常有用。
如果你看看WCF如何序列化,那么他们将类型作为属性放在序列化中,因此它知道要将其反序列化为什么。但是,如果您要使用JSON序列化fx,那么最好使用属性来保存类型信息。另请注意,此类型信息不必指定实际的CLR类型,只需要一个标识符即可让您知道如何读取数据。
一旦您知道如何读取数据,就可以创建对象并利用类型系统,例如。使用标记接口。
答案 2 :(得分:0)
您不指定邮件是否跨越流程边界。
在后一种情况下,消息在同一个应用程序中的层之间传递,消息只是对象的第一种方法(可选地实现相同的接口)可能是最简单的。
在前者中,您拥有进程间和可互操作的消息传递,我认为您可以充分利用XML。 XML非常灵活,易于在不同技术中支持,允许您以可互操作的方式签署消息(XMLDSig),并允许您创建各种不同的输入/输出端口(tcp / http / database / filesystem)。此外,可以使用XSD规范轻松验证消息的完整性。
答案 3 :(得分:0)
在pypubsub库(python的发布 - 订阅)中,我发现命名有效负载数据有很大好处,因此发送方和接收方只能填充字段而不必依赖于消息中的项目顺序,加上它提供"代码作为文档"。例如,比较这些,用伪代码编写。使用数组:
function listener(Object[] message):
do stuff with message[0], message[1], ...
message = { 123, 'abc', obj1 } // an array
sendMessage('topicName', message)
使用关键字:
function listener(int radius, string username = None):
do stuff with radius, username, ...
// username is marked as optional for receiver but we override the default
sendMessage('topicName', radius=123, username='abc')
在C#中执行此操作可能比在Python中更具挑战性,但该功能在pypubsub中非常有用。此外,您可以使用XML来定义消息的架构,记录有效负载项,并且可以将某些有效负载项标记为可选(当它们具有默认值时)与所需(当它们不相同时)。 lib还可以检查监听器是否遵守"有效负载合同",并且发送方提供通过"合同"承诺的所有数据。
你应该看看(甚至使用)现有的库来获得一些想法(pypubsub位于pypubsub.sourceforge.net)。
答案 4 :(得分:0)
这两种方法都是可行的,第二种方法涉及您负责消息的序列化,它为您提供更多的自由,权力和对消息的控制,特别是版本控制,但所有这些都需要付出代价,只有当一些演员不是.net演员时,我才认为这种成本是可持续的。否则,请使用第一种方法,正如Sean指出的那样,看一下可以极大地帮助您完成所有管道工具的工具包和框架。