将公共变量传递到Node.js中的单独模块的最佳方法是什么?

Ser*_*erg 59 design-patterns node.js

我使用单独的路由器文件作为主应用和auth app的模块.我无法获得将变量(db client)传递到路由器的最佳方法.我不想硬编码或传递它:

module.exports = function(app, db) {
Run Code Online (Sandbox Code Playgroud)

也许这是使用单例寄存器或使用全局db变量的最佳方法?

您对设计模式的体验是什么?哪种方式最好,为什么?

Dom*_*nic 109

我发现使用依赖注入来传递信息是最好的风格.它确实看起来像你有:

// App.js
module.exports = function App() {
};

// Database.js
module.exports = function Database(configuration) {
};

// Routes.js
module.exports = function Routes(app, database) {
};

// server.js: composition root
var App = require("./App");
var Database = require("./Database");
var Routes = require("./Routes");
var dbConfig = require("./dbconfig.json");

var app = new App();
var database = new Database(dbConfig);
var routes = new Routes(app, database);

// Use routes.
Run Code Online (Sandbox Code Playgroud)

这有很多好处:

  • 它会强制您将系统分离为具有明确依赖关系的组件,而不是将依赖关系隐藏在文件中间的某个位置,require("databaseSingleton")或者更糟global.database.
  • 它使得单元测试变得非常简单:如果我想要单独测试Routes,我可以用假appdatabaseparams 注入它并仅测试Routes代码本身.
  • 它将所有对象图连接放在一个位置,即组合根(在本例中为server.jsapp入口点).这为您提供了一个单独的位置,可以查看系统中所有内容是如何组合在一起的.

我见过的一个更好的解释就是采访了Mark Seeman,他是优秀的.NET依赖注入书的作者.它同样适用于JavaScript,尤其适用于Node.js:require通常用作经典服务定位器,而不仅仅是模块系统.

  • 为了保持整个应用程序的单例,最好做功能App(){...} module.exports = new App();? 如果你这样做,你只是缓存新的App()而不是函数,所以你可以确保require()缓存将使你的obj成为整个应用程序的单例.请参阅:http://bites.goodeggs.com/posts/export-this/#singleton (4认同)
  • @ alph486与依赖注入相反,我不推荐它.单身人士通常都是反模式. (2认同)