gradle依赖管理
Why Bother
何必呢
Writing software is a very expensive process, and most systems we interact with today, as technologists or even as regular consumers, are the product of thousands of years of work by different individuals all across the world.
编写软件是一个非常昂贵的过程,并且无论今天是作为技术人员,还是作为普通消费者,我们今天与大多数系统交互的都是世界各地不同个人数千年工作的产物。
For example, the Linux kernel alone is estimated to have cost USD 1.4B dollars. Developing a full Linux distro is said to cost 60,000 Person-Years or 10.8B dollars. This is more money than the combined venture funding received by Latin America tech companies ever. But regardless of the fact that none of these companies could afford building a full-fledged distro, all of them benefit from many different flavors of GNU/Linux.
例如,仅Linux内核估计就花费了1.4B美元。 开发一个完整的Linux发行版据说要花费60,000人年(10.8B美元) 。 这比拉丁美洲科技公司获得的合并风险资金要多。 但是,无论这些公司没有一家负担得起建立完善的发行版的事实,它们都从GNU / Linux的许多不同风格中受益。
Software might be the first kind of knowledge that can be composed. It is hard to develop, but it is often easy to use, and is not even that hard to combine. And the latter is what brings the real magic. It is the closest thing to “building on the shoulders of giants” in the realm of really building stuff. Thanks to the legal, cultural and intellectual foundation laid out by the Free Software movement and others, this often comes for free. Even when there is a dollar price, from the cloud providers or other commercial mechanisms, it is rarely comparable to the high cost of working out all the details alone.
软件可能是可以组成的第一类知识。 它很难开发,但通常易于使用,甚至不难组合。 后者才是真正的魔力。 在真正建造东西的领域中,这是最接近“在巨人的肩膀上建造”的东西。 由于自由软件运动和其他组织奠定了法律,文化和思想基础,因此这通常是免费的。 即使从云提供商或其他商业机制获得一美元的价格,也很难与仅计算所有细节的高昂成本相提并论。
In this document we try to give some guidance on how to benefit from this collective investment that humanity has done for us, and how to see the evidence of when you should be contributing to the pool, not taking from it. Both are beasts hard to tame, and even harder to master. Nonetheless, here is some wisdom to help.
在本文档中,我们尝试提供一些指导,说明如何从人类为我们所做的这项集体投资中受益,以及如何查看何时应向池中捐款而不是从池中提取资金的证据。 两者都是难以驯服,甚至更难掌握的野兽。 但是,这里有一些智慧可以帮助您。
Applicability
适用性
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/b33972e2c1c3c4fcb171cca92519b756.png)
The first question is when you should consider adopting an existing library to solve a problem. The answer is quite straightforward: always. You may not necessarily end up using a library, but the potential benefits are so great that you should at least always spend a bit of time to see what are the choices you have.
第一个问题是何时应考虑采用现有库来解决问题。 答案很简单:总是。 您可能不一定最终会使用库,但是潜在的好处是如此之大,以至于您至少应该总是花一点时间来看看您有什么选择。
Besides the reasons for the development cost described in the last section, there are many other positive aspects in using a well-chosen library. First, future development is paid for. Not only you get the benefits from the code that already exists, but you also get for free future development. For example, from the adoption of or-tools in our codebase to today (roughly 6 months), we have gained almost 2x performance improvements just by bumping versions.
除了上一节中介绍的开发成本原因外,使用精选库还具有许多其他积极方面。 首先,未来的发展是有偿的。 您不仅可以从已经存在的代码中受益,而且还可以免费获得将来的开发 。 例如,从在我们的代码库中采用or-tools到今天(大约6个月),仅通过更改版本即可使性能提高近2倍。
Sometimes libraries can look overwhelming. They have APIs that seem to do more than you need. And you get the feeling that you would be better off by writing the small subset of functionality you need yourself than spending the time putting yourself inside the head of the library author and asking why things are not just what you expect. Be careful on that line, the reality is that you are very likely to bump in the same obstacles that made the library author choose a different path than yours. So, what at first is causing you discomfort, is quite often you are getting the benefits of time-travelling magical hindsight from someone who went through the same journey you are about to onboard.
有时图书馆可能看起来很压倒。 他们提供的API似乎比您需要的功能更多。 通过编写所需的一小部分功能,而不是花时间把自己放在图书馆作者的头上,并问为什么事情不只是您的期望,您会感觉自己会更好。 在这条线上要小心,事实是您很可能遇到相同的障碍,导致图书馆作者选择的路径与您选择的路径不同。 因此,一开始引起您不适的原因是,您经常会从经历了与您即将登船的相同旅程的人那里获得穿越时空的神奇后见之明 。
The trade-offs
权衡取舍
Now that you are convinced that you should consider using a library in your codebase, you need to decide which one to pick, if any. Different organizations adopt different strategies, and using some proxy for popularity seems to be the most common, as you can see in this beginner’s guide for choosing a library, this writeup on open source sustainability or this short piece presenting more popularity signals, such as stack overflows questions. Scientific literature on some of these signals, like github stars, show there is good information there.
既然您已经确信应该考虑在代码库中使用一个库,那么您需要确定选择哪个库(如果有)。 不同的组织采用不同的策略,使用某种流行度代理似乎是最常见的,正如您在本初学者指南中选择图书馆 , 关于开源可持续性的文章或展示更多流行度信号(例如堆栈)的简短文章所看到的那样。溢出问题。 关于其中一些信号的科学文献,例如github星 ,表明那里有很好的信息。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/e77cbe4f49f662ddb3e644ef55cfe315.png)
Although it is better than nothing, I find it an insufficient framework, and in Loggi we have adopted instead a set of orthogonal metrics, based on a model for how libraries interact with our codebase and engineers. The main insight is that third party libraries bring (great) incremental benefits but their costs are compositional. Here is a nice equation to describe it.
尽管它总比没有好,但我发现它不是一个不足的框架,在Loggi中,我们基于库如何与我们的代码库和工程师交互的模型采用了一组正交度量。 主要的见解是, 第三方库带来了(巨大的)增量收益,但它们的成本却是组成成分 。 这是一个很好的方程式来描述它。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/e3c8f367c62d3855e2d43c366c5414b5.png)
What we are capturing this is that for each library xi we adopt, our productivity is incrementally increased by some amount f(xi), which depends essentially on the library itself. However, we pay an overall penalty by having to integrate the library with our codebase, and that penalty, g, depends on the interaction of the library with all the others in the codebase, x. The overall effect is significant and exacerbated for each library we add, like composite interest, so while we see the summation of benefits, our productivity loss gets multiplied by the more distinct libraries we use.
我们正在捕获的是,对于我们采用的每个库xi ,我们的生产率都会以一定的增量f(xi)递增,这主要取决于库本身。 但是,由于必须将库与我们的代码库集成在一起,因此要付出总体代价,而惩罚g取决于库与代码库x中所有其他库之间的交互作用。 对于我们添加的每个库,总体效果都是显着的,并且加剧了这种情况,例如综合利息,因此,尽管我们看到了收益的总和,但生产力损失却因我们使用的更加独特的库而倍增。
Let us use a simple example to understand. Assume you have a frontend codebase using vanilla js (i.e., no libraries or frameworks). You decide, very correctly according to our model, to save a lot of work by adopting AngularJS. This is one of the most popular and well maintained frameworks, so it hits home on any “choosing a library guide”. That makes the first component of our equation increase, and has little impact on the second, since you use no other libraries. Now, rinse and repeat, and add another great library to your codebase, ReactJS. Equally popular and well maintained. Now you have a more productivity codebase right? Well, not. The left side of the equation continued to increase, but the right side increased faster, since it is super hard to combine ReactJS and AngularJS and now you have the worst nightmare of many developers.
让我们用一个简单的例子来理解。 假设您有使用香草js的前端代码库(即,没有库或框架)。 您可以根据我们的模型非常正确地决定采用AngularJS来节省大量工作。 这是最流行且维护良好的框架之一,因此在任何“选择图书馆指南”中都可以找到。 由于不使用其他库,因此这增加了方程式的第一个组成部分,而对第二个组成部分的影响很小。 现在,冲洗并重复,然后在您的代码库中添加另一个出色的库ReactJS。 同样受欢迎并且维护得很好。 现在您有了更高的生产力代码库,对吗? 好吧,不是。 等式的左侧继续增加,但是右侧增加更快,因为将ReactJS和AngularJS组合起来非常困难,现在您面临许多开发人员的噩梦。
This is not just a hypothetical example. It happens everyday in many companies, and when it is noted, it is too late. For large organizations, it is often deemed unavoidable, and the microservices movement (and its less popular cousin, microfrontends) focus instead on dealing with that problem at the infrastructure level instead of preventing it. In the past we had in our codebase cocoa, reactjs, react-native, kotlin, angular and other frameworks I don’t even remember, and for every new component in our design system we had to reimplement it in all these codebases. You can’t avoid the dragons, but you need to work hard to keep them at bay.
这不仅仅是一个假设的例子。 它在许多公司中每天都在发生,并且注意到它为时已晚。 对于大型组织来说,这通常被认为是不可避免的,而微服务运动(及其流行度较低的表亲,微前端)则侧重于在基础架构级别解决该问题,而不是预防该问题。 过去,我们甚至不记得代码库中的可可,reactjs,react-native,kotlin,angular和其他框架,对于我们设计系统中的每个新组件,我们都必须在所有这些代码库中重新实现。 您无法回避这些巨龙,但是您需要努力工作才能将它们拒之门外。
Before we go deeper in how to estimate f and g in the equation, notice I chose to only model whether we use or not a library, not how much we use it. This yields an important corollary: you can always use a library someone else is using, no questions asked. Without that, the decision making process becomes just too convoluted, and people will fall to analysis paralysis. In practice, it is a reasonable approximation, and reverting past decisions are separate projects, not part of the day to day work.
在深入了解如何在方程式中估算f和g之前 ,请注意我选择仅对是否使用库进行建模,而不是对库的使用量进行建模。 这产生了一个重要的推论:您可以随时使用其他人正在使用的库,而无需问任何问题。 否则,决策过程将变得太复杂,人们将陷入分析瘫痪。 实际上,这是一个合理的近似值,还原过去的决定是单独的项目,而不是日常工作的一部分。
Computing your choices
计算您的选择
To estimate how much benefit and cost a given library can bring to our codebase, we will look at four independent dimensions: value, momentum, surface and dispersion. The first one is where the conversation started: how many engineer-years would take to develop that code in-house. The second is closely related with popularity, and captures how likely your decision is to withhold the test of time. The last two are related to the penalty side of our equation. Surface is about the cognitive cost that a library brings to your organization, and dispersion captures how many roles the library may end (intently or not) playing in your code. Let us try to create a visualization for some definition of these metrics to see how it feels.
为了估计给定库可以为我们的代码库带来多少收益和成本,我们将研究四个独立的维度: 价值,动量,表面和分散 。 第一个是对话开始的地方:内部开发该代码需要花费多少工程师年。 第二个因素与受欢迎程度密切相关,并记录了您的决定是否有可能拒绝时间的考验。 最后两个与我们方程式的惩罚方面有关。 Surface是关于库带给您的组织的认知成本,而分散则捕获了库可能在您的代码中(有意或无意)扮演多少角色。 让我们尝试为这些指标的一些定义创建可视化效果,以查看其感觉。
Let us talk about value first, which is the simplest concept. We can decide the scale for that is indeed the number of the engineers-years invested in that library. The COCOMO methodology is an established technique for deriving that, and we can find the resulting number for open source libraries in openhub.net. For example, React took 72 years to develop. We will use bubble graph, and encode the time to develop as the bubble size.
让我们首先谈谈价值 ,这是最简单的概念。 我们可以确定规模,实际上就是在该库中投资的工程师年数。 COCOMO方法论是推导该方法论的既定技术,我们可以在openhub.net中找到开放源代码库的最终数量。 例如,React花了72年的时间开发。 我们将使用气泡图,并将开发时间编码为气泡大小。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/b45f57a199b30f105ffa5ed31406cb10.png)
For momentum, we want something like github stars, but without the downsides. In particular, some notion of vitality of the project is important to give us confidence that the library will not rot, and hopefully will thrive bringing new value. This being the most common way people pick libraries, others have thought about this problem before, and we will just take a ride on libraries.io SourceRank. That metric goes from 0 to 30'ish, and we will represent it as the color of our datapoint, going from red to yellow to green. Google spreadsheet plots are not that flexible, so we will discretize it to 5 colors. React is very healthy at 34 points, so it gets a nice green tint.
为了获得动力 ,我们想要像github star之类的东西,但没有缺点 。 特别是,对于项目充满活力的一些概念很重要,它使我们相信图书馆不会腐烂,并希望能够繁荣发展并带来新的价值。 这是人们选择图书馆的最常见方式,其他人之前也曾考虑过这个问题,我们将乘搭library.io SourceRank 。 该指标从0到30'ish,我们将其表示为数据点的颜色,从红色到黄色再到绿色。 Google电子表格的绘图不够灵活,因此我们会将其离散化为5种颜色。 React的34点非常健康,因此具有不错的绿色调。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/c706dfafddf6c64f49ddebf7eb86a4b3.png)
The concept of surface is less commonly talked about, and we couldn’t find any well established metrics for it. This JSConf talk on Minimal API Surface Area is very much on target, and even mentions lodash, my favorite example of a library we should not adopt. It saves a little bit of typing for sure (low value), but it is even funny how it automatically gets mentioned on virtually every code review. The way this article extends the notion of surface cost to the personal life of an open source programmer also connects to the concept we are defining here. Essentially, how many new contact points an extra library brings to your codebase and organization? The larger the surface, more it hurts your codebase, so it better brings a lot of value. We will try to capture that by defining the x-axis of our graphic as the log of the number of files in our codebase with imports from that library. We compute it with some bash-fu: rg “import.*’react” .|cut -d: -f1 | sort -u|wc -l. For react, this yields 3060, whereas lodash scores at 450, and we take the log. Let us see how they look in our graph.
表面的概念鲜为人知,我们无法找到任何完善的指标。 关于最小API表面积的 JSConf讨论非常有针对性,甚至提到lodash,这是我不应该采用的我最喜欢的库示例。 它可以节省一定的键入时间(低价值),但有趣的是,它几乎在每次代码审查中都自动被提及。 本文将表面成本的概念扩展到开源程序员的个人生活的方式也与我们在此定义的概念有关。 本质上,一个额外的库为您的代码库和组织带来了多少个新的联系点? 表面越大,对代码库的损害越大,因此更好地带来了很多价值。 我们将尝试通过将图形的x轴定义为代码库中从该库导入的文件数的日志来捕获该图像。 我们用一些bash-fu来计算它:rg“ import。*'react”。| cut -d:-f1 | 排序-u | wc -l。 对于React,结果为3060,而lodash得分为450,我们取对数。 让我们看看它们在图中的外观。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/fe6d359a9685ae3a31094fe51a81264f.png)
To wrap up our graph, we will use dispersion as the scale for y-axis. This is a way to express how much your library resembles a swiss-knife, the ultimate tool, which can do everything, and does everything poorly. When you pick a well-focused library, it is clear which role it will play in your codebase, and it leaves room for libraries focused on different topics. But if you pick a large framework, which does a lot of things, there won’t be room for another one of those. For example, when we chose Micronaut as the JVM framework for our codebase, we knew we were giving up on Spring (a swiss knife itself). Although this is hard to define formally, we try to proxy it through the number of names a programmer needs to summon to use the library. Again, with some bash-fu we count unique symbols imported in our codebase: rg “import.*’react” .|cut -d: -f2-|tr ‘ ‘ ‘\n’| tr -d ‘{},’ | grep -v ‘from\|import\|\’.*\’;\|^’|sort -u|wc -l. Material-ui is at 164, close to react, and in the other extreme we have quagga2, exporting a single symbol. Let us see the full graph with some of the libraries in our codebase, again taking the log for the axis.
为了包裹我们的图,我们将色散用作y轴的比例。 这是一种表达您的库多少像瑞士刀的终极工具,它可以完成所有工作,并且可以完成所有工作。 当选择一个重点突出的库时,很明显它将在代码库中扮演哪个角色,并且为专注于不同主题的库留出了空间。 但是,如果您选择一个大型框架,该框架可以完成许多工作,那么再也没有空间容纳这些框架了。 例如,当我们选择Micronaut作为代码库的JVM框架时,我们知道我们已经放弃了Spring( 瑞士刀本身 )。 尽管很难正式定义它,但是我们尝试通过程序员需要召集来使用该库的名称数来代替它。 同样,通过一些bash-fu,我们计算了在代码库中导入的唯一符号:rg“ import。*'react”。| cut -d:-f2- | tr''\ n'| tr -d'{},'| grep -v'from \ | import \ | \'。* \'; \ | ^'| sort -u | wc -l。 Material-ui处于164,接近React,而在另一个极端,我们有quagga2,输出单个符号。 让我们在代码库中查看带有某些库的完整图形,再次以轴的日志为例。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/70718926b9afbca85894d622fc6a2be3.png)
So, value and momentum contribute to the positive side of our equation, f, while surface and dispersion contribute to the negative side, g. Looking at the graph, you want to have most of your libraries close to the plane origin, and you want to be very careful with the right-upper side of the graph, where only a few large, green circles can live. This visualization hints that lodash, redux and relay are not generating the same kind of benefit as the other libraries around them, namely react, material-ui and moment. The fairly new xstate and formik are a bit risky, and react-testing-library is getting a free pass for being a testing-only dependency. Yup, dexie and guagga2 are very specialized and well contained, and hence an easy choice to have in the codebase.
因此,值和动量对方程f的正向有贡献,而表面和色散对方程g的负有贡献。 查看该图,您希望大多数库都靠近平面原点,并且要非常谨慎地注意图的右上侧,其中只能容纳几个大的绿色圆圈。 该可视化提示lodash,redux和relay与周围的其他库(即React,Material-UI和Moment)所产生的好处不同。 相当新的xstate和formik有点冒险,而react-testing-library由于只是测试的依赖而获得免费通行证。 Yup,dexie和guagga2非常专业并且包含良好,因此可以轻松地在代码库中选择。
As for the equation itself, it provides intuition, but we don’t actually compute its value for the whole codebase, after all the inputs are noisy and it is an oversimplification of a complex social process. Nonetheless, you want to feel that you can get a positive result. Here is how a localized exercise looks like:
至于方程本身,它提供了直觉,但是在所有输入都是嘈杂的之后,我们实际上并没有计算出整个代码库的价值,这是对复杂的社会过程的过度简化。 尽管如此,您仍希望能够获得积极的结果。 这是一个局部练习的样子:
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/ec3bbd9f2201e44a1917022eee69fe13.png)
The plot and the whole computation are connected to a google spreadsheet where you just need to feed SourceRank, person-years of development and the output of the bash incantations mentioned here to give your own codebase a try. The final numbers may be too noisy, but I suspect you will learn a lot and be able to think better on your policy of adopting 3rd party libraries.
该图和整个计算都连接到一个Google电子表格 ,您只需在其中馈送SourceRank,开发人员年数和此处提到的bash咒语的输出,即可尝试自己的代码库。 最终的数字可能太吵了,但我怀疑您会学到很多东西,并且能够更好地考虑采用第三方库的政策。
If you are looking for a new job opportunity, we are hiring new Loggers to work in Brazil and Portugal, check out our open positions here!
翻译自: https://medium.com/swlh/dependency-management-a6cce61660d
gradle依赖管理