gpt4 book ai didi

node.js - 数据库客户端抽象

转载 作者:太空宇宙 更新时间:2023-11-03 23:11:54 25 4
gpt4 key购买 nike

我多次读到,在任何数据库客户端上编写一个抽象层是一个好主意,这样您就可以更改数据库层而不影响代码的任何其他部分。

在我的项目中,我大量使用 BigQuery 和 Firebase - 但客户端库使用起来非常简单,我不确定可以添加什么作为抽象层,例如:

  await bigquery
.dataset(datasetId)
.table(tableId)
.insert(rows);

我可以将其包装在一个函数中,其中包括一些错误处理。

另一个选择是我让这个新客户端与我的域更加耦合,并公开可以保存特定数据集的方法,而不仅仅是采用 rows 对象 - 这似乎是有害的。

Nodejs 应用程序中如何抽象数据库?

最佳答案

最重要的部分是使您的域不依赖于实现细节。数据库是一个实现细节。

因此,将其包装在函数中并为其赋予另一个名称并不重要。重点是让您的域不依赖于此。

你是怎么做到的?

通过定义一个接口(interface)(这是您的抽象)来表示“我需要存储/获取数据,无论背后有什么数据库”。然后,您可以在产品中注入(inject)该接口(interface)的 BigQuery 实现...并且可以轻松地在测试甚至开发模式下注入(inject)内存中实现。

现在,在 JavaScript 中,没有显式接口(interface)。但抽象的想法仍然存在。这只是隐式的。界面将是您实际使用的东西(鸭子打字)。

使用您的具体示例

假设您有:

async function doSomething() {
// Some other domain stuff…

await bigquery
.dataset(datasetId)
.table(tableId)
.insert(rows);
}

这没有多大帮助:

function insertInDb(rows) {
return bigquery
.dataset(datasetId)
.table(tableId)
.insert(rows);
}


async function doSomething() {
// Some other domain stuff…

await insertInDb(rows);
}

但是,这会有所帮助:

function insertInDb(rows) {
return bigquery
.dataset(datasetId)
.table(tableId)
.insert(rows);
}


async function doSomething(insertInDb) {
// Some other domain stuff…

await insertInDb(rows);
}

差异很微妙,但实际的 insertInDb 函数是在运行时注入(inject)的,这会反转依赖关系。

进一步:数据库的存储库抽象

现在,这个概念通常被称为存储库。

如果您花一些时间更好地表达领域概念,您可能会得到如下所示的最终代码:

class ScoreRepositoryBigQuery {
save(newScore) {
// Some logic to convert `newScore` into BigQuery compatible `rows`…

return this.bigquery
.dataset(this.datasetId)
.table(this.tableId)
.insert(rows);
}
}


async function answerQuestion(scoreRepository) {
// Some other domain stuff…

await scoreRepository.save(newScore);
}

使用不同的存储机制(例如 MongoDB、第三方服务、内存实现等)创建新的 ScoreRepository 会很容易。

您只需要实现隐式接口(interface)(例如,它应该有一个异步 save() 方法,该方法接受 newScore 并存储它)。

无需触及代码的其余部分,因为它不关心实际的实现。

所以将是一个有用的抽象层。

关于node.js - 数据库客户端抽象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60174785/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com