Pull to refresh
12
6
Сергей @KarmanovichDev

python разработчик с многолетним опытом

Send message

Я очень рад, что смог заинтересовать вас! Опыта в написании у меня мало, но стараюсь вкладывать душу :)

Спасибо, поправил. Прогоняю статью после написания через сервис. Не везде могу точно сказать, как будет правильнее(мой минус).

В копилку к тому, что кто-то, что-то сделает не так - мы применяем TDD при разработке, и вполне уверены в коде который пишем )

Конструируйте без фабрики, нет проблем. Клас лишь ожидает пачку примитивов, если вы смогли их получить без фабрики, то пожалуйста. Но тогда вы будете нарушать dry.

Я лишь показал свой путь эволюции при усложнении создания объектов.

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

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

Если так рассуждать, можно и Джанго модели считать DTO? Повторюсь, для меня pydantic это валидация и сериализация.

Мне кажется, если мои объекты изначально на pydantic, то нехотя бизнес-логика может начать готовить ответ сразу клиенту прямо в бизнес-логике, примешивая уровень презентации.

И я не предлагаю серебряную пулю. Я рассказываю свою историю. Я так делаю и для меня это работает :)

Может быть у вас был другой опыт, и вы нашли лучшее или просто другое решение, которое вас устраивает. Это хорошо!)

А по поводу того, что кто-то может не так использовать код - да, может. Я не боюсь этого. Мы специалисты не просто так, ну и никто не отменяет анализаторов и подсветки idea, которые решают 99% подобных проблем, если вы качественно аннотируете код :)

Я стараюсь не тащить сторонние библиотеки в бизнес-логику.

Для меня DTO не должен быть валидатором и сериализатором.

В контроллере или адапторах да, без проблем. В бизнес логике только DTO, value object, entity, которые являются простыми классами или dataclass

Здравствуйте. Рад, что статья оказалась интересной для вас)

По поводу post_init: Нужно смотреть конкретные примеры, что там происходит.

Если там происходит создание новых полей на основе тех, которые пришли в init, то в рамках эволюции при создании объекта, мне такой подход нравится меньше.

Если условная фабрика полностью конструирует объект, то post_init как будто доделывает чью-то работу. Выходит, что он не забирает на себя всю сложность создания. Эта сложность размазывается между init и post_init.

Учитывая, что они неразрывно связаны, то получается, что это то же самое, что, если бы мы в конце init вызывали post_init(За нас в данном случае это делает механизм dataclass)

Подытожу: При написании бизнес-логики я бы старался не использовать post_init для целей создания одних полей на основе других или валидации данных.

Но не забывайте о том, что как dataclass, так и архитектура кода, это инструменты, которые мы используем для решения бизнес задач.

Поэтому всем нам нужно учиться балансировать между "качеством кода" и "скоростью разработки". Далеко не всегда есть время писать так, как правильно, но лучше осознано оставлять тех долг, чем неосознанно писать некачественный код.

Спасибо, что заметили! Исправил )

Благодарю за обратную связь! Рад, что вы смогли найти статью полезной )

Я рад, что вам понравилось )

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

Если вы в целом считаете что паттерн плохой или его нельзя использовать, это ваше мнение, я с ним спорить не буду :)

Целью же данной статьи является информирование, а не холивар на тему, какой подход лучше. Лучше тот, который нравится вам и решает ваши задачи :)

Я не буду спорить. Считаю что наши мнения расходятся на этот счёт. Может быть мы просто не понимаем друг друга. Если вам не понравилась статья, это нормально. В любом случае спасибо вам за обратную свзяь! ?

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

Не буду вас переубеждать ?

Если это возможно, покажите минимальный пример, как вы взаимодействуете с UoW в клиентском коде :)

Насчёт CQRS не совсем понял, у вас агрегата не будет тогда? Если нет, то и без CQRS на отдельных репозиториях можно жить )

Если имеете ввиду, что кроме репозитория, другие механизмы будут уметь восстанавливать сущности из БД, то у вас размазываются знания об одной сущности на несколько механизмов.

По поводу разных БД, можно упростить - "у вас есть две разных БД", это более реальная ситуация.

Ещё раз упомяну, статья о паттерне, не о "серебреной пуле" в любой ситуации ?

Не соглашусь что про БД ни слова. В книге, Мартин многократно упоминает про базы данных(говоря о UoW). Сама глава про UoW начинается со слов - "Извлекая данные из базы данных ..."

В моём примере используются именно они, поэтому я и упоминаю, что UoW знает о них.

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

От вашего UoW зависит UseCase. UseCase будет использовать конкретные зависимости из UoW. Если вы не раскрываете, что лежит в UoW, как UseCase(у) взаимодействовать с ним?

В стандартном исполнении это репозитории, так как UoW по канонам используется для баз данных. Если у вас используются другие паттерны для CRUD работы с БД, то расскажите пожалуйста ваш сценарий использования UoW.

Спасибо за обратную связь!

Агрегат из другой архитектуры(ddd), мешать две архитектуры просто потому что, не мой подход.

тут я 10 раз подумаю, прежде чем создавать агрегат. Особенно из этих двух сущностей.

Создание агрегата должно быть обоснованно, и нужно понимать, какую ответственность это налагает.

С агрегатом вы обязаны управлять жизненным циклом обоих сущностей только через агрегат.

У вас не может быть репозитория клиент+менеджер, и отдельный только на менеджеров. Это сразу нарушит dry, так как ваши знания об одинаковых данных расползутся. Так же будет неправильным доступов к данным, так как с сущностями агрегата можно взаимодействовать только через агрегат.

Неудобства начинаются с самого начала, как только вам нужно получить менеджеров по какому то критерию, касающегося менеджеров.

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

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

Ну и заканчивая желанием просто перейти на карточку менеджера, нужно восстановить из памяти весь агрегат, прежде чем получить о нём информацию.

Это ещё всё не так страшно. Если ваш агрегат содержит несколько сущностей, или подчинённая сущность имеет множество вхождений, то при восстановлении агрегата у вас будут восстанавливаться тысячи или десятки тысяч объектов, когда вам нужен лишь один.

Не говоря уже о двух разных сущностных, когда их не объединить в агрегат при всём желании.

Если, как вы говорите, повесить транзакционность уровнем выше чем юзкейс, то ваш юзкейс будет неполноценным.

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

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

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

И так будет работать, но нужно понимать, что это нарушение, и идти на него с осознанием этого, а не просто делать как легче.

Подскажите, что мне сделать если один репозиторий mysql, другой postgresql, третий вообще не sql. Кто должен уметь держать три разные транзакции? Контроллер? Сомневаюсь :)

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

Спасибо за вашу обратную связь.

Согласен, я не обратил внимание, что оставил там абстракцию, такого высокого уровня.

Считаю что может быть абстрактная UoW, но отыгрывать через композицию в конкретных реализациях UoW или фабриках которые собирают это UoW.

Иначе просто наш бизнес код будет зависеть от деталей реализации.

Не совсем понял о каком интерфейсе вы говорите.

Так же не утверждаю, что UoW единственный/лучший вариант. Всё зависит от ситуации.

И статья имеет ознакомительный характер.

Уверен, что кто-то найдёт ему достойное применение )

Ещё раз спасибо!

1

Information

Rating
759-th
Location
Россия
Registered
Activity

Specialization

Backend Developer
Lead
Python
Linux
OOP