Самая важная часть - , чтобы ваш домен не зависел от деталей реализации . База данных - это деталь реализации.
Так что дело не в том, чтобы обернуть это в функцию, чтобы дать ей другое имя. Смысл в том, чтобы ваш домен не зависел от этого.
Как вы это делаете?
Определяя интерфейс (это ваша абстракция), который говорит: «Мне нужно сохранить / получить данные, какая бы база данных ни стояла ". Затем вы внедряете реализацию BigQuery этого интерфейса в prod… и внедрить реализацию в памяти в тестах или даже в режиме разработки просто.
Теперь, в JavaScript, явного интерфейса нет. Но идея абстракции еще существует. Это просто неявно. Интерфейс будет тем, что вы на самом деле используете (типизированный ввод).
Используя ваш конкретный пример
Допустим, у вас есть:
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
вводится во время выполнения, что инвертирует зависимость.
Идем дальше: абстракция репозитория над базами данных
Теперь эту концепцию обычно называют репозиторием.
Если вы потратите некоторое время на то, чтобы лучше выразить концепцию предметной области, у вас может быть конечный код, который выглядит следующим образом:
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);
}
Было бы легко создать новый ScoreRepository
с использованием другого хранилища. механизм (например, MongoDB, сторонний сервис, реализация в памяти и т. д. c.).
Вам просто нужно реализовать неявный интерфейс (например, он должен иметь асинхронный c save()
метод, который берет newScore
и сохраняет его).
Не нужно трогать остальную часть кода, поскольку его не волнует фактическая реализация.
Так что this будет полезным уровнем абстракции.