Golang - организация кода с помощью структур, переменных и интерфейсов

У меня есть кодовый где один файл содержит довольно много Structs, Interfaces и Variables в том же файл функции, и я не уверен, что если мне нужно отделить это в отдельные файлы с добавлением файла. Так, например, accounts.go будет accounts_struct.go и accounts_interface.go со структурой и интерфейсом соответственно.

Что было бы хорошим подходом для файловой организации, если у вас есть растущая база кода для структур, переменных и интерфейсов?

Ответ 1

Хорошей моделью для проверки является исходный код самого Go: http://golang.org/src/pkg/

Вы увидите, что этот подход (разделение на основе таких элементов языка, как struct, interface,...) никогда не используется.

Все файлы основаны на функциях, и лучше всего использовать принцип принципа близости, где вы можете найти в том же файле определение того, что вы используете.
Как правило, эти функции группируются в один файл для каждого пакета, за исключением больших, где один пакет состоит из множества файлов (net, net/http)

Если вы хотите что-то отделить, отделите источник (xxx.go) от тестов/тестов (xxx_test.go)


Томас Джей Раш добавляет в комментарии

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


Дейв Чейни предлагает интересную перспективу в "Absolute Unit (Test) @LondonGophers" (март 2019 г.)

Вам следует шире взглянуть на тестируемое "устройство".
Единицы - это не каждая внутренняя функция, которую вы пишете, а целый пакет. В частности, публичный API пакета.

Хорошая идея - организовать ваши файлы, чтобы облегчить тестирование их публичного API.
В этом отношении accounts_struct_test.go не имеет особого смысла.


См. также "Как организовать пакеты в Go", автор Бартломей Климчак

Иногда требуется несколько обработчиков или репозиториев.
Например, некоторая информация может быть сохранена в базе данных, а затем отправлена через событие в другую часть вашей платформы. Хранить только один репозиторий с помощью метода, подобного saveToDb(), не очень удобно.
Все подобные элементы разделены по функциональности: repository_order.go или service_user.go.
Если существует более 3 типов объектов, они перемещаются в отдельную подпапку.

Ответ 2

Вот моя ментальная модель для разработки пакета.

а. Пакет должен охватывать одну идею или концепцию. http - это концепция, http-клиент или http-сообщение.

б. Файл в пакете должен включать в себя набор связанных типов, хорошим правилом является то, что если два файла имеют один и тот же набор импорта, объедините их. Используя предыдущий пример, http/client.go, http/server.go - хороший уровень детализации

с. Не делайте ни одного файла для каждого типа, а не идиоматического Go.