
Александр
27.04.2018
07:15:14
"взять данные и положить в базу"

Dmitri
27.04.2018
07:15:19
логика - ничто, архитектура - всё

Sergey
27.04.2018
07:15:31

Dmitri
27.04.2018
07:15:44
просто может возникнуть непонятное желание впоследствии эту логику впихнуть

Google

Александр
27.04.2018
07:16:00
тоесть можно сделать два пакета аля
dbAdapter
и
db где
- UserModel.go
- AnyModel.go

Dmitri
27.04.2018
07:16:20
и вот на этом этапе тебе будет больно, если сейчас ты не разделишь модель и бд-лейер

Александр
27.04.2018
07:17:08
в dbAdapter тем не менее получается есть пару функций которые принимают на вход модель

Dmitri
27.04.2018
07:17:10
кстати, по опыту, тупо описание структур, как правило, удобнее в отдельном модуле хранить

Александр
27.04.2018
07:17:14
аля SaveUser()

Dmitri
27.04.2018
07:17:53
смотри, чо скажу:
1. отдельный пекедж с описанием структур
2. пекедж-адаптер для БД, который импортирует пекедж №1.
3. пекедж с бизнес-логикой, который импортирует пекедж №1.
и все это потому, что циклические зависимости нельзя
и всё у тебя будет хорошо, я в тебя верю)

Александр
27.04.2018
07:20:01
так
а бизнес логика же должна взаимодействовать с адаптером бд как то?

Google

Dmitri
27.04.2018
07:20:29
короче, все то, что может в качестве структурной единицы куда-то импортиться - в отдельный пекедж
а если должна, то, вероятно, через интерфейсы
это если ты хочешь именно слои друг от друга отпилить
т.е. если ты не хочешь, чтобы бизнес-логика зависела от слоя БД, то ты должен импортировать интерфейсы

Александр
27.04.2018
07:22:46
Отдельные структуры:
- Яблоки
- Апельсины
Адаптер
- Поискать яблоки на дереве
- Поискать апельсины на дереве
- Новый апельсин
- Новое яблоко
- Сохранить апельсин
- Сохранить яблоко
Бизнес логика
- Если яблоки зеленые то не сажаем на дерево
что-то в этом духе?

Dmitri
27.04.2018
07:23:28
собственно, у тебя два пути: DAO либо репозиторий
собственно, они похожи, причем сильно, вплоть до взаимопроникновения, хотя есть нюансы, доступные избранным (не всегда и не во всем мне)
итого у тебя есть пакадж models
внутрях:
type Apple struct
type Orange struct
на этом твои модели, фактически, заканчиваются
туда же ты можешь вкрутить обвязку по яблокам/апельсинам, которая зависит конкретно от полученного яблока/апельсина и не требует записи в базу
типа func (a *Apple) Color() string { return a.Color }
а дальше у тебя отдельный пакадж, допустим, dao
там методы соединения с базой и т.д. и т.п. - вся эта мишура
и плюсом, условно, тупой CRUD

Александр
27.04.2018
07:28:36
но DAO пакет получается должны тоже импортировать модели

Dmitri
27.04.2018
07:28:44
т.е.
func (dao *DAO) CreateApple() (*Apple, error)
func (dao *DAO) ReadApple(appleID int64) (*Apple, error)
func (dao *DAO) UpdateApple(apple *Apple) error
func (dao *DAO) DeleteApple(alleID int64) error

Александр
27.04.2018
07:28:54
и более того, знать про них

Google

Dmitri
27.04.2018
07:29:00
вот dao и импортирует models
весь смысл именно в том, что models твой - основополагающая сущность

Kirill
27.04.2018
07:29:22
чем в итоге dao от. репозитория отличается?

Dmitri
27.04.2018
07:29:34
от него пляшет вся остальная бизнес-логика

Александр
27.04.2018
07:29:35
DAO будет неконтролируемо расти тогда
пухнуть от каждой модели

Dmitri
27.04.2018
07:29:55
но близко к правде
там дальше уже финты ушами на тему:
1. универсальные CRUD-методы
т.е. Create(item interface{}) error

Dmitri
27.04.2018
07:31:08
и в таком роде

Александр
27.04.2018
07:31:13
а вот это не надо! :)
это потянет рефлексию

Dmitri
27.04.2018
07:31:27
либо раздельные дао на каждый тип item'а
т.е. type AppleDAO struct, type OrangeDAO struct
весь смысл этой хрени в том, что сама структура Apple|Orange тебе может понадобиться везде, а dao - только в тех местах, куда надо сохранить

Александр
27.04.2018
07:33:17
я бы тогда AppleDAO положил бы в пакет рядом Apple

Dmitri
27.04.2018
07:34:13
вероятна еще такая штука:
type AppleDAO struct {
item *Apple
}
func NewAppleDAO() *AppleDAO, err {}
func (a *AppleDAO) GetApple() *Apple { return a.item }

Google

Dmitri
27.04.2018
07:34:24
в одном пакете их класть не надо
в соседний - без вопросов

Александр
27.04.2018
07:35:32
по поводу дао выше - а как же мульти яблоки? поиск всякий

Dmitri
27.04.2018
07:37:16
просто, допустим, если ты потом будешь писать тупенький декоратор вида
package colordecorator
improt ".../models"
func RuColorOfApple(apple *models.Apple) string {
switch apple.Color {
case "Red":
return "Красное"
}
return "Непонятный какой-то цвет"
}
ты в зависимостях тупого декоратора за собой БД притянешь
т.е. описание структуры/модели - отдельный пакадж, работа с БД - отдельный

Александр
27.04.2018
07:38:11
не логично ли было этот декоратор положить в модели тогда

Dmitri
27.04.2018
07:40:35
1. откуда тяга класть все в модель
2. а куда класть декоратор вида
func RuColor(item FruitColored) string {} при условии, что type FruitColored interface { Color() string }?
ты, конечно, на входе сэкономишь на количестве пакаджей, но на выходе такого геморроя можешь хлебнуть с композицией
собственно, если у тебя что-то на пару структур и 3 метода работы с базой, при этом оно "разовое" и "дальше мы ничего с этим делать не будем" - нивапрос, сложи все в кучу, и не заморачивайся. Работать оно будет, да и на таких случаях это действительно ПРАВИЛЬНАЯ архитектура.

Admin
ERROR: S client not available

Dmitri
27.04.2018
07:42:59
пилить 200 строчек кода на 4 пакаджа - это таки перебор

Александр
27.04.2018
07:43:10
ну ясен хрен что 200 перебор
а по поводу дао, как с коннектом бд быть там?

Dmitri
27.04.2018
07:43:26
но если ты планируешь именно что-то "наращивать" сверху - то тебе придется это делать

Александр
27.04.2018
07:43:58
прокинуть "чистый" коннект в хедлер и потом кормить им дао в фабрику или же как то заморочиться

Dmitri
27.04.2018
07:44:07
собственно, можешь даже синглтон заюзать для БД

Александр
27.04.2018
07:44:40
а потом в контроллер получается NewAppleDAO(c.DBConn)

Dmitri
27.04.2018
07:44:50
просто sql.DB - это пулл коннектов

Google

Dmitri
27.04.2018
07:44:59

Александр
27.04.2018
07:45:01
у меня не совсем реляционная бд там...
но это подробности
ну да
еще есть нюансик там
а дао привязан к реализации конкретной бд?
если мы сменим Mysql на Postgre (условно), менять придется все дао + вызовы контролера
ладно в любом случаи спасибо за консультацию

Dmitri
27.04.2018
07:51:15
ты ПОД дао можешь подложить интерфейс с вызовами к БД
а потом реализовывать интерфейс уже в конкретных модулях для каждой БД свой

Александр
27.04.2018
07:52:48
да я уже тут нашел такое вот - https://github.com/gustavocd/dao-pattern-in-go

Dmitri
27.04.2018
07:52:52
собственно, по поводу "гибкости" и "мультияблок", если честно, Go не лучший выбор
гибкость и мультияблоки, а также особо ветвистая бизнес-логика + классические паттерны и мощная система типов - это немного НЕ про Go, это скорее в сторону Java или C#
в гоше дженериков нет

Александр
27.04.2018
07:54:23
когда я говорил про мультияблоки, я имел введу возможность возвратить не 1 яблоко, а несколько
про слайс яблок

Dmitri
27.04.2018
07:54:46
ну, фактически, для гоши, у тебя 2 варианта, опять же

Александр
27.04.2018
07:55:09
я как понял это можно запулить в яблочные ДАО метод search и там вернуть []*Apple

Dmitri
27.04.2018
07:55:24
либо Read(someParams *requestParams) []*Apple {}
и это для всех
просто когда ты выбираешь 1 яблоко, у тебя будет возвращаться слайс из 1 яблока
либо 2 метода

Александр
27.04.2018
07:56:02
это да