我定义了一个类类来跟踪将在运行时更新的一些动态数据。我希望我的应用程序中定义的所有路由都可以访问此类的实例:
export default class Manager {
constructor() {
let self = this;
self.table = [];
}
addEntity(obj){
let self = this;
self.table.push(obj);
}
}
让我说我运行我的应用程序并发生一些事件。然后我调用manager.addEntity(...some_event...);
。
self.table
将有一个新元素。我希望能够通过请求路由的URL(可能是GET /api/table/
)来获取路由来访问此信息。不幸的是,我目前无法访问该类的实例。
我应该将对类实例的引用分配给全局变量吗?这是一种反模式,如果可能的话,我想避免这样做。
我的服务器是使用常规推荐代码定义的:
import http from 'http';
import { env, mongo, port, ip, apiRoot } from './config';
import api from './api';
import express from './services/express';
import mongoose from './services/mongoose';
import Manager from './lib/manager.js';
const app = express(apiRoot, api);
const server = http.createServer(app);
mongoose.connect(mongo.uri, { useMongoClient: true });
mongoose.Promise = Promise;
new Manager().initialize(server);
setImmediate(() => {
server.listen(port, ip, () => {
console.log(
'Express server listening on http://%s:%d, in %s mode',
ip,
port,
env,
);
});
});
export default app;
答案 0 :(得分:1)
单例类是否合理是根据具体情况决定的。
如果使用某个类可以提供某些好处,那么这是合理的:
一个类可以多次实例化,而应该存在默认实例
可以延长课程
一个类可以提供语法或功能上的好处(例如,drastic performance optimization for prototype chain in Node.js/V8)
如果有可能需要多次实例化(嵌套应用程序,测试等),它可以是具有默认实例的类。这自然由JS模块提供,包括ES模块:
export class Manager {
constructor() {
this.table = [];
}
addEntity(obj) {
this.table.push(obj);
}
}
export default new Manager();
请注意,如果需要实例化或扩展Manager
,则会导出export default {
table: [],
addEntity(obj) {
this.table.push(obj);
}
};
。
如果不是这种情况,那么可以应用KISS原则,而可以使用普通对象:"
addEntity
KISS原则可以进一步应用;如果将一个对象推送到数组是该类所做的全部,app.set('managed entities', []);
...
app.get('managed entities').push(...);
并非如此。它可以省略,所以我们最终得到一个数组。
在Express.js中,应用程序范围的变量通常存储为application settings,因此可以从应用程序实例存储和检索变量(整个对象或表数组):
managed entities
要求是访问应用程序实例,因此使用MyApp-Swift
设置的代码应驻留在中间件函数中。另一方面,这提供了更大的灵活性。如果需要,可以覆盖该设置。
答案 1 :(得分:0)
编辑:请参阅下面Bergi的评论,了解为什么我发布的答案是个坏主意。
-
导出所有路由导入的该类的实例。可能是这样的(单实例模式):
class Manager {
...
}
export default new Manager();