进程终止时有子线程未终止_接口会终止依赖关系吗?

进程终止时有子线程未终止

回应回应

先前的文章探讨了Java程序中传递依赖与抽象方法之间的关系。 海梅·梅切特(Jaime Metcher)在他的博客上对该帖子发表了出色的批评,他总结道:

因此,我怀疑Edmund发现的是接口的使用与模块化程序结构之间的关联。 但这只是一种关联。

这是完全正确的,谢谢Jaime的澄清。

Jaime还提出了更有趣的评论:

最后,接口充当依赖关系终止点的概念似乎有些奇怪。 接口仅表示依赖关系链可能无法通过静态分析发现的点。 毫无疑问,依存关系仍然存在,否则您在运行时对该方法的调用将无济于事。

该博客已经两次 尝试理解接口如何与结构相关联,并且以上内容清楚地说明了挑战。

那么:接口会终止依赖关系吗?

程序员可能会相信他们这样做的原因有两个。

首先,程序员出于多种原因研究结构,其中之一就是成本分析。

在结构较差的程序中,对一个位置的代码进行更改会导致许多其他地方的更改(可怕的波纹效应 ),从而增加了功能介绍和修改的成本。 一个结构良好的系统可以简化这种成本预测,并且通常可以降低成本,因为程序员可以轻松地了解各个部分之间的相互依赖关系。

这几乎完全是文字问题。

源代码是文本。 程序员通过更新文本来更新代码。 涟漪效应是文本关系的野兽。 该文本结构可能会在运行时生存,也可能无法生存,但是程序员很少拼接字节码以节省成本。

从这种文本意义上说,接口终止依赖关系:它们终止文本依赖关系。 在接口A上具有文本依赖性的客户端类对实现A的任何类均不具有文本依赖性。

当然,实现可能会发生变化,从而迫使接口发生更改,这将波及到客户端类,这将我们带到了第二点。

接口终止依赖关系的第二个原因是:程序员的意图。

程序员使用抽象来允许超出具体依赖项所提供的更改程度。 当一个客户类别必须依赖其他两个行为截然不同的类别时,那就这样吧。 但是,如果这取决于多个相似的行为,并且程序员知道积压的积压行为更多,那么程序员可能会选择提取一个接口来捕获相似的行为,从而减少客户端类的暴露程度,从而减少连锁React,给其服务提供商。

界面变成了脆脆的霓虹灯,由程序员的意图驱动,上面写着:“看! 这是一个减少连锁React可能性的地方,因为我认为所有这些行为都是相同的,我们可以添加更多而不会影响客户!”

同样,这就是令人讨厌的成本模型。

您可以根据自己的喜好随意建模潜在的更新成本,包括将接口建模为非终止依赖关系,因此,使客户端类依赖于该接口背后的所有实现。 但是,然后您的成本模型将完全忽略程序员试图降低纹波效应成本的那些霓虹灯:您的成本模型将被高估。

当然,更糟糕的情况是,您会在终端接口成本模型中变得非常奢侈,但使用抽象技术的程度如此之高,以至于实际上并未降低纹波效应成本:那么您的模型将低估成本。

这两个论点的重点在于,专注于源代码结构而不考虑运行时结构通常是值得的,因为这是在程序员竞争成本的源代码领域。

进程终止时有子线程未终止_接口会终止依赖关系吗?

证据在哪里?

但是等一下 这一切的证据在哪里? 如此强大的功能肯定会在我们的程序中留下痕迹。 我们甚至怎么知道程序员将接口用作降低纹波效应概率的点?

要回答这个问题很容易。 只需采访一个大型项目中的所有开发人员,在项目的整个生命周期中回顾所有发行版中数以万计的方法,确定哪些方法发生了变化,确定哪些变化会直接或通过接口更改调用方法,计数百分比,如果可以显示受接口影响的客户端比直接依赖关系少,那么您已经展示了一种成本模型,该模型可以某种方式验证接口终止依赖关系。

然后,与其他五个大型项目重复该过程,以获取数十万种方法的良好统计样本。

嗯:不。

我们能做的是启动一个解析器,该解析器可以识别各种软件项目的连续发行版中方法的更改。 当然,由于是自动化的,因此它无法确定某个实现的更改(例如,什么实现)导致其更改的接口客户端发生了更改:这两个更改可能是独立发生的。 尽管如此,我们希望通过噪声看到一些相关性。

理想情况下,我们希望任何证据都采用红色和蓝色两个图形的形式。

显示百分比而不是绝对值(程序具有比接口更多的具体类,因此仅显示比直接接口少的接口介导的更改会太弱),红线表示每个发行版中已更改方法的数量,其调用方法也已更改,占已更改方法总数的百分比。 这将暗示沿着直接的具体依赖关系起作用的涟漪效应。

蓝线将显示当接口方法的任何实现也发生更改时,调用接口方法的已更改客户端方法的数量,占已更改实现方法总数的百分比。 这将暗示通过接口起作用的波纹效应。

因此,“接口终止依赖关系”的假设将简单地要求在项目的绝大多数生命周期中,红线都高于蓝线。

图1显示了Spring核心jar文件的22个连续发行版。

进程终止时有子线程未终止_接口会终止依赖关系吗?

图1:Spring 0.9.0 – 3.2.2版本中的涟漪效应。

在21个数据点中,有17个显示出比通过依赖关系更直接的纹波效应。

图2显示了Struts的 20个连续发行版。

进程终止时有子线程未终止_接口会终止依赖关系吗?

图2:Struts 1.0.2 – 2.3.8版中的波纹效应。

19个数据点中的15个显示出比通过接口更直接的纹波效应。

图3显示了Apache Lucene核心jar文件的26个连续发行版。

进程终止时有子线程未终止_接口会终止依赖关系吗?

图3:Lucene核心版本1.9 – 4.3.0中的纹波效应。

也许是最清晰的证据集。

图4显示了JUnit的 14个连续发行版。

进程终止时有子线程未终止_接口会终止依赖关系吗?

图4:JUnit版本3.7 – 4.11中的涟漪效应。

与JUnit混为一谈,但13个数据点中的9个显示出比通过接口更直接的波纹效应。

图5显示了Apache Maven核心jar文件的22个连续发行版。

进程终止时有子线程未终止_接口会终止依赖关系吗?

图5:Apache Maven版本1.0.0 – 3.3.9中的涟漪效应。

21个数据点中的17个显示出比通过接口更直接的纹波效应。

图6显示了Apache log4j核心jar文件的22个连续发行版。

进程终止时有子线程未终止_接口会终止依赖关系吗?

图6:Apache Maven版本1.0.4 – 2.4.1中的涟漪效应。

21个数据点中的18个显示出比通过接口更直接的纹波效应。

并非所有这些都能证明任何事情。

该假设的有效性受到了许多威胁,以至于该帖子只不过是数字信封背面的涂鸦。 正如Jaime指出的那样,数据似乎表明存在相关性,但没有证明这一点。

再者,正如Jaime所指出的那样,这不应该鼓励您使用简单的接口来打包您的项目,以减少纹波效应的成本。 必须明智地使用抽象。 确实,这种关联(如果存在的话)将有助于识别无意义的抽象,因为在不维护关联的情况下添加更多接口将表明抽象不会增加其权重。

但是,“直接波纹效应与通过接口的波纹效应之间的相关性”有点令人mouth舌,而且,如果进一步的研究证明这种相关性与统计严格性相称,那将是一个名字。

因此,除非Jaime反对,否则我们将其称为“ Metcher相关性”。

摘要

“接口终止依赖关系”并不是对与错,这是软件开发成本模型中的一个假设。 如果做出这样的假设,那么您将获得一个成本模型。 如果不这样做,就会得到另一个。 问题是:哪种成本模型更为准确?

如果您发现将接口建模为终止依赖关系更准确地反映了您的代码的实际情况,那么请假设“接口终止依赖关系”。

如果您不这样做,请不要。

PS直到2016年2月,所有原始数据以及人类乏味的解析器中的相当可悲的内容都将在此处提供

翻译自: https://www.javacodegeeks.com/2015/12/interfaces-terminate-dependencies.html

进程终止时有子线程未终止