如何利用JavaScript的默认参数进行依赖注入

by Ricardo Sousa

里卡多·索萨(Ricardo Sousa)

如何利用JavaScript的默认参数进行依赖注入 (How to take advantage of JavaScript’s default parameters for Dependency Injection)

These days it’s quite common to use Dependency Injection, which allows a projects’ modules to be loosely coupled. But as projects grow in complexity, we have an astronomical number of dependencies to control.

如今 ,使用“ 依赖注入”已经很普遍了,它可以使项目的模块松散地耦合在一起。 但是随着项目的复杂性增加,我们需要控制的天文数字也很多。

To work around this problem, we often turn to dependency injection containers. But is it necessary in every situation?

要变通解决此问题,我们经常转向依赖项注入容器。 但是在每种情况下是否有必要?

In this post, I’ll cover how JavaScript’s default parameters can help us with this question. To do this, we will implement a simple application in Node.JS. It will have the functionalities of creating and reading users’ information using three different approaches:

在本文中,我将介绍JavaScript的默认参数如何帮助我们解决这个问题。 为此,我们将在Node.JS中实现一个简单的应用程序。 它具有使用三种不同方法创建和读取用户信息的功能:

  1. Without Dependency Injection

    没有依赖注入
  2. With Dependency Injection

    带依赖注入
  3. With Dependency Injection and default parameters

    具有依赖注入和默认参数

项目结构 (Project structure)

We will structure our example project by feature (by the way — don’t structure your files around roles). So, the structure will be something like this:

我们将构建我们的示例项目由功能 (顺便说一句-不要围绕构建你的角色文件)。 因此,结构将如下所示:

├── users/│   ├── users-repository.js│   ├── users.js│   ├── users.spec.js│   ├── index.js├── app.js

Note: For the purpose of this example, we will save the users’ information in memory.

注意 :出于本示例的目的,我们将用户的信息保存在内存中。

没有依赖注入 (Without Dependency Injection)

Analyzing the previous code, we verify that we are limited by the statement: const usersRepo = require('./users-repository') in users. The users module, with this approach, is strongly coupled to the users-repository.

分析上面的代码中,我们确认我们是被限制的语句: const usersRepo = require('./users-repository')用户 。 通过这种方法, 用户模块与用户存储库紧密耦合

This limits us to using the implementation of another repository without changing the require statement. When the require is used, we create a static dependency to the required module. With that, we can’t use another repository in the app model besides the one defined by the users-repository module.

这限制了我们在不更改require语句的情况下使用另一个存储库的实现。 使用require时 ,我们将对所需模块创建静态依赖项。 这样,除了用户存储库模块定义的存储库之外,我们无法在应用程序模型中使用其他存储

Besides that, we are also bound to the users-repository in the users-spec because of the static dependency mentioned previously. These unit tests are for testing only the users module and nothing more. Imagine if the repository was connected to an external database. We would have to interact with the database in order to be able to test.

除此之外,由于前面提到的静态依赖性,我们还绑定到users-spec中users-repository 。 这些单元测试仅用于测试用户模块,仅用于测试。 想象一下,如果存储库已连接到外部数据库。 我们必须与数据库进行交互才能进行测试。

带依赖注入 (With Dependency Injection)

With Dependency Injection, the users module is no longer coupled to the users-repository module.

使用依赖注入, 用户模块不再与用户存储库模块耦合。

The main difference from the previous approach is that now we don’t have the static dependency in the users module (we don’t have the statement: const usersRepo = require('./users-repository')). Instead of that, the users module exports a factory function with a parameter for the repository. This allows us to pass any repository to the module at a higher level.

与以前的方法的主要区别在于,现在用户模块中没有静态依赖项(我们没有以下语句: const usersRepo = require('./users-repository') )。 取而代之的是, 用户模块导出带有存储库参数的工厂函数 。 这使我们可以将任何存储库传递到更高级别的模块。

An alternative to the factory function is to add a parameter for the repository’s argument in the functions create and read. But if the two functions are dependent on the same repository, we can encapsulate them with a function and take advantage of the JavaScript’s closures.

工厂函数的替代方法是在函数createread中为存储库的参数添加一个参数。 但是,如果两个函数都依赖于同一个存储库,我们可以将它们封装为一个函数,并利用JavaScript的闭包

Now, in the app module, we have the freedom to define which repository we want to use. Also, look at the unit tests. We can now test the users module without worrying about the repository. Just mock it!

现在,在应用程序模块中,我们可以自由定义我们要使用的存储库。 另外,请看单元测试。 现在,我们可以测试用户模块,而不必担心存储库。 只是嘲笑它

However, let’s be honest — how often do we define dependencies that change throughout the application’s lifecycle? Normally, we try to avoid static dependencies because it makes testing harder. But now, since we want testability, we have to pass an instance of the repository to the users module every time we want to use it.

但是,说实话-我们定义应用程序生命周期中变化的依赖关系的频率是多少? 通常,我们会尝试避免静态依赖,因为它会使测试更加困难。 但是现在,由于我们要具有可测试性,因此每次使用存储库时,都必须将其实例传递给users模块。

You know what would be really awesome? If we were able to use the module without having to give it a repository every time. We can do this in JavaScript with the default parameters.

你知道什么真的很棒吗? 如果我们能够使用模块而不必每次都给它一个存储库。 我们可以使用默认参数在JavaScript中执行此操作。

具有依赖注入和默认参数 (With Dependency Injection and default parameters)

With this strategy, in addition to the Dependency Injection we’ve seen in the previous approach, the parameter defined in the factory function exported by the users module is now a default parameter: usersRepo = defaultUsersRepo.

通过这种策略,除了我们在以前的方法中看到的依赖注入之外,现在由users模块导出的工厂函数中定义的参数现在是默认参数: usersRepo = defaultUsersRepo

With the default parameter, if we don’t pass an argument, the value of the default parameter is used by the function. Otherwise, the argument’s value is used. This is the same as using the Dependency Injection technique defined in the previous approach.

使用默认参数时,如果不传递参数,则该函数将使用默认参数的值。 否则,将使用参数的值。 这与使用先前方法中定义的依赖注入技术相同。

Now, we have the static dependency again in the users module. However, this static dependency is only to define the value used in the default parameter if no argument is passed to the factory function.

现在,在用户模块中又有了静态依赖项。 但是,如果没有将任何参数传递给工厂函数,则此静态依赖性仅用于定义默认参数中使用的值。

With this approach, we are not obligated to pass the repository in the app module when requiring the users module. Still, we can do it. We can also verify that unit tests can continue to use the mock repository, because we are able to pass it instead of using the default parameter’s value.

通过这种方法,我们不需要在需要用户模块时在app模块中传递存储库。 不过,我们可以做到。 我们还可以验证单元测试可以继续使用模拟存储库,因为我们可以传递它,而不使用默认参数的值。

结论 (Conclusion)

The default parameters are a simple JavaScript feature, yet a powerful one. With them, we can implement better solutions.

默认参数是简单JavaScript功能,但功能强大。 有了它们,我们可以实现更好的解决方案。

Feel free to ask me anything.

有什么事情尽管问我。

更多资源 (More Resources)

GitHub repository with the examples: here.

带有示例的GitHub存储库: 此处

Mattias Petter Johansson has a great Dependency Injection explanation video:

Mattias Petter Johansson有一个很棒的依赖注入说明视频:

If you enjoyed this article, please give me some claps so more people see it. Thank you!

如果您喜欢这篇文章,请给我一些鼓掌,以便更多的人看到。 谢谢!

翻译自: https://www.freecodecamp.org/news/how-to-take-advantage-of-javascripts-default-parameters-for-dependency-injection-98fc423328e1/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值