首先,我需要道歉,因为其中将包含很多代码,这将使这个问题肿。但是我认为这将有助于更好地理解我的问题。
假设我给定了MainModule
:
'use strict';
/**
* Loads Module from given name.
* @class {LoadModules}
*/
class LoadModules {
constructor(moduleName) {
// define Modulename.
this.moduleName = moduleName;
}
/**
* Initialize module.
* @method init
* @return {void} [nothing]
*/
init() {
// Path Module.
const path = require('path');
// Require Module from given Name.
let ModuleToLoad = require(path.join(__dirname, 'Modules', this.moduleName, this.moduleName + '.js'));
// Instatiate Module.
ModuleToLoad = new ModuleToLoad();
// Start module.
ModuleToLoad.init();
}
}
另一个可以加载到
MainModule
中的模块:/**
* This is a Module which can be loaded by the MainModule.
* @class {ModuleToBeLoaded}
*/
module.exports = class ModuleToBeLoaded {
constructor() {
/**
* Empty
*/
}
/**
* Initialize newly loaded Module.
* @method init
* @return {void} [nothing]
*/
init() {
console.log('module Loaded');
}
};
如您所见,它用于动态加载模块,效果很好。
我的问题是,动态加载其他模块的
MainModule
无法在模块之间共享自己的全局作用域,或者至少我不知道该怎么做。我很清楚,这很复杂,因为我的MainModule
和ModuleToBeLoaded
在不同的文件中。例如,我在
LoggerClass
的全局范围内有一个MainModule
:// This is in the global scope.
const LoggerClass = new Logger();
/**
* LoadModule class stuff comes after this.
*/
我希望所有模块都像访问自己的全局范围一样访问LoggerClass,而不必在每个模块中一次又一次地定义它。例如,我将
console.log
类中的ModuleToBeLoaded
更改为: /**
* Initialize newly loaded Module.
* @method init
* @return {void} [nothing]
*/
init() {
LoggerClass.log('module Loaded');
}
因此,基本上我在
MainModule
中定义了Globals,我想在ModuleToBeLoaded
的代码中访问这些Globals。可能的解决方案是更改constructor
中的ModuleToBeLaoded
。像这样: constructor(LoggerClass) {
// Here I can set LoggerClass internally.
this.LoggerClass = LoggerClass;
}
/**
* Initialize newly loaded Module.
* @method init
* @return {void} [nothing]
*/
init() {
this.LoggerClass.log('module Loaded');
}
这可以让我实例化此类:
// Instatiate Module.
ModuleToLoad = new ModuleToLoad(LoggerClass);
这是正确的方法,还是更可取的是有其他解决方案?
我要实现的是ES6中的已知模式
singelton pattern
。有关更多信息,请参见以下Wikipage:https://en.wikipedia.org/wiki/Singleton_pattern
旁注:我处于
NodeJS 7.10.0
环境中,没有任何第三方库。问候,
巨人神
最佳答案
LoggerClass.js,这就是您使单例(总是相同实例)的方式
let instance;
module.exports = function () {
if (!instance) {
instance = new LoggerClass();
}
return instance;
}
class LoggerClass {
constructor() {
this.instanceData = Date.now();
}
log() {
console.log(`logging secret instance: ${this.instanceData}`);
}
}
LoadModules.js
const getLoggerClass = require('./LoggerClass');
module.exports = class LoadModules {
constructor(moduleName) {
this.moduleName = moduleName;
}
init() {
const path = require('path');
// changed the require statement, to make it simpler
let ModuleToLoad = require(path.join(__dirname, this.moduleName + '.js'));
ModuleToLoad = new ModuleToLoad(getLoggerClass());
ModuleToLoad.init();
}
}
ModuleToLoad.js
module.exports = class ModuleToBeLoaded {
constructor(logger) {
this.logger = logger;
}
init() {
console.log('ModuleToBeLoaded module Loaded');
this.logger.log();
}
};
ModuleToLoad2.js
module.exports = class ModuleToBeLoaded {
constructor(logger) {
this.logger = logger;
}
init() {
console.log('ModuleToBeLoaded2 module Loaded');
this.logger.log();
}
};
演示版
> node
> const LoadModules = require('./LoadModules');
> var load = new LoadModules('ModuleToLoad');
> var load2 = new LoadModules('ModuleToLoad2');
> load.init();
ModuleToBeLoaded module Loaded
logging secret instance: 1495528699144
> load2.init();
ModuleToBeLoaded2 module Loaded
logging secret instance: 1495528699144
如您所见,根据LoggerClass的
this.instanceData
,实例是相同的删除了注释以使代码最少