Design patterns 在Node.js中将公共变量传递到单独模块的最佳方式是什么?
我使用单独的路由器文件作为主应用程序和身份验证应用程序的模块。我无法找到将变量(db客户端)传递到路由器的最佳方法。我不想硬编码或通过以下方式传递:Design patterns 在Node.js中将公共变量传递到单独模块的最佳方式是什么?,design-patterns,node.js,Design Patterns,Node.js,我使用单独的路由器文件作为主应用程序和身份验证应用程序的模块。我无法找到将变量(db客户端)传递到路由器的最佳方法。我不想硬编码或通过以下方式传递: module.exports = function(app, db) { 也许使用单例寄存器或使用全局db变量是最好的方法 你对设计模式有什么经验?哪种方式是最好的,为什么?我建议您使用db实例和其他需要全局使用的东西(如“singleton”)创建一个设置文件 例如,我的redis db客户端有settings.js: var redis =
module.exports = function(app, db) {
也许使用单例寄存器或使用全局db变量是最好的方法
你对设计模式有什么经验?哪种方式是最好的,为什么?我建议您使用db实例和其他需要全局使用的东西(如“singleton”)创建一个设置文件 例如,我的redis db客户端有settings.js:
var redis = require('redis');
exports.redis = redis.createClient(6379, '127.0.0.1');
在其他多个模块中,我包括:
var settings = require('./settings');
setting.redis.<...>
var设置=需要('./settings');
设置.redis。
很多时候,包括它,我总是有一个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.
这有很多好处:
-
<> LI>强制您将系统划分为具有明显依赖关系的组件,而不是将文件中的依赖项隐藏在文件的中间位置,它们调用“代码>”(“DabaseStudioLeon”)或更糟,<代码> Global。数据库< /代码> .
- 它使单元测试非常容易:如果我想单独测试
,我可以向它注入伪路由
和app
参数,并只测试数据库
代码本身路由
- 它将所有对象图连接放在一个地方,即合成根(在本例中是
,应用程序入口点)。这为您提供了一个单独的位置来查看系统中的所有内容是如何组合在一起的server.js
我看到的一个更好的解释是,他是一本优秀的书《在.NET中依赖注入》的作者。它同样适用于JavaScript,尤其是Node.js:
require
通常被用作经典的服务定位器,而不仅仅是模块系统。它完全过时了,但您可以使用全局
在脚本中:
global.foo = new Foo();
在另一个脚本中:
foo.bar();
您还可以使用已经存在的常量:
Object.foo = new Foo();
在这里:
Object.foo.bar();
如果使用依赖项注入框架,您可以保存连接模块的所有样板代码 列出了其中的一些。我还建了一个 编辑:下面是一份副本,以备页面更改时使用
require
是Node.js中管理依赖关系的方法,当然它直观有效,但也有其局限性
我的建议是看一下Node.js目前可用的一些依赖注入容器,了解它们的优缺点。其中包括:
require
相比,Node.js DI容器能实现什么
优点:
- 更好的可测试性:模块接受它们的依赖项作为输入
- 控制反转:决定如何在不接触应用程序主代码的情况下连接模块
- 用于解析模块的可定制算法:依赖项具有“虚拟”标识符,通常它们不绑定到文件系统上的路径
- 更好的扩展性:由IoC和“虚拟”标识符启用
- 其他花哨的东西:
- 异步初始化
- 模块生命周期管理
- DI容器本身的可扩展性
- 能够轻松实现更高级别的抽象(例如AOP)
- 与Node.js的“体验”不同:不使用
肯定会让人觉得你偏离了Node的思维方式require
- 依赖项与其实现之间的关系并不总是明确的。依赖关系可能在运行时得到解决,并受到各种参数的影响。代码变得更难理解和调试
- 启动时间较慢
- 成熟度(目前):目前没有一种解决方案真正流行,因此没有太多教程,没有生态系统,没有经过战斗测试
- 一些DI容器不能很好地与模块绑定器(如Browserify和Webpack)配合使用