创建大型消息处理程序查找表是不正确的吗?

时间:2015-11-09 06:42:28

标签: python design-patterns event-handling

我有一个队列,我正在推送消息。消息具有唯一的整数ID。我基本上有这样的东西:

#-------------------------
#Message handlers
#-------------------------
def noOperation():
    print "Do nothing"

def msgHandler1():
    print "Handling message with ID = 1"

def msgHandler2():
    print "Handling message with ID = 2"

#-------------------------
#Message lookup table
#-------------------------
lookupTable = {
    0: noOperation,
    1: msgHandler1,
    2: msgHandler2
    #...etc...
}

#-------------------------
#Message processing
#-------------------------
while threadActive:
    message = buffer.get(block=True)
    if message:
        lookupTable[message.id]()

我的问题是:有没有更有效的方法来做这种事情?如果我有几十种消息类型(或者,为了争论,我们可以说消息类型的数量是无限的,并且会随着时间的推移而继续增长),那么我的查找表将变得非常大。也许这不是一个真正的问题 - 我不确定......创建这个映射到几十个消息处理程序方法的大表只是在某种程度上感觉不对。这种事情是一个众所周知的问题,有一个定义明确的解决方案吗?有没有涉及此的模式?

2 个答案:

答案 0 :(得分:0)

我认为你的方式是最好的方式。最接近的设计模式是command pattern。这或多或少是你在python中实现它的方式。我并不担心你的查找表会太大。我将在您的代码中推荐的唯一更改是以下

if message.id in lookupTable:
    lookupTable[message.id]()
else:
    print "invalid id"

这样你就可以处理else

中的默认情况

答案 1 :(得分:0)

如果你的ID是连续的,最好使用一个可以直接访问的简单列表。这避免了必须进行字典查找。

lookupTable = [
    noOperation,        # index 0
    msgHandler1,        # index 1
    msgHandler2         # index 2 etc
    ]

while threadActive:
    message = buffer.get(block=True)
    if message:
        try:
            lookupTable[message.id]()
        except IndexError:
            print 'unknown id {}'.format(message.id)

在Python中尝试使用索引并捕获异常而不是首先测试它是否有效也是更好的。这将导致更快的代码。另外,请勿使用in,因为这会对您的数组执行线性搜索。