魔鬼作坊代码注入器_代码依赖是魔鬼。

魔鬼作坊代码注入器

“Change is the only constant…” – Heraclitus (Philosopher)
“变化是唯一不变的……” –赫拉克利特(哲学家)

The tools, libraries, and frameworks we use to build our web applications today are drastically different from the ones we used just a few short years ago.

我们今天用来构建Web应用程序的工具,库和框架与短短几年前所使用的工具,库和框架完全不同。

In a few short years from now, most of these technologies will have changed dramatically again. Yet, many of us make these a central, inextricable part of our apps.

从现在起的短短几年内,这些技术中的大多数将再次发生巨大变化。 但是,我们许多人将这些作为我们应用程序中不可或缺的核心部分。

We import, use, and inherit from the flavor-of-the-month frameworks as if they’re all going to be around and unchanged forever. Well… they’re not. And that’s a problem.

我们导入,使用和继承月度风格的框架,好像它们将永远存在并且永远不变。 好吧……他们不是。 那是个问题。

After 20+ years of developing, designing, and architecting web applications, I’ve come to appreciate two important truths:

经过20多年的开发,设计和架构Web应用程序,我逐渐意识到两个重要的事实:

  1. External dependencies pose a great threat to the long term stability and viability of any application.

    外部依赖关系对任何应用程序的长期稳定性和可行性都构成了巨大威胁。
  2. It’s increasingly difficult — if not impossible — to build any kind of non-trivial app without leveraging external dependencies.

    在没有利用外部依赖关系的情况下,构建任何类型的非平凡应用程序变得越来越困难,甚至不是不可能。

This article is about reconciling these two truths so that our apps have the greatest chance of long-term survival.

本文旨在调和这两个真理,以便我们的应用具有最大的长期生存机会。

兔子洞确实很深。 (The rabbit hole is very deep indeed.)

If we start thinking of all the things our web apps depend upon it’s easy to think of a dozen or more before we even get to the code:

如果我们开始考虑我们的Web应用程序所依赖的所有事物,那么在进入代码之前就很容易想到十几个或更多:

  • Power

    功率
  • Connectivity

    连接性
  • Firewall

    防火墙功能
  • DNS

    域名解析
  • Server Hardware (CPU, Disk, Ram, …)

    服务器硬件(CPU,磁盘,Ram等)
  • Cooling

    冷却
  • Virtualization Platform

    虚拟化平台
  • Container Platform

    集装箱平台
  • Operating System

    操作系统
  • Web Server Platform

    Web服务器平台
  • App Server Platform

    应用服务器平台
  • Web Browser

    网页浏览器

As developers, it’s good to be aware of these things, but there’s often not much we can do about them. So, let’s ignore them for now and talk only about the code.

作为开发人员,意识到这些事情是件好事,但是我们对此通常无能为力。 因此,让我们暂时忽略它们,仅讨论代码。

In code, there are three kinds of dependencies:

在代码中,存在三种依赖关系:

1.我们控制的依赖性 (1. Dependencies we control)

This is code written and owned by us or our organization.

这是我们或我们的组织编写和拥有的代码。

2.我们无法控制的依赖性 (2. Dependencies we don’t control)

This is code written by a third party vendor or open-source software community.

这是由第三方供应商或开源软件社区编写的代码。

3.依赖关系一旦删除 (3. Dependencies once removed)

These are the code dependencies our third-party code dependencies depend upon. (Say that three times fast!)

这些是我们的第三方代码依赖关系所依赖的代码依赖关系。 (快说三遍!)

We’re going to talk mainly about dependencies we don’t control.

我们将主要讨论我们无法控制的依赖项

Dependencies we control and dependencies once removed can still cause headaches, but in the case of dependencies we control, we should be able to directly intervene and mitigate any problems.

我们控制的 依赖项以及一旦删除的依赖项仍然会引起头痛,但是在我们控制的依赖项的情况下,我们应该能够直接进行干预并减轻任何问题。

In the case of dependencies once removed, we can usually rely on a third-party to take care of it for us, since they are dependent on these, too.

对于依赖项一旦被删除,我们通常可以依靠第三方来为我们处理,因为它们也依赖于它们。

为什么第三方代码依赖关系很好 (Why third-party code dependencies are good)

A large portion of your web application exists to solve common problems: authentication, authorization, data access, error handling, navigation, logging, encryption, displaying a list of items, validating form inputs, and so on...

您的Web应用程序中有很大一部分用于解决常见问题:身份验证,授权,数据访问,错误处理,导航,日志记录,加密,显示项目列表,验证表单输入,等等。

Regardless of which technology stack you use, there’s a good chance that common solutions to these problems exist, and are available as libraries that you can easily acquire and plug-in to your codebase. Writing any of this stuff completely from scratch is generally a waste of time.

无论您使用哪种技术堆栈,都有很大的机会存在针对这些问题的通用解决方案,并且可以作为可轻松获取并插入到代码库中的库提供。 完全从头开始编写所有这些东西通常是浪费时间。

You want to concentrate on code that either solves an uncommon problem or solves a common problem in an uncommon way. That’s what makes your application valuable: the code that implements the business rules that are unique to your app alone — the “secret sauce.”

您想专注于解决不常见问题或以不常见方式解决常见问题的代码。 这就是使您的应用程序变得有价值的原因:仅实现您的应用程序独有的业务规则的代码-“秘密秘诀”。

Google’s search and page ranking algorithm, Facebook’s timeline filtering, Netflix’s “recommended for you” section and data compression algorithms— the code behind all of these features is “secret sauce.”

Google的搜索和页面排名算法,Facebook的时间轴过滤,Netflix的“为您推荐”部分以及数据压缩算法-所有这些功能背后的代码都是“秘密调味料”。

Third-party code — in the form of libraries — allows you to quickly implement those commoditized features of your app, so you can stay focused on your “secret sauce.”

第三方代码(以库的形式)使您可以快速实现应用程序的那些商品化功能,因此您可以专注于“秘密调味料”。

为什么第三方代码依赖性不好 (Why third-party code dependencies are bad)

Take a look at any non-trivial web-app built in the last couple of years and you’ll be absolutely astounded by the amount of code that actually comes from a third-party library. What if one or more of those third-party libraries changes drastically, or disappears, or breaks?

看看过去几年中构建的任何平凡的Web应用程序,您都会对来自第三方库的实际代码量感到惊讶。 如果这些第三方库中的一个或多个第三方库发生巨大变化消失中断怎么办?

If it’s open-source, perhaps you can fix it yourself. But how well do you understand all the code in that library you don’t own? A big reason why you use a library in the first place is to get the benefits of the code without having to worry about all the details. But now you’re stuck. You’ve completely tied your fortune to these dependencies that you don’t own and don’t control.

如果它是开源的,也许您可​​以自己修复。 但是,您对自己不拥有的该库中的所有代码的理解程度如何? 首先使用库的一个重要原因是无需担心所有细节即可获得代码的好处。 但是现在你被困住了。 您已将自己的命运完全与那些您不拥有且无法控制的依赖项联系在一起。

Perhaps you think I’m exaggerating, or speaking from a purely academic point of view. Let me assure you — I have dozens of examples of clients who completely snookered themselves by embedding third-party code too tightly into their app. Here‘s just one recent example…

也许您认为我是在夸大其词,或者纯粹从学术角度来说。 让我向您保证-我有数十个示例,这些示例通过将第三方代码过于紧密地嵌入到他们的应用程序中而完全欺骗了自己。 这只是最近的一个例子……

A former client of mine built their app using a Backend-as-a-Service provider owned by Facebook, called Parse. They used a JavaScript client library provided by Parse to consume the Parse service. In the process, they tightly coupled all of their code — including the “secret sauce” code — to this library.

我的一位前客户使用Facebook拥有的名为Parse的后端即服务提供商来构建他们的应用程序。 他们使用了Parse提供JavaScript客户端库来使用Parse服务。 在此过程中,他们将所有代码(包括“秘密调味料”代码)紧密耦合到该库。

Three months after my client’s initial product launch — just as they started getting some good traction with real, paying customers — Parse announced it was shutting down.

在我的客户首次推出产品三个月后(正当他们开始吸引真正的付费客户获得良好的吸引力时),Parse宣布将关闭。

Now instead of focusing on iterating on their product and growing their customer base, my client had to figure out how to either migrate to a self-hosted, open-source version of Parse, or replace Parse completely.

现在,我的客户不必专注于迭代产品并扩大客户群,而不得不想出如何迁移到自托管的开源Parse版本或完全替换Parse的方法。

The disruption this caused for a young, fledgling application was so huge that my client eventually scrapped the app entirely.

这对于一个刚起步的新应用程序造成的破坏是如此巨大,以至于我的客户最终完全放弃了该应用程序。

平衡好与坏 (Balancing the good and the bad)

Several years ago, my go-to solution for overcoming the risks while retaining the benefits of third-party-libraries was to wrap them using the Adapter Pattern.

几年前,我在克服风险的同时保留第三方库利益的首选解决方案是使用Adapter Pattern包装它们。

Essentially, you wrap the third party code in an adapter class or module that you’ve written. This then works to expose the functions of the third party libraries in a manner that you control.

本质上,您将第三方代码包装在您编写的适配器类或模块中。 然后,这将以您控制的方式公开第三方库的功能。

Using this pattern, if a third-party library or framework changes, or goes away, you only have to fix a bit of adapter code. The rest of your app stays intact.

使用此模式,如果第三方库或框架发生更改或消失,则只需修复一些适配器代码。 应用程序的其余部分保持不变。

This sounds good on paper. When you have self-contained dependencies that only provide a few functions, this will do the trick. But things can get ugly fast.

在纸上听起来不错。 当您具有仅提供一些功能的独立依赖项时,这将可以解决问题。 但是事情很快就会变得丑陋。

Can you imagine having to wrap the entire React library (including JSX) before using any of it? How about wrapping jQuery, or Angular, or the Spring framework in Java? This quickly becomes a nightmare.

您能想象使用任何一个库之前都要包装整个React库(包括JSX)吗? 如何用Java包装jQuery,Angular或Spring框架? 这很快成为一场噩梦。

These days I recommend a more nuanced approach…

这些天,我推荐一种更细微的方法……

For each dependency you want to add to your codebase, evaluate the level of risk it will introduce by multiplying two factors:

对于要添加到代码库中的每个依赖项,请通过将两个因素相乘来评估它将引入的风险等级:

  1. The likelihood that the dependency will change in a material way.

    依赖关系将以实质性方式改变的可能性。
  2. The amount of damage a material change to the dependency would do to your application.

    对依赖项进行实质性更改将对您的应用程序造成损害。

A third-party library or framework is less likely to change when some or all of the following things are true:

当满足以下某些或全部要求时,第三方库或框架就不太可能更改:

  • It has been around for several years and has had several major releases.

    它已经存在了几年,并且已经发布了多个主要版本。
  • It is widely used by many commercial applications.

    它被许多商业应用广泛使用。
  • It has the active support of a large organization — preferably a household name company or institution.

    它得到了大型组织(最好是家喻户晓的公司或机构)的积极支持。

A third-party library or framework will do less damage to your application when some or all of the following things are true:

如果满足以下某些或全部要求,则第三方库或框架对您的应用程序的损害较小

  • It’s only used by a small portion of your application, rather than being used throughout.

    它仅在应用程序的一小部分中使用,而不是在整个过程中使用。
  • The code that depends upon it is not part of that “secret sauce” I talked about earlier.

    依赖于此的代码不属于我之前提到的“秘密调味料”。
  • Removing it requires minimal changes to your codebase.

    删除它只需对代码库进行最少的更改。
  • Your entire application is very small and can be rewritten quickly. (Be careful with this one — it’s rarely true for very long.)

    您的整个应用程序很小,可以快速重写。 (请注意这一点-长期以来很少如此。)

The riskier something is, the more likely you should be to wrap it or avoid it altogether.

风险越大,您越有可能将其包装或完全避免使用。

When it comes to the code that is really central to the value proposition of your application —your “secret sauce” — you need to be extremely protective of it. Make that code as independent as possible. If you absolutely need to use a dependency, consider injecting it rather than directly referencing it. Even then, be careful.

当涉及真正对应用程序的价值主张至关重要的代码时,您的“秘诀”就必须得到保护。 使该代码尽可能独立。 如果您绝对需要使用依赖项,请考虑注入它,而不是直接引用它。 即使那样,也要小心。

Sometimes this means saying “no” to a third-party library you think is really cool, or that you really want to use for one reason or another. Be strong. Trust me, it will pay off. Just ask all those people who invested heavily in the very first release of Angular, or my former client who used Parse everywhere. It’s no fun. Believe me.

有时,这意味着对您认为真的很酷的第三方库或出于某种原因而真正要使用的第三方库说“不”。 坚强。 相信我,它将得到回报。 只需问问那些在Angular的第一个发行版中投入大量资金的人,或者我曾在各处使用Parse的前客户。 没意思 相信我。

Speaking of fun, take a look at this…

说到乐趣,看看这个…

The image above is the dependency graph for an application called TinyTag Explorer.

上图是名为TinyTag Explorer的应用程序的依赖图。

Generating a dependency graph for your existing apps is a great way to understand the level of risk being introduced by your dependencies. I’ve put together a list of free tools for generating graphs similar to the above in a variety of languages including JavaScript, C#, Java, PHP, and Python. You can get it here.

为现有应用程序生成依赖关系图是了解依赖关系引入的风险级别的一种好方法。 我整理了一系列免费工具,用于以多种语言(包括JavaScript,C#,Java,PHP和Python)生成类似于上述图形的图形。 你可以在这里得到。

帮我帮别人 (Help me help others)

I want to help as many developers as I can by sharing my knowledge and experience with them. Please help me by clicking the ❤ recommend button (green heart) below.

我想通过与他们分享我的知识和经验来为尽可能多的开发人员提供帮助。 请单击下面的❤推荐按钮(绿色的心)为我提供帮助。

Finally, don’t forget to grab your list of free dependency graph generators here.

最后,不要忘了在此处获取免费的依赖图生成器列表。

翻译自: https://www.freecodecamp.org/news/code-dependencies-are-the-devil-35ed28b556d/

魔鬼作坊代码注入器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值