计算插件依赖
Posted
技术标签:
【中文标题】计算插件依赖【英文标题】:Calculating plugin dependencies 【发布时间】:2011-09-11 08:15:24 【问题描述】:我需要创建一个支持依赖项的插件系统,但我不确定解决依赖项的最佳方式。这些插件都将继承自一个基类,每个都有自己的execute()
方法。在每个插件类中,我计划创建一个dependencies
属性作为它所依赖的所有其他插件的列表。
加载插件时,我会导入所有插件并将它们放在一个列表中,并根据依赖关系对它们进行排序。一旦它们都处于正确的顺序(因此任何具有依赖关系的东西都在其所述依赖关系之后的列表中),我将遍历执行每个方法 execute()
方法的列表。
我一直模糊不清的是排序背后的逻辑。我可以开始按字母顺序排列它们,直到遇到一个具有依赖项的文件——如果它的依赖项不在列表中,则将其放入 tmp 列表中。在第一轮导入结束时,从临时列表的末尾开始(一个只有具有依赖项的插件的列表)并再次检查“运行列表”。如果我在“运行列表”中找到它的依赖项,请确保它的索引号高于其最高依赖项。如果它的依赖项不在列表中,请推迟它并移动到临时列表中的下一个插件。一旦我到达 tmp 列表的末尾,请从顶部重新开始并重试。一旦所有插件都被排序,或者 tmp 列表在循环之后没有改变大小 - 开始执行插件。
临时列表中留下的插件要么没有找到它们的依赖项,要么具有循环依赖项。 (tmp 列表中的 2 个相互依赖的插件)
如果您仍在阅读并且能够按照我的逻辑进行操作;这是一个合理的计划吗?有没有更简单的方法?如果我想为执行顺序实现序列号,是否有一种“简单”的方式来同时拥有序列和依赖关系? (如果发生冲突,依赖关系会击败排序)或者插件应该使用序列或依赖关系? (先运行带序列号的插件,然后运行有依赖项的插件?)
TL;DR
如何编写插件系统中计算依赖关系的逻辑?
编辑:
好吧-我想我从***页面实现了拓扑排序;遵循其 DFS 的逻辑示例。它似乎有效,但我以前从未做过这样的事情。
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]
【问题讨论】:
【参考方案1】:您描述的算法听起来可行,但很难检测循环依赖关系。
您正在寻找的是您的依赖项的Topological sort。如果您创建一个依赖关系图,其中从 A 到 B 的边意味着 A 依赖于 B,那么您可以执行 Depth-first search 来确定正确的顺序。您需要做一个variation of a regular DFS 来检测周期,以便在这种情况下打印错误。
如果您在每个顶点上使用有序列表来存储图中的连接,则可以使用它们的序列号添加依赖关系。使用 DFS 的一个优点是生成的排序列表在与依赖顺序不冲突时应该尊重您的序列顺序。 (我相信;我需要对此进行测试。)
【讨论】:
【参考方案2】:topological sort 会将所有内容按正确的顺序排列。
【讨论】:
以上是关于计算插件依赖的主要内容,如果未能解决你的问题,请参考以下文章
无法计算构建计划:无法解析插件 org.apache.maven.plugins:maven-jar-plugin:2.3.2 或其依赖项之一
Android Gradle 插件Gradle 依赖管理 ③ ( build.gradle#dependencies 依赖分组 | configurations 自定义依赖分组 )