170 похожих чатов

Ну и? Мокающий пакет те же ошибки возвращает, на то

он и мокающий

44 ответов

27 просмотров
Alexander- Автор вопроса

Там же, где живет оригинальный GetUser

Alexander- Автор вопроса

Положите туда же, где лежит объявленный интерфейс с этим методом

Alexander
Положите туда же, где лежит объявленный интерфейс ...

бац, а он лежит на слое логики, потому интерфейс на месте использования рекурсивный импорт

|- user |- errors.go <- вот здесь например |- user.go |- db |- mongo |- sql |- mock

Бизнес-модель (Структуры, интерфейсы, реализации сервисов)

Anton Kucherov
Бизнес-модель (Структуры, интерфейсы, реализации с...

ну это вопрос организации папок в проекте, а если у человека организована как: |- handlers |- user |- role |- service |- user |- role |- storage |- user |- role тогда где ошибки?

Anton Kucherov
|- user |- errors.go <- вот здесь например ...

и тут ещв вопрос: в errors.go там ошибки и стораджа и сервисов? или 1 набор ошибок?

Artur Karapetov
ну это вопрос организации папок в проекте, а если ...

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

Anton Kucherov
Тогда надо пересмотреть подход к организации кода....

почти все языки с вами поспорят, ну кроме golang и python

Artur Karapetov
почти все языки с вами поспорят, ну кроме golang и...

Нет. не поспорят. Со мной поспорят разве что Framework Driven Developers

Anton Kucherov
Нет. не поспорят. Со мной поспорят разве что Frame...

а кстати, а клиентов куда девать? клиенты к Consul/zipkin/microservice ?

Artur Karapetov
и тут ещв вопрос: в errors.go там ошибки и сторадж...

а у вас в сторадже может быть ошибка, кроме паники? (ну, или обертки над ней)

serg
перехваченная паника

в golang можно перехватывать паники?

Artur Karapetov
а кстати, а клиентов куда девать? клиенты к Consul...

Куда хотите. Главное чтобы бизнес-код их напрямую не вызывал и ничего о них не знал.

Artur Karapetov
и тут ещв вопрос: в errors.go там ошибки и сторадж...

Там ошибки бизнеса. И эти ошибки могут использоваться в любом инфраструктурном слое ниже.

Alexander
🙂

почитал про recover, выглядит интересно, надо попробовать

Не будет циклического импорта. Потому что пакет user не использует пакеты /db/*.

Alexander- Автор вопроса
Anton Kucherov
Там ошибки бизнеса. И эти ошибки могут использоват...

мысль интересная. то есть сделать 5 общих бизнесовых ошибок, во всех слоях просто выбрасывать fmt.Errorf(), кроме последнего, а в последнем бизнес слое, заворачивать ошибку в бизнесовую и ее уже анализировать в хендлере. но тут встает вопрос, как отличить ошибку storage, когда запрос не смог выполниться и когда просто не нашлось ничего?

Artur Karapetov
мысль интересная. то есть сделать 5 общих бизнесо...

|- user |- user.go <- Тут структуры для функционала работы с ползователями. |- errors.go <- Тут ошибки которые может вернуть сервис / абстрактное хранилище / и т.п. |- service.go <- Тут реализация сервиса, который использует интерфейс хранилища. И которым при работе с пользователями будут пользоваться хэндлеры. |- storage.go <- Тут интерфейс хранилища, который используется сервисом. |- db <- Вот эти ребята реализуют интерфейс который описан в storage.go и возвращают структуры и ошибки которые описаны в user.go и errors.go. |- sql | - mock

На этот вопрос нет однозначного ответа. Тут все зависит от фич и от юзкейсов. Это другого уровня вопрос. Поэтому обычно принято начинать с одного пакета в котором хранится вся бизнес-логика (в такой схеме все сущности и сервисы могут лежать в пакете internal например), а уже потом этот пакет дербанить на ограниченные контексты (user/group/etc.) исходя из приобретенных знаний о бизнес-домене. Иначе будет всегда одно и то же. Мы сперва разбили пакеты, потом они почему то должны использовать друг друга и у нас появляются циклические импорты. Потому что оказалось что 2 сущности тесно связаны между собой в рамках одного ограниченного контекста.

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

Anton Kucherov
На этот вопрос нет однозначного ответа. Тут все за...

я думаю Roman спрашивает про слой что-то типа Policy, когда в нем используется UserService и RoleService и OrderService

И да, на самом деле не обязательно использовать одни и те же структуры по всему коду. Код можно дублировать. Если приложение большое, сущностей User может быть несколько в разных пакетах. И эти сущности в каждом пакете будут обозначать немного разные вещи с разными юзкейсами. Существует заблуждение, что условный type User struct уровня бизнес-логики в приложении должен быть один и его потом надо таскать везде где он нужен. Это не так.

Artur Karapetov
ну нет, дублировать код не надо

Вы возводите DRY в абсолют (Т.е. превращаете его в Карго-культ). Когда сущности находятся в разных ограниченных контекстах - дублирование кода сократит вам уйму времени и нервов. Впрочем дело ваше.

Anton Kucherov
Вы возводите DRY в абсолют (Т.е. превращаете его в...

не возвожу, ну по крайней мере пока что не замечаю что возвожу

скажут что надо быть дисциплинированным и писать тесты

Сама необходимость дублирования обычно продиктована ситуациями когда в одном юзкейсе должна (бизнесово) меняться сущность, а во втором нет. 🙂 Т.е. пришел бизнес и сказал:"_ Вот в этой фиче надо вот это поменять." А вы такие: "- Бляяяяяя... А мы не можем, у нас все во всех местах поменяется. Простите." А бизнес такой: "- Погодите, а почему так, у нас же безнесово вещи никак не связаны. Это должно быть просто, почему нет?" А вы такие: "Соррян, у нас DRY"

Artur Karapetov
плохой дизайн

Поэтому существуют ситуации в которых сущности можно дублировать, чтобы получился "Хороший дизайн" (точнее более гибкий дизайн. Плохой и хороший - не совсем подходящие слова). Но опять таки. Где именно производить дублирование кода, нужно смотреть предметно и точечно, по ситуации.

Anton Kucherov
Поэтому существуют ситуации в которых сущности мож...

Так продумать места где система может измениться и есть один из важных этапов проектирования.

Anton Kucherov
Сама необходимость дублирования обычно продиктован...

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

serg
ну, скопипастить функционал, много времени не нужн...

Я бы сказал DRY в части случаев нарушает принцип единой ответственности. Объединяя код у которого имеются разные причины для изменения.

Anton Kucherov
Я бы сказал DRY в части случаев нарушает принцип е...

а пон. объединил функционал не зная меры :)

serg
ну, скопипастить функционал, много времени не нужн...

Это только микросервисами решается. А проблема вытекает из неверного выборауровне абстракции скорее всего, потому кажется что похожий функционал это нарушение DRY

serg
а пон. объединил функционал не зная меры :)

Да, я именно об этом. Я лично часто такое встречал. Когда объединяют просто чтобы объединить. Грубо говоря берем CopyPaste детектор и в тупую объединяем похожие строки кода обобщая его

Anton Kucherov
Да, я именно об этом. Я лично часто такое встречал...

хорошо, что здесь нет джавистов. сейчас бы нас просветили...

Похожие вопросы

Обсуждают сегодня

а через ESC-код ?
Alexey Kulakov
29
30500 за редактор? )
Владимир
47
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
13
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
в JclConsole объявлено так: function CtrlHandler(CtrlType: DWORD): BOOL; stdcall; - где ваше объявление с stdcall? у вас на картинке нет stdcall
Karagy
8
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
Ребят в СИ можно реализовать ООП?
Николай
33
program test; {$mode delphi} procedure proc(v: int32); overload; begin end; procedure proc(v: int64); overload; begin end; var x: uint64; begin proc(x); end. Уж не знаю...
notme
6
у вас два процесса. один посылает другому сигнал. у вас есть код обоих процессов? если всё не так - расскажите как оно на самом деле. а именно кто кому чего, есть-ли консоли,...
Karagy
6
Карта сайта