我需要创建一个具有依赖项支持的插件系统,但我不确定解决依赖项的最佳方法。这些插件都将从基类派生出来,每个都有自己的execute()
方法。在每个插件类中,我计划创建一个dependencies
属性作为它所依赖的所有其他插件的列表。
加载插件时,我将导入所有插件并将它们放入列表中,并根据依赖关系对它们进行排序。一旦它们都处于正确的顺序(因此具有依赖项的任何内容都在其所述依赖项之后的列表中),我将循环执行每个方法的列表execute()
method.
我一直感到模糊的是排序背后的逻辑。我可以开始按字母顺序排列它们,直到遇到具有依赖项的依赖项 - 如果它的依赖项不在列表中,请将其放入 tmp 列表中。在第一轮导入结束时,从临时列表的末尾开始(除了具有依赖项的插件之外什么都没有的列表)并再次检查“运行列表”。如果我在“运行列表”中找到它的依赖项,请确保它的索引号高于其最高依赖项。如果它的依赖项不在列表中,请暂停它并移至临时列表中的下一个插件。一旦我到达 tmp 列表的末尾,就从顶部开始并重试。一旦所有插件都排序完毕,或者 tmp 列表在循环遍历后没有改变大小 - 开始执行插件。
临时列表中剩下的插件要么没有找到依赖项,要么具有循环依赖项。 (tmp列表中的2个插件相互依赖)
如果您仍在阅读并且能够遵循我的逻辑;这是一个合理的计划吗?有没有更简单的方法?如果我想实现执行顺序的序列号,是否有一种“简单”的方法来同时具有序列和依赖关系? (如果存在冲突,依赖项会击败排序)或者插件应该使用序列或依赖项? (首先运行带有序列号的插件,而不是带有依赖项的插件?)
TL;DR
您将如何编写插件系统中计算依赖关系的逻辑?
Edit:
好吧-我想我从维基百科页面实现了拓扑排序;下面是 DFS 的逻辑示例。这似乎有效,但我以前从未做过这样的事情。
http://en.wikipedia.org/wiki/Topological_sorting#Examples http://en.wikipedia.org/wiki/Topological_sorting#Examples
data = {
'10' : ['11', '3'],
'3' : [],
'5' : [],
'7' : [],
'11' : ['7', '5'],
'9' : ['8', '11'],
'2' : ['11'],
'8' : ['7', '3']
}
L = []
visited = []
def nodeps(data):
S = []
for each in data.keys():
if not len(data[each]):
S.append(each)
return S
def dependson(node):
r = []
for each in data.keys():
for n in data[each]:
if n == node:
r.append(each)
return r
def visit(node):
if not node in visited:
visited.append(node)
for m in dependson(node):
visit(m)
L.append(node)
for node in nodeps(data):
visit(node)
print L[::-1]