如何应对依赖依赖的恐惧


54

我所在的团队创建了可供公司合作伙伴用来与我们的平台集成的组件。

因此,我同意在引入(第三方)依赖项时应格外小心。当前,我们没有第三方依赖项,我们必须保持框架的最低API级别。

一些例子:

  • 我们被迫停留在框架的最低API级别(.NET标准)上。其背后的原因是,有一天可能会出现一个仅支持非常低的API级别的新平台。
  • 我们已经实现了自己的用于(反)序列化JSON的组件,并且正在对JWT进行同样的处理。在更高级别的框架API上可用。
  • 我们已经围绕标准库的HTTP框架实现了包装器,因为我们不想依赖于标准库的HTTP实现。
  • 同样,出于同样的原因,所有用于映射到XML或从XML映射的代码都是“手工”编写的。

我觉得我们走得太远了。我想知道如何处理这个问题,因为这会极大影响我们的速度。


20
是否有正当的理由(例如外部要求)还是出于无知?
Blrfl

6
对代码库的一小部分进行实验,创建一个隔离层,该隔离层不会尝试成为通用库,而是定义一个对您的需求进行建模的抽象接口;然后将您自己的实现和第3方依赖关系置于其后,并比较两个版本的工作/性能。权衡利弊,评估交换实现的难易程度(或难易程度),然后做出决定。简而言之,以相对低风险的方式进行测试,看看会发生什么,然后再决定。
FilipMilovanović

73
“当前,我们没有第三方依赖项”,当人们声称这样做时,这总是让我发笑。当然可以 您尚未编写任何标准库的自己的编译器,IDE实现。您尚未编写任何间接(或直接)使用的分片对象库。当您意识到需要多少第三方软件和库时,您可以放弃“依赖关系很糟糕”的想法,而不必重新发明轮子。我只是标记您具有的依赖项,然后问为什么它们可以接受,但是json解析是不可接受的。
UKMonkey

8
就是说,还有其他的缺点,比如永远不要完成项目。但这确实促进了软件工作和就业:)
元帅工艺

5
没错,您正在通过重新发明商品软件来浪费精力。您错了,因为这与“避免所有依赖关系”相去甚远。Microsoft的Excel团队曾经编写自己的C编译器,以避免依赖Microsoft的C团队。您对操作系统,高级框架等有着极大的依赖性。
埃里克·利珀特

Answers:


94

...我们被迫停留在框架的最低API级别(.NET标准)...

对我而言,这凸显了一个事实,不仅您可能会限制自己过多,而且您的方法可能还会导致令人讨厌的跌倒。

.NET Standard不是,也永远不会是“ 框架的最低API级别 ”。通过创建针对Windows Phone和Silverlight的可移植类库,可以实现针对.NET的一组限制性最强的API。

根据所针对的.NET Standard版本,最终可以得到与.NET Framework,.NET CoreMonoXamarin兼容的非常丰富的API集。并且有许多兼容.NET Standard的第三方库,因此可在所有这些平台上运行。

然后是.NET Standard 2.1,可能会在2019年秋季发布。它将由.NET Core,Mono和Xamarin支持。至少在可预见的将来,.NET Framework的任何版本都将不支持它,并且很可能始终如此。因此,在不久的将来,.NET标准将不再是“ 框架的最低API级别 ”,而是将取代该框架,并具有该框架不支持的API。

因此,请特别小心“ 其背后的原因是,有一天新平台可能仅支持非常低的API级别 ”,因为新平台实际上很可能比旧框架支持更高级别的API。

然后是第三方库的问题。例如,JSON.NET与.NET Standard兼容。与API兼容的任何与.NET Standard兼容的库都可以与该版本的.NET Standard兼容的所有.NET实现一起使用。因此,通过不使用它并创建JSON库,您不会获得任何其他兼容性。您只需为自己创造更多工作,并为公司带来不必要的成本。

所以是的,在我看来,您绝对是太过分了。


16
“您只需为自己创造更多的工作,并为公司带来不必要的成本。” -和担保责任。如果给它递归对象,JSON编码器是否会因堆栈溢出而崩溃?您的解析器是否正确处理了转义字符?它是否拒绝应该转义的字符?未配对的代理字符如何?当JSON编码的数字大于2 ^ 64时,它会溢出吗?还是只是一个eval带有一些健全性检查且可以轻松绕开的包装纸?
John Dvorak

4
“通过创建针对Windows Phone和Silverlight的可移植类库,可以实现针对.NET的一组限制性最强的API。” 我会大胆地宣称,该子集中至少有一些API不受曾经存在的所有可能实现的支持(而且再也没有人关心WinPhone或Silvernight,甚至没有Microsoft)。使用.NetStandard 2.0作为现代框架的目标似乎非常谨慎,没有特别的限制。更新到2.1是一个不同的故事,但没有迹象表明他们会这样做。
Voo

除了未来的平台可能支持更多而不是更少之外,为所有可能发生的事情进行开发的成本非常高(而且您可能仍然会错过一些东西)。相反,不重新发明轮子开发节省更多的时间比适应一些新的情况时,需要的是要成本。
贾斯珀

51

我们被迫停留在框架的最低API级别(.net标准)上。其背后的原因是,有一天可能会出现一个仅支持非常低的API级别的新平台。

这里的推理相当落后。与较新的API相比,较旧的较低API级别更可能变得过时且不受支持。虽然我同意在“前沿”后面保持舒适的态度是明智的,以确保在您提到的方案中具有合理的兼容性水平,但永不超越​​是极端的。

我们已经实现了自己的用于(反)序列化JSON的组件,并且正在对JWT进行同样的处理。在更高级别的框架API中可用。我们已经围绕标准库的HTTP框架实现了包装器,因为我们不想依赖于标准库的HTTP实现。同样,出于同样的原因,所有用于映射到XML或从XML映射的代码都是“手工”编写的。

这是疯狂。即使您出于某种原因不想使用标准库功能,开放源代码库也具有可实现上述所有功能的商业兼容许可证。它们已经被编写,从功能,安全性和API设计的角度进行了广泛的测试,并在许多其他项目中得到了广泛的使用。

如果最坏的情况发生了,并且那个项目消失了,或者停止了维护,那么您仍然拥有构建该库的代码,并指派了一个人来维护它。而且您可能仍然比自己动手做得更好,因为实际上您将需要更多经过测试,更干净,更可维护的代码。

在更可能的情况下,该项目得以维护,并且在这些库中发现了错误或漏洞利用,您将了解它们,因此可以采取一些措施-例如免费升级至新版本或修补您的版本如果已复制,请提供修复程序。


3
即使不能,切换到另一个库仍然比滚动自己的库更容易和更好。
莫妮卡(Monica)

5
较低级别的东西死得更快的优点是。这就是建立抽象的重点。
与Monica进行的轻度比赛

“较新的,较低的API级别比新的API更有可能被淘汰和不受支持”。??据我所知,NetSTandards是相互构建的(2.0是1.3 + X)。同样,这些标准仅仅是..标准,而不是实现。谈论一个不再被支持的标准是没有意义的,在将来该标准的大多数特定实现都可能会出现(但请参见前面的内容,为什么它也不是问题)。如果您的库不需要NetStandard 1.3以外的任何内容,则完全没有理由将其更改为2.0
Voo

11

总的来说,这些东西对您的客户都有好处。出于某种原因,即使是流行的开源库也可能使他们无法使用。

例如,他们可能已经与客户签署了一份合同,承诺不使用开源产品。

但是,正如您指出的那样,这些功能并非没有成本。

  • 上市时间
  • 包装尺寸
  • 性能

我会提出这些缺点,并与客户交谈,以了解他们是否真的需要您提供的超级兼容性。

例如,如果所有客户都已经在使用Json.NET,则在产品中使用它而不是您自己的反序列化代码,可以减小它的大小并改善它。

如果您介绍产品的第二个版本,即使用第三方库的版本以及兼容的库,则可以判断两者的使用情况。客户会使用第三方早一点获得最新功能还是坚持使用“兼容”版本?


11
是的,我显然同意,我会在您的列表中添加“安全性”。与经过良好测试的框架和标准库相比,您有可能在代码中引入漏洞,尤其是在诸如JSON / JWT之类的代码中。
Bertus

是的,很难将其列出来,因为显然安全性和性能之类的东西都可能同时出现。但是,在完成功能和确保内部功能完全/理解之间存在明显的利益冲突
Ewan

12
“他们可能已经与客户签署了一份承诺不使用开源产品的合同”-他们使用的是.NET Standard。当您将整个产品基于开放源代码框架时,签署该合同是一个坏主意。
史蒂芬

仍然有人这样做
Ewan

7

简短的答案是您应该开始引入第三方依赖性。在您的下一次站立会议上,告诉大家下周的工作将是他们多年来最开心的事情-他们将用开源的标准库解决方案替换JSON和XML组件。告诉所有人,他们有三天的时间更换JSON组件。完成后庆祝。举行一个派对。这值得庆祝。


2
这也许是面目全非,但这并非不现实。我加入了一家公司,该公司的“高级”开发人员(仅受过教育的高级人员)责成初级开发人员编写状态机库。它有五个月的开发时间,但仍然存在问题,因此我花了几天的时间就将其撕掉并用交钥匙解决方案替换了。
TKK

0

基本上,这全都归功于努力与风险。

通过添加其他依赖项或更新框架或使用更高级别的API,可以减少工作量,但要承担风险。因此,我建议进行SWOT分析

  • 优点:减少工作量,因为您不必自己编写代码。
  • 缺点:并非手工设计的解决方案可满足您的特殊需求。
  • 机会:上市时间更短。您可能会从外部发展中受益。
  • 威胁:您可能会因为其他依赖性而使客户不满。

如您所见,开发手工解决方案的额外工作是降低威胁的投资。现在您可以做出战略决策。


-2

将组件库分为没有依赖性(基本上是您现在正在做的事情)的“核心”集和有“核心”和第三方库的依赖性的“通用”集。

这样,如果某人只想要“核心”功能,他们就可以拥有。

如果有人想要“通用”功能,他们可以拥有。

您可以管理“核心”与“通用”之间的区别。您可以在“通用”中更快地添加功能,如果有必要提供自己的实现,则可以将其移动到自己的“核心”实现中。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.