我正在Sequelize
中使用node.js
,其想法是使用Singleton
模式。
了解node
与modules caching的工作方式以及一些单例示例
此刻我的文件是:
const DBManager = (function () {
// Instance stores a reference to the Singleton
let instance: any;
let db: string = null;
let user: string;
let password: string;
let host: string;
let sequelize: Sequelize.Sequelize;
function init(bdName: string) {
db = bdName;
user = process.env.MYSQL_DB_USERNAME || 'root';
password = process.env.MYSQL_DB_PASSWORD || 'root';
host = process.env.MYSQL_DB_HOST || 'localhost';
return {
open: () => {
sequelize = new Sequelize(db, user, password, {
host: host,
dialect: 'mysql',
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
},
operatorsAliases: false,
logging: !process.env.HIDE_LOGS
});
},
testConnection: () => {
return sequelize.authenticate();
},
getManagerObject: () => {
return sequelize;
},
close: () => {
sequelize.close();
}
};
}
return {
// Get the Singleton instance if one exists
// or create one if it doesn't
getInstance: (bd?: string) => {
if (!instance) {
instance = init(bd);
}
return instance;
}
};
})();
export default DBManager;
因此,正如预期的那样,当我在项目的任何地方都需要此文件时,引用是相同的,并且可以按预期工作。
我不确定这是否是实现Singleton pattern
的正确方法,或者是否存在已定义并记录在案的方法,因为官方文档对此没有任何说明。
答案 0 :(得分:2)
通常不需要显式的单例实现。 JS模块(尤其是CommonJS和ES模块)在正常情况下仅评估一次,导出的类实例实际上是单例。
也不需要IIFE,因为模块具有自己的作用域。由于init
函数不会被重用,因此也可能不需要它。可以简化为:
export default {
open: ...
testConnection: ...
...
};
这种抽象是不实际的。已经有sequelize
个实例,为其自己的方法创建包装器方法并没有什么用。
由于建立连接后即可使用,因此仅导出连接的承诺是有意义的,类似于this answer中所示的连接。
如果配置(数据库名称)在数据库管理器模块中可用,则最好就地使用它:
// db.js
const dbName = someConfig.db;
const sequelize = new Sequelize(dbName, ...);
export default sequelize.authenticate().then(() => sequelize);
其用法类似于:
import dbConnection from './db';
dbConnection.then(sequelize => { /* all code that depends on the connection */ });
如果可能存在多个连接,或者导入时配置不可用,则将导出工厂功能:
// db.js
export default dbName => {
const sequelize = new Sequelize(dbName, ...);
sequelize.authenticate().then(() => sequelize);
}
单个实例自然由模块处理:
// foo-db.js
import getDbConnection from './db';
export default getFooDbName().then(dbName => getDbConnection(dbName));
并按如下方式使用:
import dbConnection from './foo-db';
dbConnection.then(sequelize => { /* all code that depends on the connection */ });