节点模块作为构造函数

时间:2017-03-16 00:08:32

标签: node.js testing module

我正在开发我的第一个NodeJS项目。当我在书本和互联网上阅读时,我开始以经典的方式构建模块。 随着项目的开始增长,我决定将模块拆分成可重复使用的小块。这导致我在文件的顶部有很多require,有时可能会遇到循环依赖的风险。而且,这种方法并不适合测试,因为我不得不要求所有依赖项进行测试。我问其他开发人员一个更好的方法来解决这个问题,他们中的大多数建议我使用函数构造函数的依赖注入。

假设我有ModuleA和ModuleB, ModuleC需要ModuleA和ModuleB。我不应该将这些模块作为页面的顶部,而应该在构造函数中将它们作为参数传递。 e.g。

module.exports = function ModuleC(moduleA, moduleB) {
 //module implementation here....
 function doSomething() {}
 return {
   doSomething
 }
}

这种方法的问题,一开始看起来不错,就是在应用程序的主入口点我必须要求并实例化所有要传递的模块。

const ModuleA = require("./moduleA");
const ModuleB = require("./moduleB");
const ModuleC = require("./moduleC");

const moduleA = new ModuleA();
const moduleB = new ModuleB();


const moduleC = new ModuleC(moduleA, moduleB);
moduleC.doSomething();

现在只有3个模块,我必须编写7行代码才能使用模块的功能。如果我有20个模块与应用程序的主入口点一起工作将是一场噩梦。

我想这不是最好的方法,即使使用这种方法,测试也不容易。

所以,我要求你建议/解释我实现这个简单任务的最佳方法,我发现,也许比开始探索NodeJS一词更难。感谢。

1 个答案:

答案 0 :(得分:0)

如果将所有代码放在一个文件中,也可以实现代码重用性。创建较小的模块并不是唯一的解决方案。考虑以下代码写在文件allLogic.js(let)中。

var allFunctions = function(){ };
var allFunctionsProto = allFunctions.prototype;

allFunctionsProto.getJSONFile = function(fileName){ 
    var that = this;    //use 'that' instead of 'this'
    //code to fetch json file
};


allFunctionsProto.calculateInterest = function(price){
    var that = this;    //use 'that' instead of 'this'
    //code to calculate interest
};

allFunctionsProto.sendResponse = function(data){
    var that = this;    //use 'that' instead of 'this'
    //code to send response
};

//similary write all of your functions here using "allFunctionsProto.<yourFunctionName>"

module.exports = new allFunctions();

每当我需要获取任何JSON文件时,我都知道获取JSON文件的逻辑已经写在allLogic.js文件中,因此我将需要此模块并使用如下所示。

var allLogic = require('../path-to-allLogic/allLogic.js');
allLogic.getJSON();

这种方法比为每项工作创建大量模块要好得多。当然,如果模块变得更长,你可以创建新的模块,但在这种情况下你需要考虑关注点分离,否则循环依赖会困扰你。

当您在moduleA中使用moduleBmoduleC时,如果您将moduleA,moduleB和moduleC中的所有代码放在单个模块中,我已经指出您可以使用that引用该模块中的函数和所有单独函数,并且在require之后也可以使用这些函数。