在使用依赖注入时,如何避免使用类型检查逻辑填充我的JavaScript代码?

时间:2021-03-15 08:40:09

I'm trying to employ SOLID principles learnt from strongly-typed languages in a Node.js application, and implement dependency injection through the constructor in my modules.

我正在尝试在Node.js应用程序中使用从强类型语言中学习的SOLID原则,并通过我的模块中的构造函数实现依赖注入。

Without a compiler to help me, I've found myself impulsively writing type-checking and null-reference checking logic to make sure dependencies of the correct type are being passed in.

没有编译器来帮助我,我发现自己冲动地编写了类型检查和空引用检查逻辑,以确保传递正确类型的依赖关系。

var _ = require('lodash');

var ExampleModule = function(dependencies) {
    var app, express, http;

    if(_.isUndefined(dependencies) || typeof dependencies !== 'object') {
        throw new ReferenceError('No dependencies object passed to the constructor. Actually passed: ' + typeof dependencies);
    }

    if(_.isUndefined(dependencies.express)) {
        throw new ReferenceError('The express module must be passed as the \'express\' property in the constructor.');
    } else {
        express = dependencies.express;
    }
    // Tempted to add a type check for dependencies.express here

    if(_.isUndefined(dependencies.http)) {
        throw new ReferenceError('The node http module must be passed as the \'http\' property in the constructor.'); 
    } else {
       http = dependencies.http; 
    }
    // Tempted to add a type check for dependencies.http here

};

module.exports = ExampleModule;

This feels fundamentally wrong for two reasons

出于两个原因,这种根本错误

  • Constructors filled with many conditional statements; likely to increase in size as more dependencies are needed.
  • 构造函数充满了许多条件语句;随着需要更多依赖性,可能会增加大小。

  • Many extra unit tests are written to check the type-checks and null-reference checks are working
  • 编写了许多额外的单元测试来检查类型检查和空引用检查是否正常

I don't want to spend half my time maintaining type-checking logic, but I also don't want to spend half my time debugging errors when the wrong type of a dependency is passed in.

我不想花一半时间来维护类型检查逻辑,但是当传入错误类型的依赖项时,我也不想花一半时间来调试错误。

What design pattern am I missing that would solve this problem?

我错过了哪种设计模式可以解决这个问题?

2 个解决方案

#1


2  

small, but important clarification: the SOLID "D" is not dependency injection. it is dependency inversion.

小而重要的澄清:SOLID“D”不是依赖注入。它是依赖倒置。

for a better understanding of SOLID as it pertains to dynamically typed languages, watch this presentation from Jim Weirich: http://confreaks.tv/videos/rubyconf2009-solid-ruby

为了更好地理解与动态类型语言相关的SOLID,请观看Jim Weirich的演示文稿:http://confreaks.tv/videos/rubyconf2009-solid-ruby

it's about Ruby, but all the principles are the same when applied to JavaScript.

它是关于Ruby的,但是当应用于JavaScript时,所有原则都是相同的。

there's also my own SOLID JavaScript presentation I did a few years ago: https://sub.watchmecode.net/episode/solid-javascript-presentation/

几年前我也做了我自己的SOLID JavaScript演示文稿:https://sub.watchmecode.net/episode/solid-javascript-presentation/

...

your own answer talks about require as dependency injection, but this isn't correct.

你自己的回答是关于require作为依赖注入,但这是不正确的。

the require call is a module loader, not a dependency manager. the difference is subtle, but important.

require调用是模块加载器,而不是依赖项管理器。差异很微妙,但很重要。

the call to require only loads code from another file. it does not supply the dependency to your other code. you have to either call the code w/ the loaded module, or use another tool such as wire.js to supply the dependency for you.

对require的调用只加载来自另一个文件的代码。它不会为您的其他代码提供依赖项。您必须使用已加载模块调用代码,或使用其他工具(如wire.js)为您提供依赖项。

...

regarding your dependency injection question: "it depends" is the only viable answer.

关于你的依赖注入问题:“它取决于”是唯一可行的答案。

i rarely use type checking like this, when dealing with the internals of my applications.

在处理我的应用程序的内部时,我很少使用这样的类型检查。

however, if you're building an API that is called from third parties, it is often necessary to do what you have done, to make sure the API is called correctly.

但是,如果您正在构建从第三方调用的API,则通常需要执行您已完成的操作,以确保正确调用API。

#2


0  

Consider using typescript or flow. This will allow typing checking like most strongly typed languages.

考虑使用打字稿或流程。这将允许像大多数强类型语言一样进行类型检查。

function typedCheckFunction(x: string): string{
    return x
}

typedCheckFunction(5) // would error at compile time

I prefer typescript because of the support for atom, but they are mostly the same.

我更喜欢打字稿,因为支持原子,但它们大多是相同的。

#1


2  

small, but important clarification: the SOLID "D" is not dependency injection. it is dependency inversion.

小而重要的澄清:SOLID“D”不是依赖注入。它是依赖倒置。

for a better understanding of SOLID as it pertains to dynamically typed languages, watch this presentation from Jim Weirich: http://confreaks.tv/videos/rubyconf2009-solid-ruby

为了更好地理解与动态类型语言相关的SOLID,请观看Jim Weirich的演示文稿:http://confreaks.tv/videos/rubyconf2009-solid-ruby

it's about Ruby, but all the principles are the same when applied to JavaScript.

它是关于Ruby的,但是当应用于JavaScript时,所有原则都是相同的。

there's also my own SOLID JavaScript presentation I did a few years ago: https://sub.watchmecode.net/episode/solid-javascript-presentation/

几年前我也做了我自己的SOLID JavaScript演示文稿:https://sub.watchmecode.net/episode/solid-javascript-presentation/

...

your own answer talks about require as dependency injection, but this isn't correct.

你自己的回答是关于require作为依赖注入,但这是不正确的。

the require call is a module loader, not a dependency manager. the difference is subtle, but important.

require调用是模块加载器,而不是依赖项管理器。差异很微妙,但很重要。

the call to require only loads code from another file. it does not supply the dependency to your other code. you have to either call the code w/ the loaded module, or use another tool such as wire.js to supply the dependency for you.

对require的调用只加载来自另一个文件的代码。它不会为您的其他代码提供依赖项。您必须使用已加载模块调用代码,或使用其他工具(如wire.js)为您提供依赖项。

...

regarding your dependency injection question: "it depends" is the only viable answer.

关于你的依赖注入问题:“它取决于”是唯一可行的答案。

i rarely use type checking like this, when dealing with the internals of my applications.

在处理我的应用程序的内部时,我很少使用这样的类型检查。

however, if you're building an API that is called from third parties, it is often necessary to do what you have done, to make sure the API is called correctly.

但是,如果您正在构建从第三方调用的API,则通常需要执行您已完成的操作,以确保正确调用API。

#2


0  

Consider using typescript or flow. This will allow typing checking like most strongly typed languages.

考虑使用打字稿或流程。这将允许像大多数强类型语言一样进行类型检查。

function typedCheckFunction(x: string): string{
    return x
}

typedCheckFunction(5) // would error at compile time

I prefer typescript because of the support for atom, but they are mostly the same.

我更喜欢打字稿,因为支持原子,但它们大多是相同的。