我使用单独的路由器文件作为主应用程序和身份验证应用程序的模块。我无法获得将变量(数据库客户端)传递到路由器的最佳方法。我不想对其进行硬编码或将其传递给:
module.exports = function(app, db) {
也许这是使用单例寄存器或使用全局数据库变量的最佳方式?
你对设计模式有什么经验?哪种方式最好,为什么?
我使用单独的路由器文件作为主应用程序和身份验证应用程序的模块。我无法获得将变量(数据库客户端)传递到路由器的最佳方法。我不想对其进行硬编码或将其传递给:
module.exports = function(app, db) {
也许这是使用单例寄存器或使用全局数据库变量的最佳方式?
你对设计模式有什么经验?哪种方式最好,为什么?
我发现使用依赖注入来传递东西是最好的风格。它确实看起来像你:
// 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.
这有很多好处:
require("databaseSingleton")
或更糟的地方,global.database
.Routes
,我可以用 fakeapp
和database
params 注入它,只测试Routes
代码本身。server.js
应用程序入口点)。这使您可以在一个地方查看所有内容如何在系统中组合在一起。我见过的对此的更好解释之一是对 Mark Seeman 的采访,他是优秀著作.NET 中的依赖注入的作者。它同样适用于 JavaScript,尤其是 Node.js:require
通常用作经典的服务定位器,而不仅仅是模块系统。
我建议您使用 db 实例和其他需要全局使用的东西(如“单例”)创建一个设置文件。
例如,我的 redis db 客户端有 settings.js:
var redis = require('redis');
exports.redis = redis.createClient(6379, '127.0.0.1');
在其他多个模块中,我将其包括在内:
var settings = require('./settings');
setting.redis.<...>
很多时候包括它我总是有一个数据库连接实例。
如果您使用依赖注入框架,您可以为自己节省所有连接模块的样板代码
这个答案列出了其中一些。我还在这里构建了一个更简单的 DI 框架。
编辑:如果页面发生变化,下面是答案的副本
require
是Node.js 中管理依赖项的方式,当然它是直观和有效的,但它也有其局限性。
我的建议是看一下目前可供 Node.js 使用的一些依赖注入容器,以了解它们的优缺点。他们之中有一些是:
仅举几个。
现在真正的问题是,与简单的require
.
优点:
缺点:
require
绝对感觉像是在偏离 Node 的思维方式。它已完全过时,但您可以global
在脚本中使用:
global.foo = new Foo();
在另一个脚本中:
foo.bar();
您还可以使用已经存在的常量:
Object.foo = new Foo();
和这里 :
Object.foo.bar();