Организация слоя базы данных Golang внутри пакета - PullRequest
1 голос
/ 19 июня 2019

Я хотел бы услышать совет от гуру Голанга. Представьте, что у меня есть пакет для слоя базы данных со множеством таблиц, для которых я должен определить структуры и функции для них. Например, у меня есть таблица с именем «MyObject», и я определил для нее структуру.

type MyObject struct {
    RecID       int
    Name        string
}

Удобно ли для функций, связанных с этой таблицей / структурой, я определяю получателя так:

func (o MyObject) AllMyObjects() ([]MyObject, error) {
    // retreive all MyObjects by query
}


func (o *MyObject) OneMyObjects() (MyObject, error) {
    // retreive one MyObject by query
}

Таким образом, по мере того, как мой пакет БД будет увеличиваться за счет структур и функций, он будет выглядеть чище и проще для вызова таких методов (хотя я должен определить 1 дополнительную строку):

var myobject MyObject
var myobjects,err = myobject.AllMyObjects()

вместо вызова функций непосредственно на уровне пакета (db - это имя моего пакета)

var myobjects,err = db.AllMyObjects()

Это способ организации кода Go или у вас есть другие советы для этого?

Ответы [ 3 ]

1 голос
/ 20 июня 2019

Мне нравится метод Бена Джонсона, описанный здесь https://medium.com/@benbjohnson/standard-package-layout-7cdbc8391fc1

Идея состоит в том, чтобы поместить ваши доменные объекты в ваш базовый пакет, а затем обернуть базу данных / nosql / redis / любой другой уровень персистентности как сервисы в подпакетах. Когда я делаю это, я сталкиваюсь с такими вещами:

  • myobject.go (определяет структуру MyObbject и интерфейс MyObjectService, имеет такие вещи, как, возможно, «Get, Update»)
  • MySQL /
    • myobject_service.go (реализует MyObjectService для сохранения MySQL)
  • Redis /
    • myobject_service.go (реализация для redis)

это позволяет вам передавать MyObjectService в вашей бизнес-логике, и вам даже не важно, как на самом деле происходит постоянство. Бетонная структура mysql.MyObjectService имеет тенденцию содержать вещи как указатель на соединение с базой данных. Кеш-пакет может хранить вещи в памяти. И т.д.

Другими словами, не основывайте свою структуру рабски на базе данных, не привязываясь к конкретной реализации. Отделите логику бизнес-кода от процесса сохранения и используйте интерфейсы для обеспечения согласованного шаблона доступа к постоянным данным.

1 голос
/ 19 июня 2019

Если вы думаете о том, как это используется, это странный способ организовать ваш код.Методы поведения их типа получателя.Работает ли MyObject по извлечению других MyObject из базы данных?Это не звучит правильно.Это должно быть делом того, что подключается к базе данных.Это могут быть функции пакета или объект, обертывающий соединение с базой данных или сеанс базы данных;каждый из них может быть подходящим подходом в зависимости от вашего приложения, базы данных и потребностей в тестировании (тестировать функции пакета гораздо сложнее, потому что их нельзя смоделировать).

Например, если тип вашей модели - Foo иBar, ваш пакет базы данных может иметь типы FooStore и BarStore, каждый из которых имеет методы для получения одного по идентификатору, получения всего, вставки одного, обновления одного и т. Д. (Независимо от потребностей каждого типа).

Часто важно держать код базы данных отделенным от модели данных, чтобы пакетам, работающим с моделью, не приходилось также импортировать DBAL, что помогает разделить проблемы.

0 голосов
/ 19 июня 2019

Отличный вопрос.Обычно, независимо от того, какой язык используется в проекте, я пытаюсь применить шаблон MVC, в котором метод этой базы данных должен быть отделен от моделей.

enter image description here

Я бы создал еще один файл с именем your_model_controller.go и дал бы ему все обязанности по сохранению

Введение в MVC

...