如何解决关于 JavaScript 中继承/架构的建议
为了访问我在mongodb中的集合,我没有使用第三方框架,我直接使用nodejs mongodb包。为此,对于数据库中的每个集合,我创建了一个 model 文件,如下所示:
const Table = "Home";
let driverPromise;
module.exports = function(driver) {
driverPromise = driver;
this.getById = getByIdAsync;
this.update = updateAsync;
this.getByIdAsync = getByIdAsync;
this.updateAsync = updateAsync;
this.deleteAsync = deleteAsync;
this.deleteallAsync = deleteallAsync;
this.findAllAsync = findAllAsync;
this.findOneAsync = findOneAsync;
this.saveAsync = saveAsync;
};
function getByIdAsync(_id) {
return driverPromise
.then(driver => driver.getByIdAsync(Table,_id))
}
function updateAsync(value) {
return driverPromise
.then(driver => driver.updateAsync(Table,value,value._id));
}
function deleteAsync(_id) {
return driverPromise
.then(driver => driver.deleteAsync(Table,_id));
}
function deleteallAsync(criteria) {
return driverPromise
.then(driver => driver.deleteallAsync(Table,criteria));
}
function saveAsync(value) {
return driverPromise
.then(driver => driver.saveAsync(Table,value));
}
function findAllAsync(criteria) {
return driverPromise
.then(driver => driver.findAllAsync(Table,criteria));
}
function findOneAsync(criteria) {
return driverPromise
.then(driver => driver.findOneAsync(Table,criteria));
}
集合的名称,每个文件都不同,在 cont Table
中定义,然后是经典的 CRUD 函数,在所有模型文件中共享。然后导出的是......好吧,我不知道到底是什么,但它有效 o_O
要使用这些文件,我会首先在初始化时创建它的一个实例 cont home = new Home(driver)
,然后在我的应用程序中使用它,例如 const result = await home.findOneAsync({name : 'toto'})
效果很好....
问题是,我对每个集合都这样做,这意味着我有一堆看起来完全相同的文件,唯一的区别是集合的名称!这已经足够了,但如果我想添加一个像“aggregateAsync”这样的方法,我必须更新所有文件:'(当然我仍然需要一些灵活性,因为某些集合有额外的方法,比如 {{1} } 具有 bcryptjs 功能,或 User
,其中我为报告添加了一个特殊的聚合管道....
所以我的问题是,我怎样才能实现一个更好的设计模式,使基本函数(getById、findOneAsync...)以及我可以在哪里创建继承的子类 那些函数,但每个函数都有自己的集合名称,并且可以扩展一些额外的函数?
解决方法
事实上,我想我找到了解决方案。
首先我创建一个像这样的“通用”CollectionModel文件
module.exports = function (Table) {
return function (driver) {
this.driver = driver;
this.getByIdAsync = function (_id) {
return this.driver.then((driver) => driver.getByIdAsync(Table,_id));
};
this.updateAsync = function (value) {
return this.driver.then((driver) =>
driver.updateAsync(Table,value,value._id)
);
};
this.deleteAsync = function deleteAsync(_id) {
return this.driver.then((driver) => driver.deleteAsync(Table,_id));
};
this.deleteAllAsync = function deleteAllAsync(criteria) {
return this.driver.then((driver) =>
driver.deleteAllAsync(Table,criteria)
);
};
this.findAllAsync = function findAllAsync(criteria) {
return this.driver.then((driver) => driver.findAllAsync(Table,criteria));
};
this.findOneAsync = function findOneAsync(criteria) {
return this.driver.then((driver) => driver.findOneAsync(Table,criteria));
};
this.saveAsync = function (value) {
return this.driver.then((driver) => driver.saveAsync(Table,value));
};
this.setAsync = function setAsync(id,values) {
const update = { $set: values };
return this.driver
.then((driver) => driver.partialUpdateAsync(Table,update,id))
.then(() => Promise.resolve(true));
};
};
};
这将以 TableName 作为输入并为我的所有 model.js 文件生成根。因此,对于 Home 集合,没有额外方法的模型文件将如下所示。
const Table = "Home";
const Model = require("../tools/mongo/CollectionModel");
let model = Model(Table);
module.exports = model;
如果模型需要额外的方法,例如 user,我可以像这样添加它们:
const Table = "Users";
const Model = require("../tools/mongo/CollectionModel");
let model = Model(Table);
/***************
* EXTRAS
****************/
const bcrypt = require("bcryptjs");
model.prototype.checkPassword = function (user,password) {
// I can access this.driver her to query my db.
};
/***************
* END OF EXTRAS
****************/
module.exports = model;
这实际上非常棒,并且减少了我的代码行数:)
感谢@Bergi 的想法...
请注意,为了使用驱动程序,我必须调用额外的方法 this.driver 并且要这样做,必须只使用 method.something = ()=>{} 又名委托样式方法。完整的 model.somethig = function() {} 不会改变上下文,因此不会让我访问我的数据库驱动程序。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。