Pull to refresh
71
0
Tishka17 @Tishka17

Пользователь

Send message

я переформулировал: вопрос в том, мы вычисляем абсолютную величину для целого или для дробного числа.

ну и в порядке шутки из других языков:

>>> x=-999999999999999999999999999999999999999999999999999999999999
>>> sqrt(abs(x))  
1e+30
>>> sqrt(fabs(x))
1e+30

используем синтаксис языка Си, хотя язык здесь не важен

Пишу на языке где нет перегрузки функций по типу параметра, поэтому - важен.

Добавление и редактирование карточки товара актуально для карточки товара. А, например, редактирование проведенной транзакции - вещь странная. Редактировать сумму счета вообще не стоит просто так. Если вы пишете конкретную логику, там будут конкретные действия вроде "отредактировать карточку товара" (редактирование даты создания сюда не входит) или "поменять статус транзакции" (изменение суммы перевода сюда не выходит). Эти действия формально все udpate, но при этом они не абстрактные, они делают конкретный вид апдейта, имеющий определенный смысл с точки зрения бизнес логики. И другие апдейты при этом могут быть запрещены

Не делать CRUD вообще. Этот набор букв - вырожденный случай. В реальном мире у вас не CRUD, а что угодно - начиная от только R и заканчивая десятками действий на сущность.

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

Даже если рассматривать только R(ead) - мы имеем разные варианты поиска сущностей. Где-то чиатем по ID, где-то получаем отфильтрованный список, где-то динамические фильтры зависящие от пользователя. С U(pdate) всё ещё хуже. Продукт может быть продан, деньги переведены на другой счет, дом построен. Сгребая всё под термин update мы теряем самое главное - то ради чего писался код, бизнес value конкретной единицы.

Обобщенный репозиторий может быть. Точечно или закрытый "фасадом". В общем, не стоит начинать с него.

Протоколы, лежащие отдельно это окей. Но они принадлежат тому же слою что интеракторы. И нужно как-то понимать где граница этого слоя.

Что за CRUDService? Какое он место занимает на исходной схеме? Что по Interface Segregation Principle?

Те же вопрос к CrudRepository. Почему это дженерик класс? Почему в нем именно такие сигнатуры методов? Гарантируете ли вы что для все сущностей все методы должны быть именно такие? Например, не везде id будет int, мало где нужен fetch_all, зато много где будут разные способы фильтрации. Почему у вас протоколы репозиториев лежат где-от отдельно от интеракторов (я же правильно понял что их роль выполняют функции в последнем блоке кода типа sell)?

Рекомендую к прочтению https://www.ben-morris.com/why-the-generic-repository-is-just-a-lazy-anti-pattern/

Если у меня есть запросы вида get by id, list с различной фильтрацией, то я хочу чтобы полученная сущность была одного типа. Желательно того, который я спроектировал до того как начал детализировать логику запроса.

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

Я правильно понял, что вы предполагаете сгенерировть кучу одинаковых классов и если мне дальше надо результат таких запросов одинаково преобразовывать - то делать union?

Тип сгенерирован и реален: делайте с ним, что душе угодно.

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

Лично мне от слоя работы с БД мне нужно две вещи: возможность легко собирать в нем разные запросы и маппить результат в какие-то классы. И тут я вижу два варианта: эти классы определены в слое работы с БД как ORM и у вас и тогда не понимаю чем плох ORM, или они определены в доменном слое и тогда я не понял как будет маппинг на них

Спсибо большое, я понял о какой проблеме речь. То есть мы теперь мы

  • потеряли:

    • возможность из линтера (без живой БД) частично проверять, что поля в запросе соответствуют некоторой определенной в коде модели

    • возможность динамически собирать запрос

    • переиспользовать типы, определенные вне слоя работы с БД

  • получили:

    • генерацию типов, соответствующих реальной БД и реальным запросам

так?

Каюсь, просмотрел по диалогонали. Увидел: написанный текстом SQL и тезис "Никаких SQL билдеров, никаких ORM, никаких моделей - просто запросы и их результаты в любой удобной для проекта форме". И вот непонимаю, елси это дополнение к SQLAlchemy Core, то почему запросы текстом. А ещё тезис, что линтер как-то поможет тут - какой линтер проверит что строковые тексты запросов соответсвуют структуре БД?

Ниже вы подставляете имена колонок из таблиц ORM, но в этом случае непонятно зачем вообще это писать в таком виде. Мы лишаемся возможности динамичеки формировать запросы, а получаем что? Очередную библиотеку маппинга на датаклассы, но почему-то привязанную к СУБД?

А какие проблемы Sqlalchemy Core решает этот проект?

Рекомендую автору почитать зачем нужен dependency injection, dependency inversion и зачем люди делают зависимости более явными (спойлер: чтобы код работал более очевидно). Вы соорудили какого-то монстра чтобы сэкономить на передаче сессии, зато потом непонятно как это поддерживать.

Зашёл прочитать про код без типов, а прочитал про код без тайп хинтов.

Автор, не путайте нас. Когда вы пишете x=1, число 1 имеет тип int, а вот переменная x хинта явного не имеет. А дальше можно накручивать разную логику подсказок и проверок. Но факт в том, что тип у объекта есть и доступные операции у единицы как раз определяются ее типом.

Так просто это не типы, это подсказки. Типы есть у любого объекта, а хинты - у переменных, атрибутов и т.п. Автор хочет всех запутать

Не заметил чтобы эти затраты учитывались в расчете прибыльности в посте

Простите, а что за bot.send_messages? Не вижу в официальной документации телеграмма возможности отправлять сообщения пачками, только по одному.

Он работает через mtproto, а не botapi, что может стать ограничением при масштабировании. Зато позволит использовать пару дополнительных методов и посылать файлы большего размера без поднятия доп сервера. А вот что там насчёт удобной работы с переходами и прочим - не знаю.

Телеграм не разрешает получать апдейты с нескольких "устройств". То есть вы не можете запустить несколько копий поллинга или настроить несколько хуков. В остальном, токен может юзать сколько угодно процессов, главное не выходить на лимиты запросов.

Антипаттерн №6: Зависимость от внешних API

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

  • с недоступностью API из-за поломки его сервера вряд ли можно что-то сделать, только сотрудничать с провайдером API и договариваться о резервировании

  • смена формата API обычно не происходит внезапно, хорошие провайдеры стараются заранее предупреждать и обеспечивать совместимость хотя бы какое-то время

  • юридические ограничения (например санкции) я обсуждать скорее всего не смогу.

Если вы не хотите зависеть от API, вы должны либо полностью отказаться от его использования, либо иметь альтернативное решение, на которое можете переключиться прозрачно для пользователя.

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

Указанный в пример "асинхронный код" на самом деле полностью синхронный, хоть и использует aiohttp - в нем все действия делаются строго по очереди. Чтобы что-то начало работать асинхронно надо как минимум запустить несколько задач по обработке, а ещё учесть как телеграм доставляет сообщения (например, число коннектов при вебхуках ограничено и он ждет успешного ответа на запрос).

Телеграм ругается только если у вас несколько копий делают polling. В случае вебхуков у вас идёт запрос на один урл, а дальше типичное масштабирование веб приложения

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity

Specialization

Backend Developer, Mobile Application Developer
Lead
Python
Docker
Linux
SQL
Git
Golang
Android SDK