Vasily
Хоть ключевых слов накидай
Shub
Хоть ключевых слов накидай
откуда их взять, у нас постановки задачи нет. у нас есть только конкретное (но не единственное) решение задачи
Roman
демагогия какая-то
Shub
фишка в том, что interpret не скейлится.
Shub
у меня таких interpret по 300 строк около 20 по проекту
Roman
покажи, как надо, чтобы скейлилось тогда
Roman
кстати, interpret и не надо скейлить на огромный проект. Он ограничен bounded context.
Roman
просто в текущем приложении у меня этот контекст один всего лишь
Shub
для этого надо знать всю задачу
Vasily
Shub
Vasily
Ок, задача, как я понял, это апи платежного шлюза
Shub
а комбинацию изменений - в отдельный слой, чуть ниже API
Roman
для этого надо знать всю задачу
вот вся задача:
Есть юзеры, у них есть кредитные карты. Для простоты 1 аккаунт - 1 карта.
Нужно реализовать
- пополнение баланса
- платежи
- установку дневного лимита
- Круд операции для всех сущностей и валидацию для них
Vasily
Shub
Shub
Shub
впрочем, там монго, значит не особо
Roman
да, консистентность, транзакционность и тд можно опустить для простоты сейчас
Shub
платежи - это что такое?
x
если ещё не постили то вот https://m.youtube.com/playlist?list=PLpVeA1tdgfCDIuCqslWaTpOUBQRPIHTM2
Roman
платежи - это что такое?
списание с баланса суммы, если карта не просрочена, активна, на ней есть бабки и не превышен дневной лимит.
Stanisλav
Ребят, а у кого можно репозиторий подсмотреть, чтобы примерно понять, как тырпрайз пишется?
Ilya
Danil
Второй ролик уже интересный
Shub
я просто знаю, что все эти apply + interpret растут из одного популярного в узких кругах бложика
Shub
поэтому хочу еще раз напомнить, что в том бложике рассматривается задача категории “оверинжениринг за 300”. видимо ради учебных целей
Ayrat
у меня есть антипример кстати про этот decode handle interpret паттерн
Ayrat
не то чтобы я против него, но его можно заабузить до усрачки
Shub
ты нашу репу нашел, что ли?
Ayrat
прям так ядерно
Ayrat
ну не, у нас был один ебаный сервис
Ayrat
ща, покажу два гиста
Ayrat
поохуеваете тут с кода упорков
Roman
я просто знаю, что все эти apply + interpret растут из одного популярного в узких кругах бложика
это все неконструктивно. Твое субъективное мнение по поводу текущей реализации мы все уже очень давно поняли, ты высказал его несколько раз.
Спросили о другом: как это решение спроектировать лучше. В идеале код, но если уж совсем туго со временем — то хотя бы просто роадмап и список абстракций, на которых все строить надо.
А повторять, что интерпретатор это от лукавого и его блога больше не нужно
Roman
Shub
см. выше. разноси interpret по разным слоям. логика изменений и валидация - в доменный тип, платежи скорее всего в отдельную сущность. персистенс и бизнес-правила - в отдельный слой
Shub
*слои
Roman
Roman
и даже внутри слоя оно на разные модули все разбито
Roman
Ayrat
https://gist.github.com/Szer/6cd0ba8e1068e4d29752f9170a72b42f
https://gist.github.com/Szer/4544187940a02d6e37a0e41dfa3a7a1b
Предлагаю два варианта одного и того же. Голосуем
Ayrat
функциональность, вплоть до логирования в нужных местах и кодах ответа идентичная.
Vladislav
Vladislav
От 2 тяжело глазам
Vladislav
Не вчитываясь
Roman
Roman
а, походу не вдвое, а больше
Roman
судя по //тонна говнокода
Ayrat
ну т.е. банальную задачу. В 21ом веке
Ayrat
И не стесняются городить ЛОГИРОВАНИЕ
let pipeTimeout
(decode:UriTemplateMatch option * HttpRequestMessage -> 'Input)
(handle:'Input -> Async<'Output>)
(interpret:UriTemplateMatch option * HttpRequestMessage -> 'Output -> Async<HttpResponseMessage>)
(timeoutMs:float) =
Marvel.Service.pipe decode handle interpret
|> Service.filterWith
(Filter.andThen errorFilterDefault loggingFilterDefault
|> Filter.andThen (Filter.timeOutMs timeoutMs)
|> Filter.andThen (Filter.timing Log))
Ayrat
бля
Ayrat
отформатировал чтобы было ПОНЯТНЕЕ
Ayrat
но скорее всего понятнее не станет
Roman
да, я не очень понимаю
Ayrat
Ну и да. Отличное применение типизированным ответам:
match data with
| Output.SellableFlagResult _ -> httpResponse request "Queue is loading ..."
| Output.AzureQueueStatusResult message -> httpResponse request message
| Output.MemberPriceOverridesResult resp -> httpResponse request resp.message
| Output.MemberPriceOverridesError msg -> httpResponse request msg
...
Ayrat
Отличная интерпретация:
| Output.AzureQueueStatusResult _
| Output.MemberPriceOverridesResult _
| Output.MemberPriceOverridesError _
| Output.AutoKillWhiteListResult _
| Output.NodeShippingMethodOverrideResult _
| Output.PromoCodResult _
| Output.LoadRskusForRepricingError _ -> Async.empty
Roman
Ayrat
в общем, код хоть сейчас на стену вешай
Roman
А для управления зависимостями норм? Или лучше через параметры инжектить?
Roman
пока тут было 4 варианта, насколько я помню:
- использовать классы и DI фреймворк
- хранить зависимости в мейлбоксе
- паршл аппликейшн
- интерпретатор
Shub
Shub
> do! interpretGeneric data
Shub
Roman
любой подход при неконтролируемом разрастании превращается в говно. Имхо это не проблема подхода, а проблема своевременной декомпозиции
Shub
Roman
Roman
ох бля
Shub
или мы про разный код говорим?
Roman
я хз. Я говорю про все тот же проект, что я скидывал. Но я не уверен, что ты читал код внимательно, если честно
Shub
ну как внимательно. минут 15 потратил, да
Shub
если речь про interpret, то там не инжектить зависимости надо, а убирать их оттуда вообще
Roman
а зачем он тогда нужен? И как тогда связать ДАЛ с бизнес логикой?