Re[7]: Что если не разделять строго dto, entity, bo...
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.12.25 17:36
Оценка: +2 :))
Здравствуйте, gandjustas, Вы писали:

G>То есть вы против dry на клиенте, потому что создание повторно используемого кода это сложно?

G>Может на сервере делать также? Просто скопипастить код в контроллерах, и поменять запросы?
Ну так это же и есть основной способ. Смотрите, как у нас всё классно — мы фигачим чотко по плану, два с половиной контроллера в человеко-день!
На каждую фичу нужно пять контроллеров, один DTO, один Entity, один репозиторий, один этот, как его, Aggregation Root, пять хранимых процедур.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[7]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 04.12.25 17:27
Оценка: 5 (1) -1 :)
Здравствуйте, Kernan, Вы писали:

K>Здравствуйте, gandjustas, Вы писали:


S>>>Здравствуйте, gandjustas, Вы писали:


K>В чём тогда серебряная пуля? Где граница применимости и как понять когда всё, приехали и "абстракции" давят и наоборот когда код превратился в набор спагетти? Все DDD, CA и т.п. было зря?



Ключевое прекрасно описано вот в этом посте: https://www.teamten.com/lawrence/programming/write-code-top-down.html

Процитирую основную мысль:

Существует два подхода к проектированию программ и написанию кода: «сверху вниз» и «снизу вверх».

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

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

Правильный подход к проектированию и написанию программы — «сверху вниз». Это не вопрос вкуса или предпочтений. Подход «снизу вверх» в корне ошибочен, и его не следует использовать.


Если вы со старта проекта начинаете применять архитектурные паттерны, то вы фактически занимаетесь проектированием «снизу вверх».

На каждом уровне существует стремление в программировании «снизу вверх». Избегайте этого. Вместо этого начните с верхнего уровня, с main() или его эквивалента, и пишите так, как будто все части уже написаны. Добейтесь правильного вида. Вставьте заглушки или хардкод отдельных частей пока не добьетесь компиляции и запуска. Затем медленно продвигайтесь вниз, стараясь максимально упростить все. Не пишите ни строчки кода, которая не решает проблему, с которой вы столкнулись прямо сейчас. Тогда у вас может появиться шанс написать большую, работоспособную и долговечную программу.

Re[10]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 04.12.25 18:19
Оценка: 83 (2)
Здравствуйте, Pauel, Вы писали:


P>Разделение, изоляция итд, это дополнительная работа. Собственно, почти всё, разве что кроме веб фронтенда, можно писать в одной единственной функции main без каких либо других функций, классов, интерфейсов итд. Буквально.

P>Собственно, если внимать словам gandjustas, то здесь нужно остановиться и прекратить заниматься ерундой — 1 файл + 1 main, и больше ничего.
Можешь показать где я такое говорил?
Я говорил что надо уменьшить количество строк.
Во-первых отсутствие декомпозиции тебе непременно количество строк увеличит из-за дублирования.
Во-вторых на любом достаточно сложном коде у тебя количество сложенных иф_ов, и циклов превысит размер, умещаемый на экране по горизонтали.
В-третьих тебе код надо не только писать, но и читать, а для этого нужна навигация по коду, которую без структуры очень сложно сделать.
В-четвертых некоторые приемы уменьшения кода: наследование, полиморфизм, функциональная композиция, вынуждают тебя делать структуру из классов или функций.
В-пятых фреймворки за счет DI и встроенных паттернов заставляют тебя делать структуру. Не сделать структуру = написать больше кода.

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

P>То есть, для маленьких приложений, буквально хватит 1 файл + 1 main.

С этим наверное вообще никто спорить не будет.

P>Но чем больше и сложнее, приложение, тем больше и глубже будет разделение на внутренние компоненты.

Не очень понятно где от одного файла и все в main перейти к domain model.

P>То есть, вводить мапперы/интерфейсы/компоненты/итд надо в том случае, когда добавленная сложность покроется выгодой от изоляции/абстрагирования и упрощения в других местах.

Если ты заранее генерируешь ДТО на каждый слой, то тебе уже нужен маппер.


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

P>Если у вас 1 бд, 1 ui, и ничего больше — от мапперов толку мало.
Апологеты DDD скажут что толк есть, негоже на UI отдавать доменные объекты.

P>А если у вас вспомогательная утилитка "скопировать 5 юзеров из той бд в эту" то вам вообще хватит 1 файл + 1 main.

Если программу изначально создавать как большую, то и получится большая, с кучей мапперов и ДТО, если по итогу она только 5 юзеров копирует.

Я всегда говорил, что нужно в каждый момент времени писать минимум кода для решения задачи, которая есть в данный момент. ИМХО в таких условиях вероятность появления domain model и DTO стремится вообще к нулю.
Re[13]: Что если не разделять строго dto, entity, bo...
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 10.12.25 08:26
Оценка: 10 (1) +1
Здравствуйте, gandjustas, Вы писали:

G>Когда код делает +\- одно и то же и может быть написан без архитектурных паттернов, то по формальным метрикам...


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

P>>А вот с мапперами вам почему то непонятно

G>Потому что мапперы это не корень проблемы, а следствие. Если вам нужен маппер, то вероятно, что вы сильно ранее свернули не туда.

Маппер нужен в том случае, если приемник требует свою форму. Например, в ui вы отдаёте плоский компактный объект, а в бд у вас иерархия таблиц-объектов-коллекций-итд.
В этом случае вы развязываете изменения в бд и ui. Например, другая фича потребует изменение в структуре бд. Опаньки — дальше маппера это изменение не пролезет.

P>>Любой концепт — класс, функция, интерфейс, итд, это то самое разделение.

P>>Если бенефитов нет, см ваши "во-первых..." то добавление класса, функции, интерфейса, итд смысла не имеет. Мапперы, паттерны здесь ничего не меняют.
G>Еще раз:
G>1) Без разделения скорее всего кода станет больше

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

G>Рецепт как вводить изменения вовремя уже многократно дан — ты пишешь максимально простой код чтобы решить ту задачу, которая у тебя есть в данный момент и не пишешь код, который к решению задачи не относится.


Это все добросовестные разработчики так делают. Просто видение что к чему относится или нет, у всех разное. Держать в фокусе только краткосрочную перспективу — идея очень так себе. Так что буквально ваш совет не работает.

P>>А если изначально большую писать как маленькую, то есть чудовищно огромный шанс или утопить, или вырастить монстра, или убить весь бюджет на один только рефакторинг.

G>Вот что-то я такого не видел. Усложнять всегда просто, упрощать — сложно.

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

P>>Ой да ладно. Вы подразумеваете какой то свой набор приложений-проектов. Озвучьте уже его.

G>Да любые корпоративные многопользовательские приложения.

Корпоративные приложения очень разные. Например, практически везде разделяют дто ui и дто базы данных. А у вас это сходу "свернули не туда"
Re[9]: Что если не разделять строго dto, entity, bo...
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 02.12.25 15:01
Оценка: 9 (2)
Здравствуйте, Kernan, Вы писали:

K>Однако, тезисы Ганджустата как-то говорят о том, на мой взгляд, что домены это хорошо, но пиши как знаешь и проще, всё равно по метрикам на большом проекте это не даёт особого профита. Вот как быть?


А что вас смущает? Он собрал какую то свою статистику на каких то ему одному известных проектах. Как это переиспользвать — вероятно, что никак.

Разделение, изоляция итд, это дополнительная работа. Собственно, почти всё, разве что кроме веб фронтенда, можно писать в одной единственной функции main без каких либо других функций, классов, интерфейсов итд. Буквально.

Собственно, если внимать словам gandjustas, то здесь нужно остановиться и прекратить заниматься ерундой — 1 файл + 1 main, и больше ничего.

Штука в том, в разделение/изоляция/абстрагирование имеют свою цену, что очевидно.

То есть, для маленьких приложений, буквально хватит 1 файл + 1 main.

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

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

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

Если у вас 1 бд, 1 ui, и ничего больше — от мапперов толку мало.

А если у вас вспомогательная утилитка "скопировать 5 юзеров из той бд в эту" то вам вообще хватит 1 файл + 1 main.
Re: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.11.25 12:46
Оценка: +1 -1
Здравствуйте, Shmj, Вы писали:

S>Вопрос такой.


S>Вот, обычно делают слои и на уровне каждого слоя свои объект — для строгого разделения. А потом мапперы между слоями.


S>Но задумался — а какие реальные бонусы?

Реальные бонусы для кого?

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

Для разработчика зачастую бонусы есть:
— возможность написать много кода, с разумным оправданием. Программисты зачастую испытывают удовольствие от написания кода и создания «архитектуры», даже если мела ной потребности в этом нет
— возможность дороже продать свою работу. написать одну строку стоит в 10 раз дешевле, чем написать 10 строк.
— возможность применить больше хайповых паттернов и библиотек, чтобы написать в резюме. В одну строку много паттернов не запихнешь, а в 10 уже можно.
Re[18]: Что если не разделять строго dto, entity, bo...
От: Sinclair Россия https://github.com/evilguest/
Дата: 31.12.25 14:07
Оценка: +1 :)
Здравствуйте, gandjustas, Вы писали:

G>Что там является "моделью предметной области", в чем её ценность, и как она влияет на остальные части кода?

Да вот же она: https://github.com/gandjustas/habr-post-stock-api/blob/main/Model.cs
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.11.25 14:32
Оценка: 78 (1)
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


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


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


А откуда мнение что код с кучей dto и мапперов менее запутанный и проще поддерживается чем без него?
Я вот проводил замеры maintainability index для кода с разделением и без и не код с разделением стабильно проигрывал.
Это потом что maintainability index зависит от halastead volume, по сути от нормированного количества строк.

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

S>И что заказчику делать, если разработчик три дня исправляет простой баг а после исправления создает новый баг? Выгонять?

Чтобы ответить на этот вопрос надо понимать почему так происходит.

S>Ок, выгнал (а скорее тот сам ушел еще до того, как проблема стала очевидной). Берет нового — новый говорит что нужно все переписывать с нуля. Берет другого — тот делает вид что работает, месяц делает вид, два — говорит что еще разбирается в проекте. А потом начинает работать еще медленнее.

Если ты заказчик, который не разбирается в процессе, то плати только за результат, а не за время
Re[9]: Что если не разделять строго dto, entity, bo...
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 05.12.25 08:35
Оценка: 5 (1)
Здравствуйте, Qulac, Вы писали:

Q>Clean Architecture не мешает разрабатывать в любом направлении. Вот TDD — подход с верху в низ, но работают здесь с моделью.


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

С подходом снизу вверх есть шанс что вы попадёте не туда. С подходом сверху вниз есть шанс что затратите хрен знает сколько времени и ресурсов.

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

Снизу вверх лучше работает, когда вы почти ничего и не знаете. Понадобилася эндпоинт — добавили. Понадобился еще один — дописали. БД не нужна — вы её и не добавляете. Нужна будет бд, или будете работать сервисов — будет ясно потом.
В этом случае есть компонент, или нет его, как он будет взаимодействовать с остальной частью приложение — такие решения принимаются максимально поздно, по мере проработки внутрянки компонента.
Недостаток — если в итоге вам нужно большое приложение, то вы затратите хрен знает сколько времени выращивая его эволюционно.

Правила большого пальца:
1. нужно маленькое приложение — пишите как маленькое
2. нужно большое — пишите как большое.
3. в любом случае нужно прояснять ситуацию, что бы не ошибиться с принятием решения.
Отредактировано 05.12.2025 8:36 Pauel . Предыдущая версия .
Re: Что если не разделять строго dto, entity, bo...
От: Qulac Россия  
Дата: 28.11.25 19:05
Оценка: +1
Здравствуйте, Shmj, Вы писали:

S>Вопрос такой.


S>Вот, обычно делают слои и на уровне каждого слоя свои объект — для строгого разделения. А потом мапперы между слоями.


S>И у меня сейчас проект, который нужно дорабатывать. Там этой парадигмы разделения не придерживались строго, так что в ui проникают как dto, так и entity. Проект пока не большой, около 25 тыс. строк кода, т.е. за пару-тройку дней можно разделить и добавить мапперы.


S>Но задумался — а какие реальные бонусы? Вот что пишет зазнайка:


S>

S>Если использовать DTO в Домене: Ваша бизнес-логика становится зависимой от API-контрактов. Если фронтенд попросит переименовать поле в JSON для удобства отображения, вам придется менять это поле в бизнес-логике, что может повлечь ошибки в расчетах. Внешний мир начинает диктовать правила внутреннему.

S>Если использовать Entity в Домене: Ваша бизнес-логика зависит от схемы базы данных. Если вы решите денормализовать таблицу для производительности или сменить PostgreSQL на MongoDB, вам придется переписывать бизнес-правила.

S>Правило архитектуры: Зависимости должны быть направлены внутрь. Слой Домена (бизнес-логика) должен быть самым стабильным и не зависеть ни от Базы Данных, ни от UI/API.

Правильно. Еще БЛ — это центральное место приложения усилий при разработке. Здесь находится самый дорогой код, на него было потрачено сотни часов работы аналитика, здесь самые дорогие и долгоживущие баги.

S>Но на практике вот что. Если что-то нужно добавить в UI — можно использовать расширения/mixin. И что? Никакой сложности не добавляет.

Можно и руками.

S>Если что-то изменилось в API — то один хрен нужно менять все слои. Но если добавилось новое поле и мы его не используем — то и в текущей схеме ничего не сломается.

Ни чего не понял.

S>Если изменилась схема хранения данных, к примеру переименовали поле — то сейчас нужно в двух местах переименовать — в entity и в ui, где этот entity напрямую используется. Если добавим мапперы — легче не станет.

Да хоть в 10 местах, что это меняет, откуда такая мания экономить на спичках?

S>Далее. Если добавим тесты и фейковые реализации сервисов — то что мешает в этих фейковых реализациях использовать уже существующие классы для объектов, ведь у них есть конструктор...

Зачем фейковые сервисы,если они только не являются сторонними к проекту. Фейковыми должны быть репозитории.

S>По этому как бы, получается, есть вера что нужно разделять — но нет реального смысла.


Ну не применяй.
Программа – это мысли спрессованные в код
Re[4]: Что если не разделять строго dto, entity, bo...
От: Shmj Ниоткуда  
Дата: 29.11.25 18:19
Оценка: +1
Здравствуйте, gandjustas, Вы писали:

G>А откуда мнение что код с кучей dto и мапперов менее запутанный и проще поддерживается чем без него?

G>Я вот проводил замеры maintainability index для кода с разделением и без и не код с разделением стабильно проигрывал.
G>Это потом что maintainability index зависит от halastead volume, по сути от нормированного количества строк.

G>В целом я не понимаю как увеличение количества кода может положительно сказываться на стоимости поддержки.


Ну на счет разделения объектов (для каждого слоя свой набор объектов) + мапперы — вижу только один смысл — когда над каждым слоем работает отдельный человек и чтобы не ждать пока Вася изменит свой слой — Петя может уже создавать и тестировать. А уже отдельный чел. занимается исключительно мапперами и интеграцией слоев в единую систему.

Других плюсов особо не видно. Т.е. если у вас нет строгого разделения труда — то нет смысла и в строгом разделении объектов. Но когда несколько человек работают над системой одновременно и каждый занимается своим слоем — появляется смысл все-же.

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

S>>И что заказчику делать, если разработчик три дня исправляет простой баг а после исправления создает новый баг? Выгонять?

G>Чтобы ответить на этот вопрос надо понимать почему так происходит.

Порядок. Вот в вещах порядок — можно все разложить по коробочкам (особенно поймут электронщики). А можно как бы не заморачиваться и все вывалить в одну большую кучу.

Когда тебе нужно найти деталь — то по коробочка найдешь сразу (при грамотном структурировании). А кучу нужно перебирать каждый раз с нуля.

S>>Ок, выгнал (а скорее тот сам ушел еще до того, как проблема стала очевидной). Берет нового — новый говорит что нужно все переписывать с нуля. Берет другого — тот делает вид что работает, месяц делает вид, два — говорит что еще разбирается в проекте. А потом начинает работать еще медленнее.

G>Если ты заказчик, который не разбирается в процессе, то плати только за результат, а не за время

Но тогда ты просто перекладываешь проблему разработки и чистоты кода на чужие плечи. А проблема эта никуда не ушла. Лучше разберись сам и научить чистоте кода без привлечения посредников.
=сначала спроси у GPT=
Re[5]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 30.11.25 03:27
Оценка: +1
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


G>>А откуда мнение что код с кучей dto и мапперов менее запутанный и проще поддерживается чем без него?

G>>Я вот проводил замеры maintainability index для кода с разделением и без и не код с разделением стабильно проигрывал.
G>>Это потом что maintainability index зависит от halastead volume, по сути от нормированного количества строк.

G>>В целом я не понимаю как увеличение количества кода может положительно сказываться на стоимости поддержки.


S>Ну на счет разделения объектов (для каждого слоя свой набор объектов) + мапперы — вижу только один смысл — когда над каждым слоем работает отдельный человек и чтобы не ждать пока Вася изменит свой слой — Петя может уже создавать и тестировать. А уже отдельный чел. занимается исключительно мапперами и интеграцией слоев в единую систему.

Это возможно если для реализации требований нужно менять верхние слои, при этом не трогая нижние . Но при разделением как рекомендует domain model или onion/hexagon/clean architecture это невозможно, так как почти каждое значимое изменение требований приведет к изменению не только представления, но и хранимых данных, и, соответственно, всех слове между ними.


S>Других плюсов особо не видно. Т.е. если у вас нет строгого разделения труда — то нет смысла и в строгом разделении объектов. Но когда несколько человек работают над системой одновременно и каждый занимается своим слоем — появляется смысл все-же.

На практике удобнее не горизонтальное, а вертикальное деление. Например asp.net identity. Показывает как можно сделать отдельную функциональность, котрая содержит как работу с базой, так и часть представления, при этом достаточно хорошо кастомизируется и интегрируется с другими частями

Но конечно в asp.net identity вы не найдете паттерном clean archtecture

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


Я, честно, не видел современных приложений построенных по такому принципу. За счет того что везде есть data binding проще иметь промежуточный объект, к которому привязывается форма, а внутри него уже дергать методы БЛ. А если мокать бл для объекта, то можно удобно тесты писать

S>>>И что заказчику делать, если разработчик три дня исправляет простой баг а после исправления создает новый баг? Выгонять?

G>>Чтобы ответить на этот вопрос надо понимать почему так происходит.

S>Порядок. Вот в вещах порядок — можно все разложить по коробочкам (особенно поймут электронщики). А можно как бы не заморачиваться и все вывалить в одну большую кучу.

Если бы «раскладывание по коробочкам» было бесплатно, то все бы так делали. Но почему-то нет. См тот же asp.net identity

S>Когда тебе нужно найти деталь — то по коробочка найдешь сразу (при грамотном структурировании). А кучу нужно перебирать каждый раз с нуля.

Мне кажется это миф, все равно надо читать код и делать go to definition. И чем меньше кода и перекладываний объектов, тем проще. По крайней мере я на себе ни разу не замечал улучшение чтения от разделения.

S>>>Ок, выгнал (а скорее тот сам ушел еще до того, как проблема стала очевидной). Берет нового — новый говорит что нужно все переписывать с нуля. Берет другого — тот делает вид что работает, месяц делает вид, два — говорит что еще разбирается в проекте. А потом начинает работать еще медленнее.

G>>Если ты заказчик, который не разбирается в процессе, то плати только за результат, а не за время

S>Но тогда ты просто перекладываешь проблему разработки и чистоты кода на чужие плечи. А проблема эта никуда не ушла. Лучше разберись сам и научить чистоте кода без привлечения посредников.

Далеко не каждый сам способен разобраться
Re[11]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 04.12.25 18:50
Оценка: +1
Здравствуйте, Qulac, Вы писали:

Q>Здравствуйте, gandjustas, Вы писали:


G>>Здравствуйте, Qulac, Вы писали:


Q>>>Clean Architecture не мешает разрабатывать в любом направлении.

G>>Честно до сих пор не понимаю что такое CA.
G>>Если я написал контроллер из которого вызвал EF и данные в базу записал это уже clean или еще нет?
G>>Если мне для Clean Architecture еще что-то сделать, то это уже программирование «снизу вверх».

Q>Нет не CA.

Тогда оно не очень нужно.

Q>Лучше книжку почитать, самому поэкспериментировать.

Спасибо, обойдусь.
Re[11]: Что если не разделять строго dto, entity, bo...
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 05.12.25 07:15
Оценка: +1
Здравствуйте, gandjustas, Вы писали:

G>Я говорил что надо уменьшить количество строк.


Смотрите сам, что вы пишете "кода с разделением и без и не код с разделением стабильно проигрывал"

G>Во-первых

G>Во-вторых
G>В-третьих
G>В-четвертых
G>В-пятых

На примере 1 файл 1 main вам вроде бы понятно, какие последствия если отказаться от того самого разделения.
А вот с мапперами вам почему то непонятно
Любой концепт — класс, функция, интерфейс, итд, это то самое разделение.
Если бенефитов нет, см ваши "во-первых..." то добавление класса, функции, интерфейса, итд смысла не имеет. Мапперы, паттерны здесь ничего не меняют.

P>>Но чем больше и сложнее, приложение, тем больше и глубже будет разделение на внутренние компоненты.

G>Не очень понятно где от одного файла и все в main перейти к domain model.

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

P>>То есть, вводить мапперы/интерфейсы/компоненты/итд надо в том случае, когда добавленная сложность покроется выгодой от изоляции/абстрагирования и упрощения в других местах.

G>Если ты заранее генерируешь ДТО на каждый слой, то тебе уже нужен маппер.

А кто говорил, что надо заранее? Любое разделение обязанностей, см ваши пункты про main, нужно вводить вовремя. Слишком рано — утяжеляем и замедляем разработку. Слишком поздно — хаос.

P>>Если у вас 1 бд, 1 ui, и ничего больше — от мапперов толку мало.

G>Апологеты DDD скажут что толк есть, негоже на UI отдавать доменные объекты.

Да, есть люди, у которых инструмент важнее задачи. Что это доказывает? Это во всех методологиях ровно так же.

P>>А если у вас вспомогательная утилитка "скопировать 5 юзеров из той бд в эту" то вам вообще хватит 1 файл + 1 main.

G>Если программу изначально создавать как большую, то и получится большая, с кучей мапперов и ДТО, если по итогу она только 5 юзеров копирует.

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

G>Я всегда говорил, что нужно в каждый момент времени писать минимум кода для решения задачи, которая есть в данный момент. ИМХО в таких условиях вероятность появления domain model и DTO стремится вообще к нулю.


Ой да ладно. Вы подразумеваете какой то свой набор приложений-проектов. Озвучьте уже его.
Re[9]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 05.12.25 16:25
Оценка: +1
Здравствуйте, Kernan, Вы писали:

G>>Процитирую основную мысль:

G>>

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

K>Не совсем понятно как это работает, если честно.


K>Со старта я начинаю собирать сценарии использования

Сценарий использования это набор форм и или методов апи — создай эти формы\методы для начала
На формах есть поля, у методов есть входные и выходные данные. Сделай валидацию входных данных, сделай заглушку для возвращаемых данных.
Далее если одна функция данные сохраняет, а вторая возвращает, то напиши код который это делает самым простым способом — вызови напрямую ef\dapper\sqlclient что проще.
Повтори процедуру для других форм и методов. Устрани противоречия. Сделай рефакторинг, вынеси повторяющийся код в отдельные функции\классы. Только тут могут появиться простые паттерны GoF. До DDD и прочих архитектурных излишеств не дойдет если не пытаться решать задачи, которых нет.

K>и через них выхожу на модели предметной области, алгоритмы и т.п.

Мне кажется программисты слишком заморочены на "модели предметной области", как-будто есть в этом ценность.
Re[10]: Что если не разделять строго dto, entity, bo...
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 05.12.25 17:19
Оценка: +1
Здравствуйте, gandjustas, Вы писали:

K>>Со старта я начинаю собирать сценарии использования

G>Сценарий использования это набор форм и или методов апи — создай эти формы\методы для начала
А лучше начать с тестов...
G>Повтори процедуру для других форм и методов. Устрани противоречия. Сделай рефакторинг, вынеси повторяющийся код в отдельные функции\классы. Только тут могут появиться простые паттерны GoF. До DDD и прочих архитектурных излишеств не дойдет если не пытаться решать задачи, которых нет.
Не получилось бы так, чтобы всё написанное не пришлось бы переписать полностью после неудачных решений по-месту.
G>Мне кажется программисты слишком заморочены на "модели предметной области", как-будто есть в этом ценность.
Проще работать с моделями и метафорами чем с набором примитивных типов.
Sic luceat lux!
Re[14]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 07.12.25 17:53
Оценка: +1
Здравствуйте, Shmj, Вы писали:


S>Вот по тому же принципу и было добавлено — проще не делать архитектуру, где будет минимум кода — а добавить очередной костыль побыряку.


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

Сохранять простоту кода при разработке нетривиальных программ — сложный навык: требует концентрации, чтения существующего кода, постоянного изучения новых библиотек. Но эти затраты многократно окупаются на поддержке.
Если хорошо натренировать всегда выдавать максимально простой код, то это будет сильно быстрее, чем то, что фигачат DDD-программисты и всякие ИИ. Потому что есть предел количества строк отлаженного продуктивного кода, который может выдавать программист в единицу времени. И он почти не зависит ни от языка, ни от архитектуры.
Re[14]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.12.25 10:52
Оценка: -1
Здравствуйте, Pauel, Вы писали:

P>Здравствуйте, gandjustas, Вы писали:


G>>В этом случае конечно второе. Но это уже последствие.

G>>Ведь кто-то изначально написал эти 10к ЛИШНИХ строк, потратив кучу времени и денег.
G>>А если бы с самого начала не занимались этим, то вариант 2 не возник бы никогда.

P>Почему обязательно лишних, и потратив кучу времени и денег? Может оказаться что всё ровно наоборот.

P>Например, на момент написания эти 10к строк решали конкретные требования которые со временем отжили своё. Или, например, срочность изменений в требованиях была настолько высокой, что другого варианта, кроме как строчить и копипастить, вообще не было.
P>То есть, чаще всего вот эти "лишние" строки становятся такими только со временем. Это если отказаться от варианта "все дураки"
Тогда в чем проблема удалить код, который вообще не используется? Это же требует примерно 0 усилий.

Проблема удаления кода возникает когда он используется, на него много зазвано.

Например напрмиер предполагали высокую нагрузки и сразу же сделали систему "масштабируемой" за счет CQRS, а оказалось что нагрузка вполне приличная, а CQRS не обеспечивает транзакционность в нужных сценариях. Но вся бизнес-логика уже заточена на CQRS. И новые требования, касающиеся транзакционности, можно реализовать или навесив глобальный лок на таблицу, а можно выкинуть CQRS и сделать обычную транзакцию. Причем выкинуть локально, в одном методе, CQRS не получится, так как БЛ не может работать без него, надо или дополнительные связи в проект прокидывать или переписывать BL.

Причем мы же прекрасно понимаем, что в момент когда кто-то решил что нужно CQRS, то никакой явной потребности в этом не было.

P>Поэтому вопрос в том, какая у нас перстпектива в проектировании:

P>Если краткосрочная, "главное сделаить", тогда нужно строчить, копипастить и срезать углы, или просто лепить однострочники абы кода было поменьше.
P>Или же среднесрочная-долгосрочная, тогда нужно определиться какие же актуальные цели кроме "главное сделать".
Это же две альтернатиы, а целый континуум. Я предлагаю делйствовать как завещал Кент Бек: Make it work, make it right, make it fast.
То есть сначала делаем "главное чтобы заработало", потом устраняем ошибки в corner cases, очевидные code smells, вписываем в сущствующую архитектуру, делаем оптимальным.
Главное фокусироваться на одной задаче, а не заниматься проектированием системы. То есть не трогать ничего, что напрямую не касается данной задачи.

P>Например, реанимировать проект краткосрочными интервенциями "главное сделать" не получится. Скорее всего, он именно и зашел в тупик благодаря "главное сделать".

Как раз наоборот, в тупик заходят проекты, "проектируют наперед". Потому что если ты каждый раз делаешь минимум кода для решения задачи, то по какой причине у тебя появится тонна ненужного, но используемого кода?
Re[16]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.12.25 13:42
Оценка: +1
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


G>>Если хорошо натренировать всегда выдавать максимально простой код, то это будет сильно быстрее, чем то, что фигачат DDD-программисты и всякие ИИ. Потому что есть предел количества строк отлаженного продуктивного кода, который может выдавать программист в единицу времени. И он почти не зависит ни от языка, ни от архитектуры.


S>Я ни разу не апологет DDD, ни одной (пока) книги не прочитал, хотя тему изучал. Так вот, люди его не зря ценят, начиная от определенного объема

S>сложности, если архитектура спроектирована с учетом DDD, банально проще и быстрее расширять, вносить изменения и т.п. Но это дает свои плоды
S>при определенных объемах задачи\предметной области, т.е. много человеколет.

Я заявления эти тоже слышал, но на практике подтвердить не могу.

Любое тестовое приложение ограниченного объема без ДДД оказывается проще и быстрее, чем с DDD.
Найти два эквивалентных приложения одно с ДДД, а другое без для сравнения невозможно.
Некоторые парттерны DDD в некоторых условиях заведомо хуже работают, при этом явная выгода от них отсутствует.

Поэтому все что я видел глазами это то, что DDD несет большую сложность без какой-либо выгоды в небольшом приложении (условно до 10к строк), а какая выгода в большом — мне не ясно.
Re[15]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.12.25 15:36
Оценка: +1
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:



S>>>Считается, что первое достигается при помощи второго.

G>>Не понимаю логики:
G>>1) считается что без "модели предметной области" не бывает хорошей структуры кода? Это мягко говоря неправда
G>>2) считается что наличие "модели предметной области" всегда приводит к хорошей структуре? Это еще большая неправда

S>Понимание модели предметной области помогает достигать качественного кода -- все по папочка и т.п., а не в одном большом

S>методе main.

Вы сейчас пытаетесь сказать, что не бывает хорошего структурированного кода без "модели предметной области"? Я еще раз повторю что это неправда, предлагаю перестать об этом говорить.
Могу показать примеры хорошего структурированного кода, где нет ничего, что можно было было назвать "моделью предметной области". Опять-таки можно сказать что это простые примеры, но я не видел сложных примеров с ДДД, где везде хороший структурированный код.
Re[17]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 30.12.25 10:27
Оценка: +1
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


G>>Вы сейчас пытаетесь сказать, что не бывает хорошего структурированного кода без "модели предметной области"? Я еще раз повторю что это неправда, предлагаю перестать об этом говорить.


S>А какую проблему решает хороший код, если он даже не пытается моделировать предметную область, т.е. не оперирует необходимыми абстракциями?

1) Уменьшает дублирование кода
2) Уменьшает количество связей и сайд-эффектов
3) Уменьшает цепочку вызовов и количество промежуточных слоев между вызовов и действием
4) Увеличивает быстродействие
5) Уменьшает неявную передачу данных и изменение стояния
Это все вещи связанные, но в некоторых местах могут противоречить друг другу, поэтому хороший код это баланс.


S>По-моему, даже на не ООП языках типа С люди стараются оперировать абстракциями в коде.

Вы как-то слишком широко применяете слово "абстракция". Когда вы создаете класс с набором свойств это не абстракция. Реализация интерфейса это тоже не абстракция. Абстракция это то, что использует такие классы или интерфейсы. А писать такой код нет необходимости. Большинство полезных абстракций уже есть в библиотеках, зачастую стандартных.

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

S>Давайте, а то мне кажется мы говорим о разном, подразумевая "модель предметной области".
Начнем с простого, позже смогу вырезать кусок из реального проекта.
Недавно делал пример для статьи на Хабре https://github.com/gandjustas/habr-post-stock-api, АПИшка для резервации заказов, работает с базой, содержит очень важную для бизнеса логику. Это как маленький кусок большого приложения
Там даже есть абстракция — очередь запросов (она не шибко полезная в целом)

Что там является "моделью предметной области", в чем её ценность, и как она влияет на остальные части кода?
Re[18]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.01.26 01:37
Оценка: -1
Здравствуйте, Pauel, Вы писали:

G>>Обычно мертвый код выглядит как классы которые нигде не создаются, находятся тремя-четырьмя кликами в студии.


P>Необязательно. Чаще всего они могут создаться, вызываться итд по недостижимым путям. У вас нет абсолютно точного синтаксического анализатора, который выдаст всё на блюдечке — проблема останова мешает.

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


P>>>Это всё крайне растяжимое. У каждого своё видение, насколько глубоко это всё надо делать.

G>>Рамки задачи всегда можно сохранить. Просто задавай себе вопрос: "как это влияет на ту задачу, которую мне сейчас необходимо решить?". Если никак, то не надо этого делать.
P>Вы в слова играете. У каждого своё видение, что именно относится к задаче.
В итоге все сойдутся на мнении лида и оно станет одно.


G>>Кроме того, я изначально писал что нужно заниматься проектированием и программированием "сверху вниз", тогда контролировать скоуп несложно.

P>Это общие слова.
Это волне конкретный порядок действий, я не буду сюда очередной раз копипастить контент статьи.

P>>>Одна единственная задача это только краткосрочная перспектива.

G>>Это именно краткосрочная.
P>О чем я вам говорю, и это — проблема, т.к. все среднесрочные и долгосрочные цели вне фокуса.
И это хорошо. Требования часто меняются, будущее угадывать невозможно. Нет смысла ориентироваться на "долгосрочные" цели разрабатывая каждый блок функционала.


P>>>Пример — думали хватит чисто эндпоинта таскать из ui в базу и обратно, а после первого релиза вылезло такое...

G>>Ну так после первого релиза и поправьте. Никто ведь заранее не знал, что вылезет после релиза, а если бы пытались угадать, то вероятнее всего не угадали бы.
P>В этом и есть проектирование — выяснить, какие у вас цели, абы сделать, или глянуть чуть дальше, те самые среднесрочные-долгосрочные цели.
У меня есть эпичный пример на этот счет.
Был такой один проектировщик. Он даже ен ИТшник был, а фин менеджер. Проектировал процесс согласования. Говорил что должно быть строго три согласующих, потому что так уже 7 лет в компании было. И буквально на следующий день, как выпустили процесс, согласующих стало 2.
Как бы красиво не называли, это все попытка угадать будущее. И чаще всего люди не угадывают. Поэтому единственный универсальный способ — написать сегодня настолько мало, чтобы завтра было не жалко выкинуть.
Как только вы начинаете проектировать наперед, то создаете кучу ограничений и потом сложнее отказаться от написанного, ибо работает когнитивная ошибка невозвратных затрат, да и просто обосновать зачем столько делали становится сложнее.


P>>>Я вам уже привел пример Хорошее проектирование это не только здесь и сейчас, за что вы топите, но прежде всего и адеватный горизонт планирования.

G>>Практика показывает что занимаясь проектированием "только здесь и сейчас" почти всегда получается компактный код, который легко поддерживать.

P>Вам что бы обратную совместимость заложить в какое апи уже надо отойти от здесь и сейчас, а рассмотреть а что же вообще может или не может появиться.

Зачем нужна обратная совместимость?
1) если добавляется необязательное поле, то старый код продолжает работать
2) если поле обязательное, то старый код в любом случае сломается
3) если происходят более значимые изменения, то просто создается новый метод (возможно с номером версии в сегменте пути, querystring или заголовке)

P>Или вы предлагаете сначала сломать, а потом, если у когото утекут миллионы, завести тикет и начать фиксить?

Если задача создать новый метод не поломав старый, то она решается целиком. А не так, что сначала создается новый, а потом чинится старый. Некоторые изменения в системах должны быть атомарны — это и будет одна задача для одного программиста.
Re[19]: Что если не разделять строго dto, entity, bo...
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 02.01.26 12:41
Оценка: +1
Здравствуйте, gandjustas, Вы писали:

P>>Необязательно. Чаще всего они могут создаться, вызываться итд по недостижимым путям. У вас нет абсолютно точного синтаксического анализатора, который выдаст всё на блюдечке — проблема останова мешает.

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

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

P>>Вы в слова играете. У каждого своё видение, что именно относится к задаче.

G>В итоге все сойдутся на мнении лида и оно станет одно.

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

G>>>Это именно краткосрочная.

P>>О чем я вам говорю, и это — проблема, т.к. все среднесрочные и долгосрочные цели вне фокуса.
G>И это хорошо. Требования часто меняются, будущее угадывать невозможно. Нет смысла ориентироваться на "долгосрочные" цели разрабатывая каждый блок функционала

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

G>Как бы красиво не называли, это все попытка угадать будущее. И чаще всего люди не угадывают. Поэтому единственный универсальный способ — написать сегодня настолько мало, чтобы завтра было не жалко выкинуть.


Браво — у вас та самая попытка угадать будущее, предположение что всё нахрен не надо. Так себе идея. Обычно при проектировании учитывают как минимум известные риски. Например, закладывают некоторую ожидаемую нагрузку.
А если вас буквально воспринять, то такими глупостями вообще заниматься не надо. А что — пока проект не стартовал, нагрузка неизвестна.

P>>>>Я вам уже привел пример Хорошее проектирование это не только здесь и сейчас, за что вы топите, но прежде всего и адеватный горизонт планирования.

G>>>Практика показывает что занимаясь проектированием "только здесь и сейчас" почти всегда получается компактный код, который легко поддерживать.

Компактность слишком часто идет с невозможностью мейнтейнить, или хотя бы прочитать, проанализировать. Вы что, не видели проектов, которые раздувают до монстров однострочниками, никому не понятным метапрограммированием, срезанием углов и прочим мракобесием?
Я в недалёком прошлом выбросил просто чудовищную кучу кода как раз такого сорта — просто дропнул весь компактнейший всемогутор. И это вобщем довольно частый паттерн — "светило" пишет настолько компактно, что разве что компилятор с архиватором обогнать могут.
А вас почитать, это и есть наилучший вариант.

Как минимум, код должен быть поддерживаемым, читабельным, сопровождаемым. Иначе вы его даже выбросить не сможете, хоть и сильно-сильно захотите. А это именно то самое будущее которое, по вашему, никак не доступно, ужос-ужос.

P>>Вам что бы обратную совместимость заложить в какое апи уже надо отойти от здесь и сейчас, а рассмотреть а что же вообще может или не может появиться.

G>Зачем нужна обратная совместимость?
G>1) если добавляется необязательное поле, то старый код продолжает работать

Необязательно

G>2) если поле обязательное, то старый код в любом случае сломается


Необязательно

G>3) если происходят более значимые изменения, то просто создается новый метод (возможно с номером версии в сегменте пути, querystring или заголовке)


Необязательно

Вы шота держитесь за какой то свой вариант

G>Если задача создать новый метод не поломав старый, то она решается целиком. А не так, что сначала создается новый, а потом чинится старый. Некоторые изменения в системах должны быть атомарны — это и будет одна задача для одного программиста.


Важно не то, как вы будете создавать, а как вы будете деливерить. Многие вещи будут слишком большим изменением на одного программиста.
Что если не разделять строго dto, entity, bo...
От: Shmj Ниоткуда  
Дата: 28.11.25 17:47
Оценка:
Вопрос такой.

Вот, обычно делают слои и на уровне каждого слоя свои объект — для строгого разделения. А потом мапперы между слоями.

И у меня сейчас проект, который нужно дорабатывать. Там этой парадигмы разделения не придерживались строго, так что в ui проникают как dto, так и entity. Проект пока не большой, около 25 тыс. строк кода, т.е. за пару-тройку дней можно разделить и добавить мапперы.

Но задумался — а какие реальные бонусы? Вот что пишет зазнайка:

Если использовать DTO в Домене: Ваша бизнес-логика становится зависимой от API-контрактов. Если фронтенд попросит переименовать поле в JSON для удобства отображения, вам придется менять это поле в бизнес-логике, что может повлечь ошибки в расчетах. Внешний мир начинает диктовать правила внутреннему.

Если использовать Entity в Домене: Ваша бизнес-логика зависит от схемы базы данных. Если вы решите денормализовать таблицу для производительности или сменить PostgreSQL на MongoDB, вам придется переписывать бизнес-правила.

Правило архитектуры: Зависимости должны быть направлены внутрь. Слой Домена (бизнес-логика) должен быть самым стабильным и не зависеть ни от Базы Данных, ни от UI/API.


Но на практике вот что. Если что-то нужно добавить в UI — можно использовать расширения/mixin. И что? Никакой сложности не добавляет.

Если что-то изменилось в API — то один хрен нужно менять все слои. Но если добавилось новое поле и мы его не используем — то и в текущей схеме ничего не сломается.

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

Далее. Если добавим тесты и фейковые реализации сервисов — то что мешает в этих фейковых реализациях использовать уже существующие классы для объектов, ведь у них есть конструктор...

По этому как бы, получается, есть вера что нужно разделять — но нет реального смысла.
=сначала спроси у GPT=
Отредактировано 28.11.2025 17:53 Shmj . Предыдущая версия .
Re[2]: Что если не разделять строго dto, entity, bo...
От: Shmj Ниоткуда  
Дата: 29.11.25 07:11
Оценка:
Здравствуйте, Qulac, Вы писали:

S>>Правило архитектуры: Зависимости должны быть направлены внутрь. Слой Домена (бизнес-логика) должен быть самым стабильным и не зависеть ни от Базы Данных, ни от UI/API.

S>>[/q]
Q>Правильно. Еще БЛ — это центральное место приложения усилий при разработке. Здесь находится самый дорогой код, на него было потрачено сотни часов работы аналитика, здесь самые дорогие и долгоживущие баги.

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

Остальное у клиента — это практически дергание API и базы а так же синхронизация данных API, базы и UI.

Из частых проблем может быть — на форме обновили значение суммы (допустим) а в общем балансе забыли обновить — но это состояние приложения.

S>>Но на практике вот что. Если что-то нужно добавить в UI — можно использовать расширения/mixin. И что? Никакой сложности не добавляет.

Q>Можно и руками.

Я не о том что руками — вопрос в объектах. Что если не создавать ViewModel и даже не создавать business object для domain-слоя — а тупо в UI применять dto, который отдало API. В чем минус такого подхода?

Минус вижу один — не получится отвязать физически слои в разные библиотеки и тестировать из независимо. Но на практике это и не нужно, как бы это уникальный случай, когда над каждым слоем работает отдельный человек, а взаимодействие на основе контрактов.

S>>Если что-то изменилось в API — то один хрен нужно менять все слои. Но если добавилось новое поле и мы его не используем — то и в текущей схеме ничего не сломается.

Q>Ни чего не понял.

Ну если внешней сервис изменил имя поля в ответе — как то было WokrTime а стало WorkTime — один хрен, даже если ты создал dto, bo, entity — придется менять dto + в маппере dto->bo и скорее всего в маппере dto->entity. Это 3 изменения кода. Если не создавал отдельно bo — то сразу меняешь в dto и в ui — два изменения кода. Получается не создавать объекты + мапперы — меньше работы и нет особых минусов

S>>Если изменилась схема хранения данных, к примеру переименовали поле — то сейчас нужно в двух местах переименовать — в entity и в ui, где этот entity напрямую используется. Если добавим мапперы — легче не станет.

Q>Да хоть в 10 местах, что это меняет, откуда такая мания экономить на спичках?

Чем меньше монотонной работы — тем лучше. Всегда лучше изменить в одном месте чем 4 местах, ибо раздражает, тратится время. А плюс в чем?

S>>Далее. Если добавим тесты и фейковые реализации сервисов — то что мешает в этих фейковых реализациях использовать уже существующие классы для объектов, ведь у них есть конструктор...

Q>Зачем фейковые сервисы,если они только не являются сторонними к проекту. Фейковыми должны быть репозитории.

Так сервисы же есть внешние (которые связывают с API) и сервисы domain-слоя (бизнес логика). Можно мокать и внешние и бизнес слоя. Бизнес слойные сервисы мокают если хотят протестить один из сервисов, независимо от других — другие заменяют моками/фейками.

S>>По этому как бы, получается, есть вера что нужно разделять — но нет реального смысла.

Q>Ну не применяй.

Но все же хочется понять — почему принято делать 3 похожих типа объектов, если нет реальных плюсов:

1. dto — в виде, который отдает внешний сервис.
2. entity — в виде, который хранится в таблице базы данных.
3. business object — в виде, который представлен в бизнес-логике — domain-слое.
(4). Иногда добавляют view model — в виде, который отображается пользователю на форме.

+ еще и мапперы между каждым из слоев

Просто что всех так по учебникам учили?
=сначала спроси у GPT=
Re[3]: Что если не разделять строго dto, entity, bo...
От: Qulac Россия  
Дата: 29.11.25 08:03
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, Qulac, Вы писали:


S>>>Правило архитектуры: Зависимости должны быть направлены внутрь. Слой Домена (бизнес-логика) должен быть самым стабильным и не зависеть ни от Базы Данных, ни от UI/API.

S>>>[/q]
Q>>Правильно. Еще БЛ — это центральное место приложения усилий при разработке. Здесь находится самый дорогой код, на него было потрачено сотни часов работы аналитика, здесь самые дорогие и долгоживущие баги.

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


S>Остальное у клиента — это практически дергание API и базы а так же синхронизация данных API, базы и UI.


S>Из частых проблем может быть — на форме обновили значение суммы (допустим) а в общем балансе забыли обновить — но это состояние приложения.


S>>>Но на практике вот что. Если что-то нужно добавить в UI — можно использовать расширения/mixin. И что? Никакой сложности не добавляет.

Q>>Можно и руками.

S>Я не о том что руками — вопрос в объектах. Что если не создавать ViewModel и даже не создавать business object для domain-слоя — а тупо в UI применять dto, который отдало API. В чем минус такого подхода?


S>Минус вижу один — не получится отвязать физически слои в разные библиотеки и тестировать из независимо. Но на практике это и не нужно, как бы это уникальный случай, когда над каждым слоем работает отдельный человек, а взаимодействие на основе контрактов.


S>>>Если что-то изменилось в API — то один хрен нужно менять все слои. Но если добавилось новое поле и мы его не используем — то и в текущей схеме ничего не сломается.
Q>>Ни чего не понял.

S>Ну если внешней сервис изменил имя поля в ответе — как то было WokrTime а стало WorkTime — один хрен, даже если ты создал dto, bo, entity — придется менять dto + в маппере dto->bo и скорее всего в маппере dto->entity. Это 3 изменения кода. Если не создавал отдельно bo — то сразу меняешь в dto и в ui — два изменения кода. Получается не создавать объекты + мапперы — меньше работы и нет особых минусов


S>>>Если изменилась схема хранения данных, к примеру переименовали поле — то сейчас нужно в двух местах переименовать — в entity и в ui, где этот entity напрямую используется. Если добавим мапперы — легче не станет.

Q>>Да хоть в 10 местах, что это меняет, откуда такая мания экономить на спичках?

S>Чем меньше монотонной работы — тем лучше. Всегда лучше изменить в одном месте чем 4 местах, ибо раздражает, тратится время. А плюс в чем?


S>>>Далее. Если добавим тесты и фейковые реализации сервисов — то что мешает в этих фейковых реализациях использовать уже существующие классы для объектов, ведь у них есть конструктор...

Q>>Зачем фейковые сервисы,если они только не являются сторонними к проекту. Фейковыми должны быть репозитории.

S>Так сервисы же есть внешние (которые связывают с API) и сервисы domain-слоя (бизнес логика). Можно мокать и внешние и бизнес слоя. Бизнес слойные сервисы мокают если хотят протестить один из сервисов, независимо от других — другие заменяют моками/фейками.


S>>>По этому как бы, получается, есть вера что нужно разделять — но нет реального смысла.

Q>>Ну не применяй.

S>Но все же хочется понять — почему принято делать 3 похожих типа объектов, если нет реальных плюсов:


S>1. dto — в виде, который отдает внешний сервис.

S>2. entity — в виде, который хранится в таблице базы данных.
S>3. business object — в виде, который представлен в бизнес-логике — domain-слое.
S>(4). Иногда добавляют view model — в виде, который отображается пользователю на форме.

S>+ еще и мапперы между каждым из слоев


S>Просто что всех так по учебникам учили?



Еще раз повторю: проекты валятся не из-за того, что в 10 местах переменную переименовать нужно, а из-за того, что в БЛ в в том виде в котором она реализована, становится невозможно вносить изменения, а баги начинают жить вечно. Это вопрос собственно какую ценность мы выбираем: проект или код в котором не нужно менять в трех местах переменную. Это чисто "житейский" подход, что мы отделаем главное от не главного, а код здесь вторичен.


P.S. Я это видел на практике, один объект везде, что-то типа такого:

class Customer: Entity
{ 
   [NoMapper] - что это здесь делает?
   strring property{get;set;}

   DateTime DateTime {get;set;}

   string FomratDateTime
   {
     returt DatetTim.Format - //возвращаем в нужном формате
   }
}
Программа – это мысли спрессованные в код
Отредактировано 29.11.2025 8:10 Qulac . Предыдущая версия .
Re[4]: Что если не разделять строго dto, entity, bo...
От: Shmj Ниоткуда  
Дата: 29.11.25 09:23
Оценка:
Здравствуйте, Qulac, Вы писали:

Q>Еще раз повторю: проекты валятся не из-за того, что в 10 местах переменную переименовать нужно, а из-за того, что в БЛ в в том виде в котором она реализована, становится невозможно вносить изменения, а баги начинают жить вечно. Это вопрос собственно какую ценность мы выбираем: проект или код в котором не нужно менять в трех местах переменную. Это чисто "житейский" подход, что мы отделаем главное от не главного, а код здесь вторичен.


Давай на примерах рассмотрим.

Q>P.S. Я это видел на практике, один объект везде, что-то типа такого:

Q>

Q>class Customer: Entity
Q>{ 
Q>   [NoMapper] - что это здесь делает?
Q>   strring property{get;set;}

Q>   DateTime DateTime {get;set;}

Q>   string FomratDateTime
Q>   {
Q>     returt DatetTim.Format - //возвращаем в нужном формате
Q>   }
Q>}
Q>


Т.е. вам не нравится что в одном классе лишние поля, часть из которых не нужна для конкретного слоя? А что если добавить методы-расширения или mixin, чтобы нужные для конкретного слоя поля были в этом слое?
=сначала спроси у GPT=
Re[5]: Что если не разделять строго dto, entity, bo...
От: Qulac Россия  
Дата: 29.11.25 09:36
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, Qulac, Вы писали:


Q>>Еще раз повторю: проекты валятся не из-за того, что в 10 местах переменную переименовать нужно, а из-за того, что в БЛ в в том виде в котором она реализована, становится невозможно вносить изменения, а баги начинают жить вечно. Это вопрос собственно какую ценность мы выбираем: проект или код в котором не нужно менять в трех местах переменную. Это чисто "житейский" подход, что мы отделаем главное от не главного, а код здесь вторичен.


S>Давай на примерах рассмотрим.


Q>>P.S. Я это видел на практике, один объект везде, что-то типа такого:

Q>>

Q>>class Customer: Entity
Q>>{ 
Q>>   [NoMapper] - что это здесь делает?
Q>>   strring property{get;set;}

Q>>   DateTime DateTime {get;set;}

Q>>   string FomratDateTime
Q>>   {
Q>>     returt DatetTim.Format - //возвращаем в нужном формате
Q>>   }
Q>>}
Q>>


S>Т.е. вам не нравится что в одном классе лишние поля, часть из которых не нужна для конкретного слоя? А что если добавить методы-расширения или mixin, чтобы нужные для конкретного слоя поля были в этом слое?


А ради чего дрючиться, ради какой такой святой цели? Что бы с "оптимизировать" код который имеет низкую ценность и вообще ни на что не влияет?
А как быть с вот таким ответом из БЛ:

class CustomerCarTuple: ValueObject
{
  public Customer Customer {get;private set}

  public Car Car {get;private set}
}

//метод сервиса
public Ienumerable<CustomerCarTuple> GetCustomerCarReport()
{
  //
  returt ...
}

Программа – это мысли спрессованные в код
Re[6]: Что если не разделять строго dto, entity, bo...
От: Shmj Ниоткуда  
Дата: 29.11.25 09:43
Оценка:
Здравствуйте, Qulac, Вы писали:

Q>А ради чего дрючиться, ради какой такой святой цели? Что бы с "оптимизировать" код который имеет низкую ценность и вообще ни на что не влияет?


А зачем плодить лишние сущности? Вот в чем вопрос. Какой реальный смысл создавать одинаковые классы на каждом уровне и потом еще и маппить один в один?

Ну ОК, если совсем другая структура — то создай. А для всех случаев в чем смысл? Однообразно и безобразно?

Q>А как быть с вот таким ответом из БЛ:


Q>
Q>class CustomerCarTuple: ValueObject
Q>{
Q>  public Customer Customer {get;private set}

Q>  public Car Car {get;private set}
Q>}

Q>//метод сервиса
Q>public Ienumerable<CustomerCarTuple> GetCustomerCarReport()
Q>{
Q>  //
Q>  returt ...
Q>}
Q>

Q>

А в чем вопрос?
=сначала спроси у GPT=
Re[7]: Что если не разделять строго dto, entity, bo...
От: Qulac Россия  
Дата: 29.11.25 09:46
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, Qulac, Вы писали:


Q>>А ради чего дрючиться, ради какой такой святой цели? Что бы с "оптимизировать" код который имеет низкую ценность и вообще ни на что не влияет?


S>А зачем плодить лишние сущности? Вот в чем вопрос. Какой реальный смысл создавать одинаковые классы на каждом уровне и потом еще и маппить один в один?


S>Ну ОК, если совсем другая структура — то создай. А для всех случаев в чем смысл? Однообразно и безобразно?


Q>>А как быть с вот таким ответом из БЛ:


Q>>
Q>>class CustomerCarTuple: ValueObject
Q>>{
Q>>  public Customer Customer {get;private set}

Q>>  public Car Car {get;private set}
Q>>}

Q>>//метод сервиса
Q>>public Ienumerable<CustomerCarTuple> GetCustomerCarReport()
Q>>{
Q>>  //
Q>>  returt ...
Q>>}
Q>>

Q>>

S>А в чем вопрос?


Здесь в viewModel только маппинг нужен.
Программа – это мысли спрессованные в код
Re: Что если не разделять строго dto, entity, bo...
От: DiPaolo Россия  
Дата: 29.11.25 10:20
Оценка:
S>И у меня сейчас проект, который нужно дорабатывать. Там этой парадигмы разделения не придерживались строго, так что в ui проникают как dto, так и entity. Проект пока не большой, около 25 тыс. строк кода, т.е. за пару-тройку дней можно разделить и добавить мапперы.

Ну может оно и не надо? Тут надо оценить целесообразность и учесть:
— на каком этапе проект
— сколько денег приносит и сколько клиентов имеет
— объем доработок (+ в процентах к текущим LOC)
— единоразовая ли доработка
— как часто проект требует вмешательства в-принципе

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

S>Но на практике вот что. Если что-то нужно добавить в UI — можно использовать расширения/mixin. И что? Никакой сложности не добавляет.


S>Если что-то изменилось в API — то один хрен нужно менять все слои. Но если добавилось новое поле и мы его не используем — то и в текущей схеме ничего не сломается.


S>Если изменилась схема хранения данных, к примеру переименовали поле — то сейчас нужно в двух местах переименовать — в entity и в ui, где этот entity напрямую используется. Если добавим мапперы — легче не станет.


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

Давай на примерах:
— связка сервис <-> слой БД: ты захотел оптимизировать хранение и теперь хочешь хранить не доллары+центы, а доллары умноженные на 100. Если у тебя один общий объект, ты должен по всему коду в сервисе и в БД поменять 1 поле на два + всю связанную логику. Если два отдельных объекта: поменял только часть на стороне БД и живешь дальше спокойно
— связка REST API <-> сервис: ну тут вообще часто бывают изменения во внутренних сервисах, которые не должны никак затрагивать REST API, оставляя его неизменным. Например, пришла пора порефакторить внутри код и вынести какую-то логику в отдельный сервис. Вот у тебя информация об автомобиле приходила в одном объекте, а теперь есть отдельный сервис для хранения и расчетов по технической части. Тогда тебе надо, чтобы информация также и приходила в одном объекте через АПИ, а потом надо побить его на два объекта: каждый в свой сервис пойдет
— UI <-> REST API: тоже часто бывают изменения, например, когда сущности/элементы UI меняют свое название либо требуют отдельных полей для удобства работы. Ну например, был у тебя один элемент для тех же долларов+центов, ты его там строкой показывал. А теперь понадобилось сделать два отдельных элемента, да чтобы они еще и отдельно каждые могли изменяться пользователем. Сплетешь флоатинг филд, приходящий с РЕСТ АПИ, на два Филда по Инту на каждый и биндишь его к своим двум элементам управления на UI.

В целом, надо всегда думать головой и выбирать, что уместнее в каждом конкретном случае. Где-то и один и тот же объект удобнее таскать А где-то внутренние entity будут всегда жестко связаны с БД и быть один-в-один с таблицами/колонками.
Патриот здравого смысла
Re[7]: Что если не разделять строго dto, entity, bo...
От: Qulac Россия  
Дата: 29.11.25 10:32
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, Qulac, Вы писали:


Q>>А ради чего дрючиться, ради какой такой святой цели? Что бы с "оптимизировать" код который имеет низкую ценность и вообще ни на что не влияет?


S>А зачем плодить лишние сущности? Вот в чем вопрос. Какой реальный смысл создавать одинаковые классы на каждом уровне и потом еще и маппить один в один?


Вот опять вопрос понимания. Сущности сидят в БЛ, а тут нет сущностей, тут классы, просто так удобней. Вообще класс — это синтаксическая конструкция языка, а будет он сущностью или нет зависит от того, как мы им пользуемся.
Программа – это мысли спрессованные в код
Re[2]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.11.25 12:55
Оценка:
Здравствуйте, Qulac, Вы писали:

Q>Правильно. Еще БЛ — это центральное место приложения усилий при разработке. Здесь находится самый дорогой код, на него было потрачено сотни часов работы аналитика, здесь самые дорогие и долгоживущие баги.

Вы сейчас о чем говорите? Самая дорогая часть это UI. Туда обычно тратится больше всего времени аналитиков, дизайнеров, и разработчиков. Это касается и веба, где ui от бизнес-логики отделен http-вызовами, и десктоп приложений, где визуальное представление связано с логикой через viewmodel/presenter.

А на втором месте по объему затрат и кода занимает работа с базой и обеспечение согласованности.

Если вы отделяете работу с базой от БЛ, то что выполняется в БЛ после того как вы вытащили данные из базы и перед тем как отдали в UI?
Re[3]: Что если не разделять строго dto, entity, bo...
От: Qulac Россия  
Дата: 29.11.25 13:38
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, Qulac, Вы писали:


Q>>Правильно. Еще БЛ — это центральное место приложения усилий при разработке. Здесь находится самый дорогой код, на него было потрачено сотни часов работы аналитика, здесь самые дорогие и долгоживущие баги.

G>Вы сейчас о чем говорите? Самая дорогая часть это UI. Туда обычно тратится больше всего времени аналитиков, дизайнеров, и разработчиков. Это касается и веба, где ui от бизнес-логики отделен http-вызовами, и десктоп
приложений, где визуальное представление связано с логикой через viewmodel/presenter.

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

G>А на втором месте по объему затрат и кода занимает работа с базой и обеспечение согласованности.

Это почти все бизнес-логика, как и должно быть.

G>Если вы отделяете работу с базой от БЛ, то что выполняется в БЛ после того как вы вытащили данные из базы и перед тем как отдали в UI?


Преобразование к модели вида, т.е. данные отображения.
Программа – это мысли спрессованные в код
Re[2]: Что если не разделять строго dto, entity, bo...
От: Shmj Ниоткуда  
Дата: 29.11.25 13:45
Оценка:
Здравствуйте, gandjustas, Вы писали:

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


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

И что заказчику делать, если разработчик три дня исправляет простой баг а после исправления создает новый баг? Выгонять?

Ок, выгнал (а скорее тот сам ушел еще до того, как проблема стала очевидной). Берет нового — новый говорит что нужно все переписывать с нуля. Берет другого — тот делает вид что работает, месяц делает вид, два — говорит что еще разбирается в проекте. А потом начинает работать еще медленнее.
=сначала спроси у GPT=
Re[4]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.11.25 14:57
Оценка:
Здравствуйте, Qulac, Вы писали:

Q>Если это не про игры или какие ни будь с заказным навороченным дизайном — то это говорит о том, что кто-то как-то не правильно все делает.

Почему неправильно? Любой ui это много элементов и взаимодействий, а логика гораздо проще, ибо код stateless, а все «состояние» находится вовне.


Q>Преобразование к модели вида, т.е. данные отображения.

То есть то, что делает маппер?
Re[5]: Что если не разделять строго dto, entity, bo...
От: Qulac Россия  
Дата: 29.11.25 15:17
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, Qulac, Вы писали:


Q>>Если это не про игры или какие ни будь с заказным навороченным дизайном — то это говорит о том, что кто-то как-то не правильно все делает.

G>Почему неправильно? Любой ui это много элементов и взаимодействий, а логика гораздо проще, ибо код stateless, а все «состояние» находится вовне.

Если вы используете какую ни будь хорошую библиотеку для ui, то все практические превращается в банальное формошлебство — т.е. соединение одного с другим. Это если правильно делать. Приведу пример из практики как не правильно. Дано: штук 5 справочников к которым нужно приделать новый фронт на реакт + добавить возможность редактирования. Все уже для этого есть и компонеты и дизайн. Казалось бы делай вот так:

1. Получили из апи данные справочника
2. Загрузили из другого апи данные выпадающего списка
3. Отправили на апи результат из диалоговой формы
4. Перешли к другому справочнику

На фронтенду захотелось сделать универсальный для таких случаев способ, т.е. что бы один запрос возвращал json который описывает данные, поля, выпадающие списки и прочее что может быть в форме. В результате конечно полезли баги, а как это работает через неделю уже не вспомнишь. Вот на пустом месте сами себе создали проблему и дрючились. И такое где react и vue встречается довольно часто, т.е. люди сами себе усложняют задачу, зачем и ради какой цели — не понятно. И это только один пример у меня было еще хлеще.

Q>>Преобразование к модели вида, т.е. данные отображения.

G>То есть то, что делает маппер?

Нет, маппер к нужным видам приводит, их может быть несколько разных, бл возвращает данные такими какие они есть в бд.
Программа – это мысли спрессованные в код
Отредактировано 29.11.2025 15:17 Qulac . Предыдущая версия .
Re[6]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.11.25 17:09
Оценка:
Здравствуйте, Qulac, Вы писали:

Q>Здравствуйте, gandjustas, Вы писали:


G>>Здравствуйте, Qulac, Вы писали:


Q>>>Если это не про игры или какие ни будь с заказным навороченным дизайном — то это говорит о том, что кто-то как-то не правильно все делает.

G>>Почему неправильно? Любой ui это много элементов и взаимодействий, а логика гораздо проще, ибо код stateless, а все «состояние» находится вовне.

Q>Если вы используете какую ни будь хорошую библиотеку для ui, то все практические превращается в банальное формошлебство — т.е. соединение одного с другим. Это если правильно делать. Приведу пример из практики как не правильно. Дано: штук 5 справочников к которым нужно приделать новый фронт на реакт + добавить возможность редактирования. Все уже для этого есть и компонеты и дизайн. Казалось бы делай вот так:


Q>1. Получили из апи данные справочника

Q>2. Загрузили из другого апи данные выпадающего списка
Q>3. Отправили на апи результат из диалоговой формы
Q>4. Перешли к другому справочнику
То есть предлагаете копипастить кучи кода?

А что делать на нетривиальных формах?
— кода видимость/обязательность одних элементов зависит от значен у других?
— когда используются справочники, в том числе каскадные ?
— когда а одной форме есть mater-detail и логика работающая на всех detail записях?

На стороне бл это простое дерево объектов: получили, обновили из запроса, записали в базу.
А на стороне клиента это тонна логики

Q>На фронтенду захотелось сделать универсальный для таких случаев способ, т.е. что бы один запрос возвращал json который описывает данные, поля, выпадающие списки и прочее что может быть в форме. В результате конечно полезли баги, а как это работает через неделю уже не вспомнишь. Вот на пустом месте сами себе создали проблему и дрючились. И такое где react и vue встречается довольно часто, т.е. люди сами себе усложняют задачу, зачем и ради какой цели — не понятно. И это только один пример у меня было еще хлеще.

То есть вы против dry на клиенте, потому что создание повторно используемого кода это сложно?
Может на сервере делать также? Просто скопипастить код в контроллерах, и поменять запросы?

Q>>>Преобразование к модели вида, т.е. данные отображения.

G>>То есть то, что делает маппер?

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

Ну выглядит так, что именно это маппер и делает. В чем тогда заключается БЛ, если отделяем её от запросов?
Re[7]: Что если не разделять строго dto, entity, bo...
От: Qulac Россия  
Дата: 29.11.25 17:21
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, Qulac, Вы писали:


Q>>Здравствуйте, gandjustas, Вы писали:


G>>>Здравствуйте, Qulac, Вы писали:


Q>>>>Если это не про игры или какие ни будь с заказным навороченным дизайном — то это говорит о том, что кто-то как-то не правильно все делает.

G>>>Почему неправильно? Любой ui это много элементов и взаимодействий, а логика гораздо проще, ибо код stateless, а все «состояние» находится вовне.

Q>>Если вы используете какую ни будь хорошую библиотеку для ui, то все практические превращается в банальное формошлебство — т.е. соединение одного с другим. Это если правильно делать. Приведу пример из практики как не правильно. Дано: штук 5 справочников к которым нужно приделать новый фронт на реакт + добавить возможность редактирования. Все уже для этого есть и компонеты и дизайн. Казалось бы делай вот так:


Q>>1. Получили из апи данные справочника

Q>>2. Загрузили из другого апи данные выпадающего списка
Q>>3. Отправили на апи результат из диалоговой формы
Q>>4. Перешли к другому справочнику
G>То есть предлагаете копипастить кучи кода?

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

G>А что делать на нетривиальных формах?

G>- кода видимость/обязательность одних элементов зависит от значен у других?
G>- когда используются справочники, в том числе каскадные ?
G>- когда а одной форме есть mater-detail и логика работающая на всех detail записях?

Что делать, писать код.

G>На стороне бл это простое дерево объектов: получили, обновили из запроса, записали в базу.

G>А на стороне клиента это тонна логики

Q>>На фронтенду захотелось сделать универсальный для таких случаев способ, т.е. что бы один запрос возвращал json который описывает данные, поля, выпадающие списки и прочее что может быть в форме. В результате конечно полезли баги, а как это работает через неделю уже не вспомнишь. Вот на пустом месте сами себе создали проблему и дрючились. И такое где react и vue встречается довольно часто, т.е. люди сами себе усложняют задачу, зачем и ради какой цели — не понятно. И это только один пример у меня было еще хлеще.

G>То есть вы против dry на клиенте, потому что создание повторно используемого кода это сложно?

Оно просто не нужно.

G>Может на сервере делать также? Просто скопипастить код в контроллерах, и поменять запросы?


Q>>>>Преобразование к модели вида, т.е. данные отображения.

G>>>То есть то, что делает маппер?

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

G>Ну выглядит так, что именно это маппер и делает. В чем тогда заключается БЛ, если отделяем её от запросов?

Еще раз, видом у сущности может быть много, не пихать же каждый в бл, поэтому бл должна возвращать данные в каком — то одном виде, а уже потом это будет преобразоваться.
Программа – это мысли спрессованные в код
Re[2]: Что если не разделять строго dto, entity, bo...
От: Shmj Ниоткуда  
Дата: 29.11.25 18:08
Оценка:
Здравствуйте, DiPaolo, Вы писали:

DP>Давай на примерах:


а давай

DP>- связка сервис <-> слой БД: ты захотел оптимизировать хранение и теперь хочешь хранить не доллары+центы, а доллары умноженные на 100. Если у тебя один общий объект, ты должен по всему коду в сервисе и в БД поменять 1 поле на два + всю связанную логику. Если два отдельных объекта: поменял только часть на стороне БД и живешь дальше спокойно


Ну можно же 1 поле добавить для хранения а то что было ранее — сделать Transient (не хранится в базе) — а сразу вычисляется на основе нового поля, которое хранится в базе. Тогда 1 изменение и все. А вам с вашим разделением строгим — еще в маппере нужно менять, то есть 2 изменения против одного.

Получается код с единственным классом — выигрывает

DP>- связка REST API <-> сервис: ну тут вообще часто бывают изменения во внутренних сервисах, которые не должны никак затрагивать REST API, оставляя его неизменным. Например, пришла пора порефакторить внутри код и вынести какую-то логику в отдельный сервис. Вот у тебя информация об автомобиле приходила в одном объекте, а теперь есть отдельный сервис для хранения и расчетов по технической части. Тогда тебе надо, чтобы информация также и приходила в одном объекте через АПИ, а потом надо побить его на два объекта: каждый в свой сервис пойдет


Ну тут еще вот в чем дело. В этом проекте нет строгости — то есть для части объектов есть маппинг api object -> data enity. Когда это удобно — маппинг есть. Примерно в 40% случаев. Но только когда это имеет смысл.

Я же думаю над тем чтобы не решать имеет смысл или нет — а делать строгое разделение для всех случаев.

И сейчас пытаюсь понять плюсы и минусы.

Похоже что плюсов особо нет.

Т.е. еще раз. В этом проекте нет именно что строгой идеи — что будем делать только так. В одном месте для одного случая разделение объектов добавили — кое-где даже ViewModel есть. А в других случаях разделения нет и api object отображается прямо на форме.

DP>- UI <-> REST API: тоже часто бывают изменения, например, когда сущности/элементы UI меняют свое название либо требуют отдельных полей для удобства работы. Ну например, был у тебя один элемент для тех же долларов+центов, ты его там строкой показывал. А теперь понадобилось сделать два отдельных элемента, да чтобы они еще и отдельно каждые могли изменяться пользователем. Сплетешь флоатинг филд, приходящий с РЕСТ АПИ, на два Филда по Инту на каждый и биндишь его к своим двум элементам управления на UI.


Ну так можно же методы-расширения/mixin добавить для таких редких случаев. Т.е. оставляете тот же объект, но в отдельной папочке пишите extension — и добавляете поверх новые свойства.

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

DP>В целом, надо всегда думать головой и выбирать, что уместнее в каждом конкретном случае. Где-то и один и тот же объект удобнее таскать А где-то внутренние entity будут всегда жестко связаны с БД и быть один-в-один с таблицами/колонками.


Тут же нет запрета — хочешь создавай спец. объект для отдельного слоя.

Вопрос лишь вот в чем: если взять это за обязательное правило — то в чем плюсы?
=сначала спроси у GPT=
Re[6]: Что если не разделять строго dto, entity, bo...
От: Shmj Ниоткуда  
Дата: 30.11.25 06:55
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Это возможно если для реализации требований нужно менять верхние слои, при этом не трогая нижние . Но при разделением как рекомендует domain model или onion/hexagon/clean architecture это невозможно, так как почти каждое значимое изменение требований приведет к изменению не только представления, но и хранимых данных, и, соответственно, всех слове между ними.


Тут вот для чего. Если над каждым слоем работает свой человек — то без создания объектов на каждом уровне — они будут кивать друг на друга. Не могу сделать — слой данных еще не готов.

Когда же строгое разделение — тебе пофиг готов слой данных или не готов — забадяжил свои объекты, инициализировал фейковыми данными — проверил. Потом уже тот кто интегрирует и пишет мапперы протестирует с реальными данными.

А для реализации "не трогать нижние" — в Dart, к примеру, есть extension-свойства и методы.

https://dart.dev/language/extension-methods

И что, эта маленькая фича языка отменяет смысл создания объектов на каждом уровне? Т.е. если на твоем уровне чего-то не хватает — добавь расширения. Если всего хватает — ничего не добавляй.

S>>Других плюсов особо не видно. Т.е. если у вас нет строгого разделения труда — то нет смысла и в строгом разделении объектов. Но когда несколько человек работают над системой одновременно и каждый занимается своим слоем — появляется смысл все-же.

G>На практике удобнее не горизонтальное, а вертикальное деление. Например asp.net identity. Показывает как можно сделать отдельную функциональность, котрая содержит как работу с базой, так и часть представления, при этом достаточно хорошо кастомизируется и интегрируется с другими частями

Но при таком разделении нет смысла для каждого слоя во всех случаях (т.е. не берем отдельные случаи) клепать свои объекты и мапперы Но при этом нет смысла и запрещать — смотреть по ситуации. Иногда это имеет смысл а иногда нет.

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


G>Я, честно, не видел современных приложений построенных по такому принципу. За счет того что везде есть data binding проще иметь промежуточный объект, к которому привязывается форма, а внутри него уже дергать методы БЛ. А если мокать бл для объекта, то можно удобно тесты писать


Но что делать если не строго придерживаются этого правила и иногда прямо из обработчика события нажатия кнопки вызывают внешние сервисы

S>>Порядок. Вот в вещах порядок — можно все разложить по коробочкам (особенно поймут электронщики). А можно как бы не заморачиваться и все вывалить в одну большую кучу.

G>Если бы «раскладывание по коробочкам» было бесплатно, то все бы так делали. Но почему-то нет. См тот же asp.net identity

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

Но нужно подходить с умом — иногда, если в коробочке 1 деталь — то смысла нет.

S>>Когда тебе нужно найти деталь — то по коробочка найдешь сразу (при грамотном структурировании). А кучу нужно перебирать каждый раз с нуля.

G>Мне кажется это миф, все равно надо читать код и делать go to definition. И чем меньше кода и перекладываний объектов, тем проще. По крайней мере я на себе ни разу не замечал улучшение чтения от разделения.

При перекладывании объектов — тут да, смысла особо нет. А в других аспектах, как то строгое разделение на слои — смысл огромный.

S>>Но тогда ты просто перекладываешь проблему разработки и чистоты кода на чужие плечи. А проблема эта никуда не ушла. Лучше разберись сам и научить чистоте кода без привлечения посредников.

G>Далеко не каждый сам способен разобраться

Но речь то о тех, кто хочет маржу забрать себе — т.е. не нанимать команду а сам заняться разработкой. И часто такие люди, которые решили заниматься разработкой — не думают о качестве кода — смотрят только на реально сделанные фичи. Большое заблуждение.
=сначала спроси у GPT=
Re[3]: Что если не разделять строго dto, entity, bo...
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 30.11.25 16:10
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Если вы отделяете работу с базой от БЛ, то что выполняется в БЛ после того как вы вытащили данные из базы и перед тем как отдали в UI?


Сама бл в этом случае и есть то, что между чтением из бд и пулянием в ui
Отредактировано 01.12.2025 7:28 Pauel . Предыдущая версия .
Re[4]: Что если не разделять строго dto, entity, bo...
От: Shmj Ниоткуда  
Дата: 30.11.25 19:03
Оценка:
Здравствуйте, Pauel, Вы писали:

P>Сама бл в этом случае и есть то, что между чтением и бд и пулянием в ui


Между получением данных из API и DB — есть есть еще кеширование — но это в репозиториях, слой данных.

Логика — это когда есть состояние а разные сценарии, в зависимости от состояния. Т.е. if на неком состоянии.

Вот практически везде есть:

1. Логика авторизации, устаревания и обновления сессии, проверка актуальности ключа и при протухании/деактивации ключа — заново требовать авторизацию. Сюда же смена пользователя и пр.
2. Вызов по таймеру и отметка в базе о последнем успешном обновлении.
3. Логика оффлайн-режима. Т.е. перевести в состояние "оффлай", выдавать только старые данные, паттерн "короткое замыкание".

В общем то и все, обычно.

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

А так основная логика сейчас на стороне сервера, клиенты в основном только эти 3 пункта логики. Остальное — UI и кеширование.

Часто путают логику со слоем данных — т.е. называют логикой простое получение данных с кешированием.
=сначала спроси у GPT=
Отредактировано 30.11.2025 19:06 Shmj . Предыдущая версия .
Re[6]: Что если не разделять строго dto, entity, bo...
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 02.12.25 03:32
Оценка:
Здравствуйте, gandjustas, Вы писали:

S>>Здравствуйте, gandjustas, Вы писали:


В чём тогда серебряная пуля? Где граница применимости и как понять когда всё, приехали и "абстракции" давят и наоборот когда код превратился в набор спагетти? Все DDD, CA и т.п. было зря?
Sic luceat lux!
Re[7]: Что если не разделять строго dto, entity, bo...
От: Qulac Россия  
Дата: 02.12.25 05:51
Оценка:
Здравствуйте, Kernan, Вы писали:

K>Здравствуйте, gandjustas, Вы писали:


S>>>Здравствуйте, gandjustas, Вы писали:


K>В чём тогда серебряная пуля? Где граница применимости и как понять когда всё, приехали и "абстракции" давят и наоборот когда код превратился в набор спагетти? Все DDD, CA и т.п. было зря?


Тут нет ни какого другого способа, кроме как работать с моделью. Если ее смог создать у себя бизнес, то собственно и мы можем ее сделать в программной реализации. Для этого ее нужно отделить от обслуживающих ее слоев, что бы нам ни чего не мешало сосредотачиваться на ней. Общий подход, если простыми словами: все есть модель, а остальное — "обслуга" модели. И важно: мы тут еще отделяем проблемную часть, от не проблемной.
Программа – это мысли спрессованные в код
Re[8]: Что если не разделять строго dto, entity, bo...
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 02.12.25 06:35
Оценка:
Здравствуйте, Qulac, Вы писали:

Q>Тут нет ни какого другого способа, кроме как работать с моделью. Если ее смог создать у себя бизнес, то собственно и мы можем ее сделать в программной реализации. Для этого ее нужно отделить от обслуживающих ее слоев, что бы нам ни чего не мешало сосредотачиваться на ней. Общий подход, если простыми словами: все есть модель, а остальное — "обслуга" модели. И важно: мы тут еще отделяем проблемную часть, от не проблемной.

Ну кулстори, конечно. Делай хорошо и будет всё замечательно. Я не согласен с этим. Вот по своей практике у меня сложилось мнение, что основные задачи проектирования это снижение сложности и создания архитектуры устойчивой к изменению требований, в разумных пределах конечно же. Если первое можно решать созданием удобных для использования типов данных, ну например, currency и money, то второе сводится к натягиванию предметной области на код в виде абстракций с сложным разграничением ответственности м/д классами и подход к разработке архитектуры через наши любимые принципы, паттерны, СОЛИД, GRASP и т.п. Однако, тезисы Ганджустата как-то говорят о том, на мой взгляд, что домены это хорошо, но пиши как знаешь и проще, всё равно по метрикам на большом проекте это не даёт особого профита. Вот как быть?
Sic luceat lux!
Re[9]: Что если не разделять строго dto, entity, bo...
От: Qulac Россия  
Дата: 02.12.25 07:15
Оценка:
Здравствуйте, Kernan, Вы писали:

K>Здравствуйте, Qulac, Вы писали:


Q>>Тут нет ни какого другого способа, кроме как работать с моделью. Если ее смог создать у себя бизнес, то собственно и мы можем ее сделать в программной реализации. Для этого ее нужно отделить от обслуживающих ее слоев, что бы нам ни чего не мешало сосредотачиваться на ней. Общий подход, если простыми словами: все есть модель, а остальное — "обслуга" модели. И важно: мы тут еще отделяем проблемную часть, от не проблемной.

K>Ну кулстори, конечно. Делай хорошо и будет всё замечательно. Я не согласен с этим. Вот по своей практике у меня сложилось мнение, что основные задачи проектирования это снижение сложности и создания архитектуры устойчивой к изменению требований, в разумных пределах конечно же. Если первое можно решать созданием удобных для использования типов данных, ну например, currency и money, то второе сводится к натягиванию предметной области на код в виде абстракций с сложным разграничением ответственности м/д классами и подход к разработке архитектуры через наши любимые принципы, паттерны, СОЛИД, GRASP и т.п. Однако, тезисы Ганджустата как-то говорят о том, на мой взгляд, что домены это хорошо, но пиши как знаешь и проще, всё равно по метрикам на большом проекте это не даёт особого профита. Вот как быть?

Если он это подтвердит исследованиями, а так это его просто личное мнение.
Программа – это мысли спрессованные в код
Re[10]: Что если не разделять строго dto, entity, bo...
От: Shmj Ниоткуда  
Дата: 03.12.25 12:47
Оценка:
Здравствуйте, Pauel, Вы писали:

P>Например, у вас сервис работает с несколькими стораджами/провайдерами/итд, у всех разные дто.


Во! Кстати действительно веская причина — если одновременно несколько разных СУБД — тут да, нужны мапперы.
=сначала спроси у GPT=
Re[8]: Что если не разделять строго dto, entity, bo...
От: Qulac Россия  
Дата: 04.12.25 17:58
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, Kernan, Вы писали:


K>>Здравствуйте, gandjustas, Вы писали:


S>>>>Здравствуйте, gandjustas, Вы писали:


K>>В чём тогда серебряная пуля? Где граница применимости и как понять когда всё, приехали и "абстракции" давят и наоборот когда код превратился в набор спагетти? Все DDD, CA и т.п. было зря?



G>Ключевое прекрасно описано вот в этом посте: https://www.teamten.com/lawrence/programming/write-code-top-down.html


G>Процитирую основную мысль:

G>

G>Существует два подхода к проектированию программ и написанию кода: «сверху вниз» и «снизу вверх».

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

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

G>Правильный подход к проектированию и написанию программы — «сверху вниз». Это не вопрос вкуса или предпочтений. Подход «снизу вверх» в корне ошибочен, и его не следует использовать.


G>Если вы со старта проекта начинаете применять архитектурные паттерны, то вы фактически занимаетесь проектированием «снизу вверх».


G>

G>На каждом уровне существует стремление в программировании «снизу вверх». Избегайте этого. Вместо этого начните с верхнего уровня, с main() или его эквивалента, и пишите так, как будто все части уже написаны. Добейтесь правильного вида. Вставьте заглушки или хардкод отдельных частей пока не добьетесь компиляции и запуска. Затем медленно продвигайтесь вниз, стараясь максимально упростить все. Не пишите ни строчки кода, которая не решает проблему, с которой вы столкнулись прямо сейчас. Тогда у вас может появиться шанс написать большую, работоспособную и долговечную программу.


Clean Architecture не мешает разрабатывать в любом направлении. Вот TDD — подход с верху в низ, но работают здесь с моделью.
Программа – это мысли спрессованные в код
Re[9]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 04.12.25 18:24
Оценка:
Здравствуйте, Qulac, Вы писали:

Q>Clean Architecture не мешает разрабатывать в любом направлении.

Честно до сих пор не понимаю что такое CA.
Если я написал контроллер из которого вызвал EF и данные в базу записал это уже clean или еще нет?
Если мне для Clean Architecture еще что-то сделать, то это уже программирование «снизу вверх».
Re[10]: Что если не разделять строго dto, entity, bo...
От: Qulac Россия  
Дата: 04.12.25 18:39
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, Qulac, Вы писали:


Q>>Clean Architecture не мешает разрабатывать в любом направлении.

G>Честно до сих пор не понимаю что такое CA.
G>Если я написал контроллер из которого вызвал EF и данные в базу записал это уже clean или еще нет?
G>Если мне для Clean Architecture еще что-то сделать, то это уже программирование «снизу вверх».

Нет не CA. Лучше книжку почитать, самому поэкспериментировать.
Программа – это мысли спрессованные в код
Re[8]: Что если не разделять строго dto, entity, bo...
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 05.12.25 06:52
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Ключевое прекрасно описано вот в этом посте: https://www.teamten.com/lawrence/programming/write-code-top-down.html


Так себе статья. bottom up нужен в тех случаях, когда вы не знаете куда двигаться, и потому создаёте небольшие кирпичики, которые потом объединяете в компоненты.
В этом случае вы даже не знаете, какая архитектура будет через год.
И это нормально, есть на то причины.

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

G>Если вы со старта проекта начинаете применять архитектурные паттерны, то вы фактически занимаетесь проектированием «снизу вверх».


Накидывание паттернов к этим двум подходам никак не относится. Например, решили, что "у нас будут микросервисов 100 штук, свяжем через очередь, хз зачем, детали накинем позже"
Вот вам и top down, читаем вместе вашу же ссылку "With top-down design you start with a vision of the whole program, perhaps what some of the components are, and how they fit together, but the components themselves are still fuzzy. "
Re[9]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 05.12.25 07:31
Оценка:
Здравствуйте, Pauel, Вы писали:

P>В этом случае вы даже не знаете, какая архитектура будет через год.

Никто не знает какая архитектура будет через год. Все кто утверждает обратное — скорее всего просто заблуждаются

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

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

G>>Если вы со старта проекта начинаете применять архитектурные паттерны, то вы фактически занимаетесь проектированием «снизу вверх».

P>Накидывание паттернов к этим двум подходам никак не относится. Например, решили, что "у нас будут микросервисов 100 штук, свяжем через очередь, хз зачем, детали накинем позже"
Как это будет реально выглядеть?

Вот ты сделаешь file->new project... как из этого получится 100 микросервисов, чем они будут заниматься?

P>Вот вам и top down, читаем вместе вашу же ссылку "With top-down design you start with a vision of the whole program, perhaps what some of the components are, and how they fit together, but the components themselves are still fuzzy. "

Так прочитай внимательно что написано — "вы начинаете с представления о всей программе, возможно, о некоторых её компонентах". То есть не надо заранее придумать ВСЕ компоненты. Если ты заранее проектируешь компоненты, а потом из них что-то работающее собрать — это проектирование "снизу вверх"
Re[10]: Что если не разделять строго dto, entity, bo...
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 05.12.25 08:22
Оценка:
Здравствуйте, gandjustas, Вы писали:

P>>В этом случае вы даже не знаете, какая архитектура будет через год.

G>Никто не знает какая архитектура будет через год. Все кто утверждает обратное — скорее всего просто заблуждаются

Опаньки! И как же вы будете код сверху вниз писать не зная? Вам придется растить приложение архитектуру эволюционно, добавлять те или иные вещи по мере необходимости.

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

G>Откуда ты знаешь какая архитектура нужна на любом нетиповом проекте?
G>Понятно если если ты делаешь сайт-визитку, то они все плюс-минус одинаковые, и в принципы готовые решения-фреймворки есть, в рамках которых ты также двигаешься "сверху вниз".

Вы зачем то пересказываете то, что я вам сам же и сказал Вы читаете или только пишете?

P>>Накидывание паттернов к этим двум подходам никак не относится. Например, решили, что "у нас будут микросервисов 100 штук, свяжем через очередь, хз зачем, детали накинем позже"

G>Как это будет реально выглядеть?

G>Вот ты сделаешь file->new project... как из этого получится 100 микросервисов, чем они будут заниматься?


В вашей ссылке на это ответ "the components themselves are still fuzzy". Обычно это так выглядит "вот здесь будет сервис, но что он будет делать, решим потом"

P>>Вот вам и top down, читаем вместе вашу же ссылку "With top-down design you start with a vision of the whole program, perhaps what some of the components are, and how they fit together, but the components themselves are still fuzzy. "

G>Так прочитай внимательно что написано — "вы начинаете с представления о всей программе, возможно, о некоторых её компонентах". То есть не надо заранее придумать ВСЕ компоненты. Если ты заранее проектируешь компоненты, а потом из них что-то работающее собрать — это проектирование "снизу вверх"

Нету никакого проектирования компонентов, есть исключительно представление о всей программе целиком. Ни про один из компонентов нет внятного представления. То есть, ровно то, о чем в вашей ссылке.
Отредактировано 05.12.2025 10:00 Pauel . Предыдущая версия .
Re[8]: Что если не разделять строго dto, entity, bo...
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 05.12.25 08:42
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Ключевое прекрасно описано вот в этом посте: https://www.teamten.com/lawrence/programming/write-code-top-down.html

Ну так в CA про тоже написано.

G>Процитирую основную мысль:

G>

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

Не совсем понятно как это работает, если честно.

G>Если вы со старта проекта начинаете применять архитектурные паттерны, то вы фактически занимаетесь проектированием «снизу вверх».

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

G>

G>На каждом уровне существует стремление в программировании «снизу вверх». Избегайте этого.

Не совсем понятно как это работает в реальном мире. ibn4: оно не работает.
Sic luceat lux!
Re[12]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 05.12.25 16:10
Оценка:
Здравствуйте, Pauel, Вы писали:

P>Здравствуйте, gandjustas, Вы писали:


G>>Я говорил что надо уменьшить количество строк.


P>Смотрите сам, что вы пишете "кода с разделением и без и не код с разделением стабильно проигрывал"


Когда код делает +\- одно и то же и может быть написан без архитектурных паттернов, то по формальным метрикам он скорее всего превзойдет код с такими паттернами. Но я не исключаю, что могут быть случаи, когда паттерны реально уменьшают количество кода и\или улучшают потребительские характеристики системы. Но это надо в каждом конкретном случае оценивать, а не принимать как мантру, что DDD\CA\SOLID\GRASP\DICK это хорошо и обязательно надо делать.

G>>Во-первых

G>>Во-вторых
G>>В-третьих
G>>В-четвертых
G>>В-пятых

P>На примере 1 файл 1 main вам вроде бы понятно, какие последствия если отказаться от того самого разделения.

P>А вот с мапперами вам почему то непонятно
Потому что мапперы это не корень проблемы, а следствие. Если вам нужен маппер, то вероятно, что вы сильно ранее свернули не туда.

P>Любой концепт — класс, функция, интерфейс, итд, это то самое разделение.

P>Если бенефитов нет, см ваши "во-первых..." то добавление класса, функции, интерфейса, итд смысла не имеет. Мапперы, паттерны здесь ничего не меняют.
Еще раз:
1) Без разделения скорее всего кода станет больше
2) Иногда разделение необходимо для использования фреймворков и библиотек
3) Разделение нужно чтобы была навигация по коду. если у вас одна сплошная простыня текста на много экранов, то вы много времени тратить будете на навигацию.


P>А кто говорил, что надо заранее? Любое разделение обязанностей, см ваши пункты про main, нужно вводить вовремя. Слишком рано — утяжеляем и замедляем разработку. Слишком поздно — хаос.

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

P>А если изначально большую писать как маленькую, то есть чудовищно огромный шанс или утопить, или вырастить монстра, или убить весь бюджет на один только рефакторинг.

Вот что-то я такого не видел. Усложнять всегда просто, упрощать — сложно.

G>>Я всегда говорил, что нужно в каждый момент времени писать минимум кода для решения задачи, которая есть в данный момент. ИМХО в таких условиях вероятность появления domain model и DTO стремится вообще к нулю.

P>Ой да ладно. Вы подразумеваете какой то свой набор приложений-проектов. Озвучьте уже его.
Да любые корпоративные многопользовательские приложения.
Re[8]: Что если не разделять строго dto, entity, bo...
От: Shmj Ниоткуда  
Дата: 05.12.25 19:17
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Процитирую основную мысль:

G>

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


G>Если вы со старта проекта начинаете применять архитектурные паттерны, то вы фактически занимаетесь проектированием «снизу вверх».


Как раз нет — там же прямо написано "о программе в целом, возможно, о некоторых её компонентах и о том, как они взаимодействуют друг с другом". Т.е. реализации еще нет, а уже есть взаимодействие — это и есть паттерны.

То что вы предлагаете — сразу писать реализацию чтобы сразу работало не думая об архитектуре — и есть снизу вверх. Неужели не очевидно?
=сначала спроси у GPT=
Re[11]: Что если не разделять строго dto, entity, bo...
От: Shmj Ниоткуда  
Дата: 05.12.25 19:19
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Я всегда говорил, что нужно в каждый момент времени писать минимум кода для решения задачи, которая есть в данный момент. ИМХО в таких условиях вероятность появления domain model и DTO стремится вообще к нулю.


Тут вопрос — а если не продумали архитектуру и:

1. Можно решить задачу просто добавив 100 строк.
2. Можно убрать 10 тыс. лишних строк и добавить еще 500 строк.

Что выбрать?
=сначала спроси у GPT=
Re[12]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 05.12.25 19:58
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


G>>Я всегда говорил, что нужно в каждый момент времени писать минимум кода для решения задачи, которая есть в данный момент. ИМХО в таких условиях вероятность появления domain model и DTO стремится вообще к нулю.


S>Тут вопрос — а если не продумали архитектуру и:


S>1. Можно решить задачу просто добавив 100 строк.

S>2. Можно убрать 10 тыс. лишних строк и добавить еще 500 строк.

S>Что выбрать?


В этом случае конечно второе. Но это уже последствие.
Ведь кто-то изначально написал эти 10к ЛИШНИХ строк, потратив кучу времени и денег.
А если бы с самого начала не занимались этим, то вариант 2 не возник бы никогда.
Re[9]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 05.12.25 20:14
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


G>>Процитирую основную мысль:

G>>

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


G>>Если вы со старта проекта начинаете применять архитектурные паттерны, то вы фактически занимаетесь проектированием «снизу вверх».


S>Как раз нет — там же прямо написано "о программе в целом, возможно, о некоторых её компонентах и о том, как они взаимодействуют друг с другом". Т.е. реализации еще нет, а уже есть взаимодействие — это и есть паттерны.

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

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

Не очевидно почему эт "не думая об архитектуре". Нигде ведь не написано что не надо вообще применять паттерны, структурировать код итд.
Все что написано:
1) Напиши сначала вызывающий код, а потом вызываемый, не наоборот
2) Не пиши код, который не требуется для задачи, которую ты решаешь в данный момент
3) Пиши максимально простой код для решения задачи, например есть если ты можешь написать 10 строк, то не надо писать 100

Если что-то из этого мешает тебе думать об архитектуре?
Может то, что ты называешь архитектурой и есть тот самый bottom-up development, который мешает?
Re[11]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 05.12.25 20:22
Оценка:
Здравствуйте, Kernan, Вы писали:

K>Здравствуйте, gandjustas, Вы писали:


K>>>Со старта я начинаю собирать сценарии использования

G>>Сценарий использования это набор форм и или методов апи — создай эти формы\методы для начала
K>А лучше начать с тестов...
Чем лучше? Я вот сомневаюсь. Запускаемое работающие приложение лучше десятка "зеленых" тестов.
Конечно иногда запустить код сложно, поэтому нужны тесты, но это скорее костыль

G>>Повтори процедуру для других форм и методов. Устрани противоречия. Сделай рефакторинг, вынеси повторяющийся код в отдельные функции\классы. Только тут могут появиться простые паттерны GoF. До DDD и прочих архитектурных излишеств не дойдет если не пытаться решать задачи, которых нет.

K>Не получилось бы так, чтобы всё написанное не пришлось бы переписать полностью после неудачных решений по-месту.
Ну перепиши. Если ты написал 10 строк, то можешь их переписать на написать новые 10.
Это будет проще, че поменять 10 строк в эквивалентном коде на 100 строк со всякими паттернами итд.

Опять таки есть святая вера что если написать заранее больше, то потом придется писать и править меньше. Но нет, количество и сложность изменений прямо пропорциональны объему кода.

G>>Мне кажется программисты слишком заморочены на "модели предметной области", как-будто есть в этом ценность.

K>Проще работать с моделями и метафорами чем с набором примитивных типов.
За счет чего проще? Не является ли этой очередной популярной мантрой?
Если код структурирован, имеет хороший нейминг, высокую согласованность внутри классов и низкую связность между ними, придерживается SOLID, то какая по большому счету разница если нет набора классов, которые вы могли бы назвать "моделью предметной области"
Re[13]: Что если не разделять строго dto, entity, bo...
От: Shmj Ниоткуда  
Дата: 05.12.25 21:15
Оценка:
Здравствуйте, gandjustas, Вы писали:

S>>1. Можно решить задачу просто добавив 100 строк.

S>>2. Можно убрать 10 тыс. лишних строк и добавить еще 500 строк.

S>>Что выбрать?


G>В этом случае конечно второе. Но это уже последствие.


Тут вот в чем дело. Добавить 100 строк — проще, чем удалить 10 тыс. и добавить 500. Верно? Т.е. для бизнеса здесь и сейчас — лучше не перекраивать архитектуру а просто добавить 100 строк.

G>Ведь кто-то изначально написал эти 10к ЛИШНИХ строк, потратив кучу времени и денег.

G>А если бы с самого начала не занимались этим, то вариант 2 не возник бы никогда.

Вот по тому же принципу и было добавлено — проще не делать архитектуру, где будет минимум кода — а добавить очередной костыль побыряку.
=сначала спроси у GPT=
Re[10]: Что если не разделять строго dto, entity, bo...
От: Shmj Ниоткуда  
Дата: 05.12.25 22:05
Оценка:
Здравствуйте, gandjustas, Вы писали:

S>>Как раз нет — там же прямо написано "о программе в целом, возможно, о некоторых её компонентах и о том, как они взаимодействуют друг с другом". Т.е. реализации еще нет, а уже есть взаимодействие — это и есть паттерны.

G>Конечно, если он решают конкретную задачу, которая есть в данный момент. Если такой нет, то и паттерн никакой не нужен.

А какая может быть задача? Вот есть задача — разработать сервис. Кто-то продумал функционал. Что делать? Сделать кусочек работающего функционала, чтобы хотя бы одна страничка работала — или же сделать скелет, который охватывает все, но при этом ничего полезного не делает?
=сначала спроси у GPT=
Re[11]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 07.12.25 17:33
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


S>>>Как раз нет — там же прямо написано "о программе в целом, возможно, о некоторых её компонентах и о том, как они взаимодействуют друг с другом". Т.е. реализации еще нет, а уже есть взаимодействие — это и есть паттерны.

G>>Конечно, если он решают конкретную задачу, которая есть в данный момент. Если такой нет, то и паттерн никакой не нужен.

S>А какая может быть задача? Вот есть задача — разработать сервис. Кто-то продумал функционал. Что делать? Сделать кусочек работающего функционала, чтобы хотя бы одна страничка работала — или же сделать скелет, который охватывает все, но при этом ничего полезного не делает?

Речь всегда идет о решении задачи\проблемы пользователя.
Re[14]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 07.12.25 17:40
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


S>>>1. Можно решить задачу просто добавив 100 строк.

S>>>2. Можно убрать 10 тыс. лишних строк и добавить еще 500 строк.

S>>>Что выбрать?


G>>В этом случае конечно второе. Но это уже последствие.

S>Тут вот в чем дело. Добавить 100 строк — проще, чем удалить 10 тыс. и добавить 500. Верно? Т.е. для бизнеса здесь и сейчас — лучше не перекраивать архитектуру а просто добавить 100 строк.
Проще — да. Совокупный экономический эффект от удаления 9500 строк окажется выше. Возможно даже стоит разделить задачи — сначала удалить лишнее, а потом добавить 100 строк, которые решают задачу пользователя.


G>>Ведь кто-то изначально написал эти 10к ЛИШНИХ строк, потратив кучу времени и денег.

G>>А если бы с самого начала не занимались этим, то вариант 2 не возник бы никогда.

S>Вот по тому же принципу и было добавлено — проще не делать архитектуру, где будет минимум кода — а добавить очередной костыль побыряку.

Ты сам себе противоречишь.
1) Если когда-то было написано 10000 срок, которые сейчас можно удалить, то это были лишние строки еще в момент написания. Это значит кто-то отклонился от правила писать минимум строк для решения задачи.
2) Если эти сроки не были лишние в момент написания, но просто стали ненужными из-за изменения требований, то удалить их проблемы не представляет и надо это сделать.
3) Если строки нельзя просто удалить, потому что на них завязан другой код, но их удалить НУЖНО, то см п1
Re[12]: Что если не разделять строго dto, entity, bo...
От: Shmj Ниоткуда  
Дата: 07.12.25 18:20
Оценка:
Здравствуйте, gandjustas, Вы писали:

S>>А какая может быть задача? Вот есть задача — разработать сервис. Кто-то продумал функционал. Что делать? Сделать кусочек работающего функционала, чтобы хотя бы одна страничка работала — или же сделать скелет, который охватывает все, но при этом ничего полезного не делает?

G>Речь всегда идет о решении задачи\проблемы пользователя.

Пользователю нужен продукт, а чтобы сделать продукт — нужно решить множество задач.

Еще раз вопрос как вы поставите работу: сделаете 1 минимальную рабочую страницу/экран, который делает уже что-то. Либо же напишите скелет системы, который ничего не делает а просто как бы охватывает все без реализации? Это важный вопрос.
=сначала спроси у GPT=
Re[15]: Что если не разделять строго dto, entity, bo...
От: Shmj Ниоткуда  
Дата: 07.12.25 18:39
Оценка:
Здравствуйте, gandjustas, Вы писали:

S>>Тут вот в чем дело. Добавить 100 строк — проще, чем удалить 10 тыс. и добавить 500. Верно? Т.е. для бизнеса здесь и сейчас — лучше не перекраивать архитектуру а просто добавить 100 строк.

G>Проще — да. Совокупный экономический эффект от удаления 9500 строк окажется выше. Возможно даже стоит разделить задачи — сначала удалить лишнее, а потом добавить 100 строк, которые решают задачу пользователя.

Кто сказал что выше? Кому мешают лишние строки — ведь удалить — это работа. Оно же все завязано одно на другое — это не значит что просто взял и удалил вчистую.

G>>>Ведь кто-то изначально написал эти 10к ЛИШНИХ строк, потратив кучу времени и денег.

G>>>А если бы с самого начала не занимались этим, то вариант 2 не возник бы никогда.

S>>Вот по тому же принципу и было добавлено — проще не делать архитектуру, где будет минимум кода — а добавить очередной костыль побыряку.

G>Ты сам себе противоречишь.
G>1) Если когда-то было написано 10000 срок, которые сейчас можно удалить, то это были лишние строки еще в момент написания. Это значит кто-то отклонился от правила писать минимум строк для решения задачи.

Давай на примере, причем реальном. Вот, под некий язык нет библиотек для авто-генерации под SOAP. Что делать? Поискали — нету.

Нужно сделать задачу, задействовав несколько SOAP-методов. Проще руками. Раз и написал.

Далее, через год в проекте уже 1.9 Мб и 300+ файлов с ручными SOAP-обертками. Почему? Потому что каждый раз для решения задачи легче было написать несколько оберток вручную, чем выделить время для написания кодогенератора по WSDL.

И тут приходит Вася, пишет кодогенератор на 49 Кб — это значит все эти 1.9 Мб — можно выкинуть. Но кодогенератор имеет немалый код — 49 Кб. — писать не один день а скорее несколько дней, причем код сложнее чем тривиальный код обертки.

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

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

G>2) Если эти сроки не были лишние в момент написания, но просто стали ненужными из-за изменения требований, то удалить их проблемы не представляет и надо это сделать.


Представляет проблему — т.к. вручную написанные обертки отличаются от тех, что будут сгенерены автоматом — там свои именования (чуть другие), свои методы для enum и т.д. Т.е. огромный кусок работы — пока решено оставить как есть, хотя генератор все генерит за секунду и писать не нужно.

G>3) Если строки нельзя просто удалить, потому что на них завязан другой код, но их удалить НУЖНО, то см п1


Но бизнесу это не даст бонусов, т.к. написанное вручную уже более-менее работает.
=сначала спроси у GPT=
Re[15]: Что если не разделять строго dto, entity, bo...
От: Shmj Ниоткуда  
Дата: 07.12.25 19:48
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Если хорошо натренировать всегда выдавать максимально простой код, то это будет сильно быстрее, чем то, что фигачат DDD-программисты и всякие ИИ. Потому что есть предел количества строк отлаженного продуктивного кода, который может выдавать программист в единицу времени. И он почти не зависит ни от языка, ни от архитектуры.


Тут вот в чем проблема. На начальном этапе проще код написанный в лоб. Когда проект уже вырос — получается что первоначальная стратегия уже не годится, что лучше подойти с умом.
=сначала спроси у GPT=
Re[16]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 08.12.25 07:26
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


S>>>Тут вот в чем дело. Добавить 100 строк — проще, чем удалить 10 тыс. и добавить 500. Верно? Т.е. для бизнеса здесь и сейчас — лучше не перекраивать архитектуру а просто добавить 100 строк.

G>>Проще — да. Совокупный экономический эффект от удаления 9500 строк окажется выше. Возможно даже стоит разделить задачи — сначала удалить лишнее, а потом добавить 100 строк, которые решают задачу пользователя.

S>Кто сказал что выше? Кому мешают лишние строки — ведь удалить — это работа. Оно же все завязано одно на другое — это не значит что просто взял и удалил вчистую.

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

G>>>>Ведь кто-то изначально написал эти 10к ЛИШНИХ строк, потратив кучу времени и денег.

G>>>>А если бы с самого начала не занимались этим, то вариант 2 не возник бы никогда.

S>Давай на примере, причем реальном. Вот, под некий язык нет библиотек для авто-генерации под SOAP. Что делать? Поискали — нету.

S>Нужно сделать задачу, задействовав несколько SOAP-методов. Проще руками. Раз и написал.
Допустим. У тебя как минимум появится код, который делает сериализацию-десериализацию в SOAP, который может быть обобщен, так как не зависит от сервисов. Для первой обертки это конечно не имеет смысла.

S>Далее, через год в проекте уже 1.9 Мб и 300+ файлов с ручными SOAP-обертками. Почему? Потому что каждый раз для решения задачи легче было написать несколько оберток вручную, чем выделить время для написания кодогенератора по WSDL.

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


S>И тут приходит Вася, пишет кодогенератор на 49 Кб — это значит все эти 1.9 Мб — можно выкинуть. Но кодогенератор имеет немалый код — 49 Кб. — писать не один день а скорее несколько дней, причем код сложнее чем тривиальный код обертки.

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

И естественно оно все никак не связно с задачей добавления нового функционала.

S>Т.е. нужно не просто быстро решить текущую задачу — а понимать масштабы проекта и видеть на несколько шагов вперед.

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

G>>2) Если эти сроки не были лишние в момент написания, но просто стали ненужными из-за изменения требований, то удалить их проблемы не представляет и надо это сделать.

S>Представляет проблему — т.к. вручную написанные обертки отличаются от тех, что будут сгенерены автоматом — там свои именования (чуть другие), свои методы для enum и т.д. Т.е. огромный кусок работы — пока решено оставить как есть, хотя генератор все генерит за секунду и писать не нужно.
Если у вас генератор не поддерживает мэппинг на существующие классы, то вы с высокой вероятностью не откажетесь от самописных оберток.
Но суть проблемы это не меняет. Ваши мегабайты говнокода появились именно потому, что программисты не следовали правилу создавать максимально простое решение в каждый момент времени.

G>>3) Если строки нельзя просто удалить, потому что на них завязан другой код, но их удалить НУЖНО, то см п1

S>Но бизнесу это не даст бонусов, т.к. написанное вручную уже более-менее работает.
Поэтому в реальности такой замены не будет, видел это несколько раз. Замена будет тогда, когда SOAP сменится на какой-нибудь rest и править мегабайты самописных оберток станет невозможно, тогда просто выкинут старое и возьмут генератор.
Re[16]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 08.12.25 07:29
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


G>>Если хорошо натренировать всегда выдавать максимально простой код, то это будет сильно быстрее, чем то, что фигачат DDD-программисты и всякие ИИ. Потому что есть предел количества строк отлаженного продуктивного кода, который может выдавать программист в единицу времени. И он почти не зависит ни от языка, ни от архитектуры.


S>Тут вот в чем проблема.

В чем?

S>На начальном этапе проще код написанный в лоб.

Никто не спорит.

S>Когда проект уже вырос — получается что первоначальная стратегия уже не годится, что лучше подойти с умом.

Звучит как-будто вы вчера писали все в одном файле в main, а сегодня у вас 100500 сервисов\проектов\классов\файлов.
Это может случится если вайб-кодить, но если писать руками, то развитие идет постепенно. На второй или максимум третьей однотипной задаче код получится легче если провести небольшой рефакторинг и вынести общие куски.
Re[17]: Что если не разделять строго dto, entity, bo...
От: Shmj Ниоткуда  
Дата: 08.12.25 18:32
Оценка:
Здравствуйте, gandjustas, Вы писали:

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


Вот в том то и проблема — никто не знает заранее как приложение получится проще. А когда уже написано — то на текущий момент нет времени переписывать — т.к. нужен ежедневный результат и текучка задач от бизнеса — на рефакторинг и приведение в порядок уже нет времени обычно.

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


Не нашли. Кто-то понял что так будет проще и взял и написал, вместо того чтобы ждать пока до других это дойдет.
=сначала спроси у GPT=
Re[17]: Что если не разделять строго dto, entity, bo...
От: Shmj Ниоткуда  
Дата: 08.12.25 18:33
Оценка:
Здравствуйте, gandjustas, Вы писали:

S>>Когда проект уже вырос — получается что первоначальная стратегия уже не годится, что лучше подойти с умом.

G>Звучит как-будто вы вчера писали все в одном файле в main, а сегодня у вас 100500 сервисов\проектов\классов\файлов.
G>Это может случится если вайб-кодить, но если писать руками, то развитие идет постепенно. На второй или максимум третьей однотипной задаче код получится легче если провести небольшой рефакторинг и вынести общие куски.

К сожалению так не работает. Архитектура должна быть изначально — иначе потом переделывать под другую архитектуру будет слишком дорого и не будет времени.
=сначала спроси у GPT=
Re[17]: Что если не разделять строго dto, entity, bo...
От: Shmj Ниоткуда  
Дата: 09.12.25 07:42
Оценка:
Здравствуйте, gandjustas, Вы писали:

S>>И тут приходит Вася, пишет кодогенератор на 49 Кб — это значит все эти 1.9 Мб — можно выкинуть. Но кодогенератор имеет немалый код — 49 Кб. — писать не один день а скорее несколько дней, причем код сложнее чем тривиальный код обертки.

G>Допустим это не вася, а просто нашли готовую реализацию генератора.

Вот на этом примере и открывается главная ваша проблема.

Вы не смотрите в будущее.

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

А если нет халявы и нужно принять решение? Нужно написать генератор кода по WSDL, который охватит все API используемые (по стандарту не требуется — пусть работает только для наших API + возможность доработки, кода чего-то не хватает) — кто будет оценивать сколько строк кода и насколько сложно это написать??? Кто будет оценивать стоит ли игра свеч???

Вот это и есть самое сложное — и никто точно не может сказать как лучше, как проще
=сначала спроси у GPT=
Re[13]: Что если не разделять строго dto, entity, bo...
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 10.12.25 14:10
Оценка:
Здравствуйте, gandjustas, Вы писали:

S>>Что выбрать?


G>В этом случае конечно второе. Но это уже последствие.

G>Ведь кто-то изначально написал эти 10к ЛИШНИХ строк, потратив кучу времени и денег.
G>А если бы с самого начала не занимались этим, то вариант 2 не возник бы никогда.

Сомнительно. Если предположить, что разработчик был добросовестным, то 10к лишних строк появились по простой причине
1 появились требования
2 появилось решение с учетом всех целей и приоритетов того времени
3 требования поменялись, возможно, несколько раз
4 "инвентаризацию" отложили на потом т.к. были другие приоритеты

Это ведь только у джуна одна единственная цель "что бы работало". Обычно же есть множество сопутствующих целей. И решение должно достигать все актуальные цели. Потому и кода получается больше, чем просто "что бы работало"

Например, можно точечно поправить условие, это приведет к тому, что следующие N фиксов у других разработчиков будут заканчиваться неудачами. Так мины обычно и закладываются — находишь однострочник, а потом по всему коду попытки купировать, то тут, то там.
Re[13]: Что если не разделять строго dto, entity, bo...
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 29.12.25 10:18
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>В этом случае конечно второе. Но это уже последствие.

G>Ведь кто-то изначально написал эти 10к ЛИШНИХ строк, потратив кучу времени и денег.
G>А если бы с самого начала не занимались этим, то вариант 2 не возник бы никогда.

Почему обязательно лишних, и потратив кучу времени и денег? Может оказаться что всё ровно наоборот.

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

То есть, чаще всего вот эти "лишние" строки становятся такими только со временем. Это если отказаться от варианта "все дураки"

Поэтому вопрос в том, какая у нас перстпектива в проектировании:
Если краткосрочная, "главное сделаить", тогда нужно строчить, копипастить и срезать углы, или просто лепить однострочники абы кода было поменьше.
Или же среднесрочная-долгосрочная, тогда нужно определиться какие же актуальные цели кроме "главное сделать".

Например, реанимировать проект краткосрочными интервенциями "главное сделать" не получится. Скорее всего, он именно и зашел в тупик благодаря "главное сделать".
Re[10]: Что если не разделять строго dto, entity, bo...
От: Sharov Россия  
Дата: 29.12.25 11:36
Оценка:
Здравствуйте, gandjustas, Вы писали:

K>>и через них выхожу на модели предметной области, алгоритмы и т.п.

G>Мне кажется программисты слишком заморочены на "модели предметной области", как-будто есть в этом ценность.

Внезапно программисты получают деньги не за то, что они есть, а за то, что решают бизнес проблемы заказчика.
И вот, чтобы как можно легче, проще и быстрее решать эти проблемы и появились всякие модели предметной области и DDD.
Кодом людям нужно помогать!
Re[12]: Что если не разделять строго dto, entity, bo...
От: Sharov Россия  
Дата: 29.12.25 12:01
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>За счет чего проще? Не является ли этой очередной популярной мантрой?

G>Если код структурирован, имеет хороший нейминг, высокую согласованность внутри классов и низкую связность между ними, придерживается SOLID, то какая по большому счету разница если нет набора классов, которые вы могли бы назвать "моделью предметной области"

Считается, что первое достигается при помощи второго.
Кодом людям нужно помогать!
Re[15]: Что если не разделять строго dto, entity, bo...
От: Sharov Россия  
Дата: 29.12.25 12:15
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Если хорошо натренировать всегда выдавать максимально простой код, то это будет сильно быстрее, чем то, что фигачат DDD-программисты и всякие ИИ. Потому что есть предел количества строк отлаженного продуктивного кода, который может выдавать программист в единицу времени. И он почти не зависит ни от языка, ни от архитектуры.


Я ни разу не апологет DDD, ни одной (пока) книги не прочитал, хотя тему изучал. Так вот, люди его не зря ценят, начиная от определенного объема
сложности, если архитектура спроектирована с учетом DDD, банально проще и быстрее расширять, вносить изменения и т.п. Но это дает свои плоды
при определенных объемах задачи\предметной области, т.е. много человеколет.
Кодом людям нужно помогать!
Re[11]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.12.25 13:24
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


K>>>и через них выхожу на модели предметной области, алгоритмы и т.п.

G>>Мне кажется программисты слишком заморочены на "модели предметной области", как-будто есть в этом ценность.

S>Внезапно программисты получают деньги не за то, что они есть, а за то, что решают бизнес проблемы заказчика.

И? как это связано с "моделью предметной области"? Я не улавливаю.

S>И вот, чтобы как можно легче, проще и быстрее решать эти проблемы и появились всякие модели предметной области и DDD.

Слишком мало примеров когда они что-то упрощают и слишком много примеров, когда они что-то усложняют.
Re[13]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.12.25 13:26
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


G>>За счет чего проще? Не является ли этой очередной популярной мантрой?

G>>Если код структурирован, имеет хороший нейминг, высокую согласованность внутри классов и низкую связность между ними, придерживается SOLID, то какая по большому счету разница если нет набора классов, которые вы могли бы назвать "моделью предметной области"

S>Считается, что первое достигается при помощи второго.

Не понимаю логики:
1) считается что без "модели предметной области" не бывает хорошей структуры кода? Это мягко говоря неправда
2) считается что наличие "модели предметной области" всегда приводит к хорошей структуре? Это еще большая неправда
Re[12]: Что если не разделять строго dto, entity, bo...
От: Sharov Россия  
Дата: 29.12.25 14:03
Оценка:
Здравствуйте, gandjustas, Вы писали:

S>>Внезапно программисты получают деньги не за то, что они есть, а за то, что решают бизнес проблемы заказчика.

G>И? как это связано с "моделью предметной области"? Я не улавливаю.

Без понимания и выработки соотв. абстракций решать проблемы будет крайне затруднительно.

S>>И вот, чтобы как можно легче, проще и быстрее решать эти проблемы и появились всякие модели предметной области и DDD.

G>Слишком мало примеров когда они что-то упрощают и слишком много примеров, когда они что-то усложняют.

Это факт. Это, кмк, нужно для больших, типа банковских и т.п., сервисов и приложений. Но по отдельности и некоторые компоненты DDD можно
использовать -- ubitiquos language, bounded context и т.п. Но тут тогда уж проще следовать методологии целиком, а не по кускам выдергивать.
Мож не взлетает именно из-за кусочничества .
Кодом людям нужно помогать!
Re[14]: Что если не разделять строго dto, entity, bo...
От: Sharov Россия  
Дата: 29.12.25 14:04
Оценка:
Здравствуйте, gandjustas, Вы писали:


S>>Считается, что первое достигается при помощи второго.

G>Не понимаю логики:
G>1) считается что без "модели предметной области" не бывает хорошей структуры кода? Это мягко говоря неправда
G>2) считается что наличие "модели предметной области" всегда приводит к хорошей структуре? Это еще большая неправда

Понимание модели предметной области помогает достигать качественного кода -- все по папочка и т.п., а не в одном большом
методе main.
Кодом людям нужно помогать!
Re[15]: Что если не разделять строго dto, entity, bo...
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 29.12.25 14:16
Оценка:
Здравствуйте, gandjustas, Вы писали:

P>>То есть, чаще всего вот эти "лишние" строки становятся такими только со временем. Это если отказаться от варианта "все дураки"

G>Тогда в чем проблема удалить код, который вообще не используется? Это же требует примерно 0 усилий.

Как вы это представляете, каждая строка сама напишет в Slack "репозиторий-путь-файл-номер, можно удалять?"

Мертвый код сначаоа нужно идентифицировать. Чаще всего он просто выглядт, как живой код.

G>Проблема удаления кода возникает когда он используется, на него много зазвано.


Необязательно. Куда чаще мертвый код просто выглядит как живой и работающий, хотя нигде не вызывается или же его вызовы заканчиваются сразу на старте if (disabled) return;

G>То есть сначала делаем "главное чтобы заработало", потом устраняем ошибки в corner cases, очевидные code smells, вписываем в сущствующую архитектуру, делаем оптимальным.


Это всё крайне растяжимое. У каждого своё видение, насколько глубоко это всё надо делать.

G>Главное фокусироваться на одной задаче, а не заниматься проектированием системы. То есть не трогать ничего, что напрямую не касается данной задачи.


Это общие слова. Одна единственная задача это только краткосрочная перспектива. Пример — думали хватит чисто эндпоинта таскать из ui в базу и обратно, а после первого релиза вылезло такое...

P>>Например, реанимировать проект краткосрочными интервенциями "главное сделать" не получится. Скорее всего, он именно и зашел в тупик благодаря "главное сделать".

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

Я вам уже привел пример Хорошее проектирование это не только здесь и сейчас, за что вы топите, но прежде всего и адеватный горизонт планирования.

На одном проекте горизонт это день, на другом — год. В первом случае вам абы результат показать, а во втором у вас наверняка появятся всевозможные особенности maintainability. И если вы попутаете кейсы, и во втором проекте начнете струячить, как на первом, хаос будет бежать впереди вас.
Re[13]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.12.25 15:32
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


S>>>Внезапно программисты получают деньги не за то, что они есть, а за то, что решают бизнес проблемы заказчика.

G>>И? как это связано с "моделью предметной области"? Я не улавливаю.

S>Без понимания и выработки соотв. абстракций решать проблемы будет крайне затруднительно.

Честно не понимаю о чем речь. Давайте возьмём например разработку форума. Какие абстракции для этого нужно создать? Того что предлагает .NET FW недостаточно?


S>>>И вот, чтобы как можно легче, проще и быстрее решать эти проблемы и появились всякие модели предметной области и DDD.

G>>Слишком мало примеров когда они что-то упрощают и слишком много примеров, когда они что-то усложняют.

S>Это факт. Это, кмк, нужно для больших, типа банковских и т.п., сервисов и приложений. Но по отдельности и некоторые компоненты DDD можно

S>использовать -- ubitiquos language, bounded context и т.п. Но тут тогда уж проще следовать методологии целиком, а не по кускам выдергивать.
S>Мож не взлетает именно из-за кусочничества .
Тем не менее не видел примеров где БОЛЬШЕ ДДД делает код лучше, чем когда МЕНЬШЕ ДДД.
Может это какие-то слишком простые примеры были, но где взять сложные, чтобы можно было сравнивать подходы?
Re[16]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.12.25 15:46
Оценка:
Здравствуйте, Pauel, Вы писали:

P>Здравствуйте, gandjustas, Вы писали:


P>>>То есть, чаще всего вот эти "лишние" строки становятся такими только со временем. Это если отказаться от варианта "все дураки"

G>>Тогда в чем проблема удалить код, который вообще не используется? Это же требует примерно 0 усилий.

P>Как вы это представляете, каждая строка сама напишет в Slack "репозиторий-путь-файл-номер, можно удалять?"

P>Мертвый код сначаоа нужно идентифицировать. Чаще всего он просто выглядт, как живой код.
Давайте считать что мертвый код уже был идентифицирован, ибо если нет, то о чем разговор?

G>>Проблема удаления кода возникает когда он используется, на него много зазвано.

P>Необязательно. Куда чаще мертвый код просто выглядит как живой и работающий, хотя нигде не вызывается или же его вызовы заканчиваются сразу на старте if (disabled) return;
Обычно мертвый код выглядит как классы которые нигде не создаются, находятся тремя-четырьмя кликами в студии.
Мы же говорим о тысячах строк такого кода, вряд ли это будет в таких ифах.

G>>То есть сначала делаем "главное чтобы заработало", потом устраняем ошибки в corner cases, очевидные code smells, вписываем в сущствующую архитектуру, делаем оптимальным.

P>Это всё крайне растяжимое. У каждого своё видение, насколько глубоко это всё надо делать.
Рамки задачи всегда можно сохранить. Просто задавай себе вопрос: "как это влияет на ту задачу, которую мне сейчас необходимо решить?". Если никак, то не надо этого делать.
Кроме того, я изначально писал что нужно заниматься проектированием и программированием "сверху вниз", тогда контролировать скоуп несложно.

G>>Главное фокусироваться на одной задаче, а не заниматься проектированием системы. То есть не трогать ничего, что напрямую не касается данной задачи.

P>Это общие слова.
Вполне конкретные.

P>Одна единственная задача это только краткосрочная перспектива.

Это именно краткосрочная.

P>Пример — думали хватит чисто эндпоинта таскать из ui в базу и обратно, а после первого релиза вылезло такое...

Ну так после первого релиза и поправьте. Никто ведь заранее не знал, что вылезет после релиза, а если бы пытались угадать, то вероятнее всего не угадали бы.


P>>>Например, реанимировать проект краткосрочными интервенциями "главное сделать" не получится. Скорее всего, он именно и зашел в тупик благодаря "главное сделать".

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

P>Я вам уже привел пример Хорошее проектирование это не только здесь и сейчас, за что вы топите, но прежде всего и адеватный горизонт планирования.

Практика показывает что занимаясь проектированием "только здесь и сейчас" почти всегда получается компактный код, который легко поддерживать. Как только пытаешься проектировать "наперед" появляется херня которая потом тянет назад, или просто зря тратишь время.
Особенно плохо если "каркас" приложения пишет "архитектор", а рядовые разрабы пытаются впихнуть в эти рамки свою логику, не имея возможности поменять неудобные места.
Re[14]: Что если не разделять строго dto, entity, bo...
От: Sharov Россия  
Дата: 30.12.25 08:53
Оценка:
Здравствуйте, gandjustas, Вы писали:

S>>Без понимания и выработки соотв. абстракций решать проблемы будет крайне затруднительно.

G>Честно не понимаю о чем речь. Давайте возьмём например разработку форума. Какие абстракции для этого нужно создать? Того что предлагает .NET FW недостаточно?

Ну, например, абстракция "Запись" или "Пользователь". Когда какой-то пользователь создает где-то "Запись". У абстракции "Запись"
может быть ряд своих атрибутов тип содержимого, когда создан, можно ли редактировать, показывать данную запись всем или только
зарегистрированным пользователем. У "Пользователя" есть свои атрибуты. Форум -- это группа записей объединенных по какому-либо
критерию, скажем подфорум. Ну в общем, продолжая в том же духе можно еще прикинуть какие-нибудь важные доменные объекты или
абстракции. Что такого предлагает .NET FW кроме инструментов для работы с абстракциями(доменными сущностями)?

S>>Это факт. Это, кмк, нужно для больших, типа банковских и т.п., сервисов и приложений. Но по отдельности и некоторые компоненты DDD можно

S>>использовать -- ubitiquos language, bounded context и т.п. Но тут тогда уж проще следовать методологии целиком, а не по кускам выдергивать.
S>>Мож не взлетает именно из-за кусочничества .
G>Тем не менее не видел примеров где БОЛЬШЕ ДДД делает код лучше, чем когда МЕНЬШЕ ДДД.
G>Может это какие-то слишком простые примеры были, но где взять сложные, чтобы можно было сравнивать подходы?

Ну вот я работал в компании, где монолит распили на микросервисы по ДДД. Вроде работало. Но опять же, от ДДД там только
разбивка на микросервисы с помощью Bounded Context + Ubiquitous Language. Короче, в основном стратегические паттерны.
Кодом людям нужно помогать!
Re[16]: Что если не разделять строго dto, entity, bo...
От: Sharov Россия  
Дата: 30.12.25 09:34
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Вы сейчас пытаетесь сказать, что не бывает хорошего структурированного кода без "модели предметной области"? Я еще раз повторю что это неправда, предлагаю перестать об этом говорить.


А какую проблему решает хороший код, если он даже не пытается моделировать предметную область, т.е. не оперирует необходимыми абстракциями?
По-моему, даже на не ООП языках типа С люди стараются оперировать абстракциями в коде.

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


Давайте, а то мне кажется мы говорим о разном, подразумевая "модель предметной области".
Кодом людям нужно помогать!
Re[15]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 30.12.25 10:12
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


S>>>Без понимания и выработки соотв. абстракций решать проблемы будет крайне затруднительно.

G>>Честно не понимаю о чем речь. Давайте возьмём например разработку форума. Какие абстракции для этого нужно создать? Того что предлагает .NET FW недостаточно?

S>Ну, например, абстракция "Запись" или "Пользователь". Когда какой-то пользователь создает где-то "Запись". У абстракции "Запись"

S>может быть ряд своих атрибутов тип содержимого, когда создан, можно ли редактировать, показывать данную запись всем или только
S>зарегистрированным пользователем. У "Пользователя" есть свои атрибуты. Форум -- это группа записей объединенных по какому-либо
S>критерию, скажем подфорум. Ну в общем, продолжая в том же духе можно еще прикинуть какие-нибудь важные доменные объекты или
S>абстракции.

Из этой речи я понял, что "абстракции" это описания типов хранимых данных, чтобы делать запросы и получать данные типизировано?
Если так, то слово "абстракция" тут неуместно.

S>Что такого предлагает .NET FW кроме инструментов для работы с абстракциями(доменными сущностями)?

Например ASP.NET Core Identity. Он как раз представляет из себя абстракцию (определяет операции, позволяющие потребителю не зависеть от их реализации) для работы с пользователями в любой системе.
Вы можете по образу и подобию сделать свою абстракцию для работы с темами и сообщениями в форуме. Но она имеет смысл только тогда, кода к этой абстракции будет обращаться кто-то еще.
Для решения конкретной задачи — создания форума — нужны такие абстракции как "обработчик веб-запроса" (контроллеры), доступ к данным Entity Framework Core, фоновые задачи — backgroundservice, инструменты для работы с конфигурацией — Configuration и Options/
Вы на них собираете нужную вам функциональность.

Какие абстракции еще нужны? Или все "абстракции" сводятся к описаниям типов хранимых и передаваемых данных?
Re: Что если не разделять строго dto, entity, bo...
От: elmal  
Дата: 30.12.25 17:32
Оценка:
Здравствуйте, Shmj, Вы писали:

S>По этому как бы, получается, есть вера что нужно разделять — но нет реального смысла.

Смысл появляется с ростом проекта и с изменениями в проекте. На этапе прототипа и всяких MVP можно не разделять. Основное — выкатить что хоть как то работающее как можно быстрее. А вот далее пойдет развитие, доработки и т.д. И тут рано или поздно появится именно необходимость уже все разделять. Но в теории может и не понадобиться, если по быстрому написали и далее изменений не требуется почти. Но далее наверняка будут миграции всякие, смены базы данных, смена библиотек, возможно даже смена языка программирования, плюс все будет переписываться частями, потребуются хитрые интеграции со сторонними сервисами, зачастую еще разных версий — вот тут уже будут и разные DTO и чего только не будет. И это все будет очень оправдано, так как это тупо сэкономит до хрена времени на разработку и поиск и исправление багов. А пока проект детский, большой необходимости в разделении на Entity, DTO и бизнес объекты по большому счету нет. При развитии это все можно достаточно быстро все выносить, сложности то в преобразовании никакой. Но ключевое — хоть и сами объекты могут и выполнять на начальном этапе разные роли, крайне важно даже на этапе прототипа MVP не смешивать логику ввода-вывода, UI и бизнес логику. Иначе проблемы будут даже на детских проектах и будет баг на баге.
Re[18]: Что если не разделять строго dto, entity, bo...
От: Sharov Россия  
Дата: 31.12.25 00:13
Оценка:
Здравствуйте, gandjustas, Вы писали:

S>>А какую проблему решает хороший код, если он даже не пытается моделировать предметную область, т.е. не оперирует необходимыми абстракциями?

G>1) Уменьшает дублирование кода
G>2) Уменьшает количество связей и сайд-эффектов
G>3) Уменьшает цепочку вызовов и количество промежуточных слоев между вызовов и действием
G>4) Увеличивает быстродействие
G>5) Уменьшает неявную передачу данных и изменение стояния
G>Это все вещи связанные, но в некоторых местах могут противоречить друг другу, поэтому хороший код это баланс.

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


S>>По-моему, даже на не ООП языках типа С люди стараются оперировать абстракциями в коде.

G>Вы как-то слишком широко применяете слово "абстракция". Когда вы создаете класс с набором свойств это не абстракция. Реализация интерфейса это тоже не абстракция. Абстракция это то, что использует такие классы или интерфейсы. А писать такой код нет необходимости. Большинство полезных абстракций уже есть в библиотеках, зачастую стандартных.

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

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

S>>Давайте, а то мне кажется мы говорим о разном, подразумевая "модель предметной области".
G>Начнем с простого, позже смогу вырезать кусок из реального проекта.
G>Недавно делал пример для статьи на Хабре https://github.com/gandjustas/habr-post-stock-api, АПИшка для резервации заказов, работает с базой, содержит очень важную для бизнеса логику. Это как маленький кусок большого приложения

Ну мы ведем речь про явно более крупные приложения, а не про crud на 3 операции.

G>Там даже есть абстракция — очередь запросов (она не шибко полезная в целом)


Зачем, лукавое это? А что стандартная библиотека, кстати, не помогла?

G>Что там является "моделью предметной области", в чем её ценность, и как она влияет на остальные части кода?


Ну как минимум https://github.com/gandjustas/habr-post-stock-api/blob/main/Model.cs
Кодом людям нужно помогать!
Re[17]: Что если не разделять строго dto, entity, bo...
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 31.12.25 13:16
Оценка:
Здравствуйте, gandjustas, Вы писали:

P>>Мертвый код сначаоа нужно идентифицировать. Чаще всего он просто выглядт, как живой код.

G>Давайте считать что мертвый код уже был идентифицирован, ибо если нет, то о чем разговор?

Ага, давайте считать, что проблемы нет, а строчки сами будут говорить надо ли их удалять.

G>Обычно мертвый код выглядит как классы которые нигде не создаются, находятся тремя-четырьмя кликами в студии.


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

P>>Это всё крайне растяжимое. У каждого своё видение, насколько глубоко это всё надо делать.

G>Рамки задачи всегда можно сохранить. Просто задавай себе вопрос: "как это влияет на ту задачу, которую мне сейчас необходимо решить?". Если никак, то не надо этого делать.

Вы в слова играете. У каждого своё видение, что именно относится к задаче. Например, один меняет метод, и все точки вызова проверит и поправит. А другой решит,что такая чистка к его задаче не относится, и даже тикет не создаст.

G>Кроме того, я изначально писал что нужно заниматься проектированием и программированием "сверху вниз", тогда контролировать скоуп несложно.


Это общие слова.

P>>Одна единственная задача это только краткосрочная перспектива.

G>Это именно краткосрочная.

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

P>>Пример — думали хватит чисто эндпоинта таскать из ui в базу и обратно, а после первого релиза вылезло такое...

G>Ну так после первого релиза и поправьте. Никто ведь заранее не знал, что вылезет после релиза, а если бы пытались угадать, то вероятнее всего не угадали бы.

В этом и есть проектирование — выяснить, какие у вас цели, абы сделать, или глянуть чуть дальше, те самые среднесрочные-долгосрочные цели.

P>>Я вам уже привел пример Хорошее проектирование это не только здесь и сейчас, за что вы топите, но прежде всего и адеватный горизонт планирования.

G>Практика показывает что занимаясь проектированием "только здесь и сейчас" почти всегда получается компактный код, который легко поддерживать.

Вам что бы обратную совместимость заложить в какое апи уже надо отойти от здесь и сейчас, а рассмотреть а что же вообще может или не может появиться.
Или вы предлагаете сначала сломать, а потом, если у когото утекут миллионы, завести тикет и начать фиксить?
Re[19]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.01.26 01:22
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


G>>Что там является "моделью предметной области", в чем её ценность, и как она влияет на остальные части кода?

S>Ну как минимум https://github.com/gandjustas/habr-post-stock-api/blob/main/Model.cs
То есть "модель предметной области" это типизированное описание схемы БД, так?
Апологеты DDD как раз с этим спорят.




S>>>А какую проблему решает хороший код, если он даже не пытается моделировать предметную область, т.е. не оперирует необходимыми абстракциями?

G>>1) Уменьшает дублирование кода
G>>2) Уменьшает количество связей и сайд-эффектов
G>>3) Уменьшает цепочку вызовов и количество промежуточных слоев между вызовов и действием
G>>4) Увеличивает быстродействие
G>>5) Уменьшает неявную передачу данных и изменение стояния
G>>Это все вещи связанные, но в некоторых местах могут противоречить друг другу, поэтому хороший код это баланс.

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

А кто сказал что отсутствие "объектов доменной модели" автоматически приводит к плохому решению задачи?
И кто сказал что наличие "объектов доменной модели" автоматически приводит к хорошему решению задачи?


S>Ну и самый главный вопрос, а как всему вышеперечисленному мешает оперирование объектами доменной модели?

Никак не мешает и никак не помогает. Хотя зависит от того, что входит в понятие "оперирование объектами доменной модели", так как это может давать ограничения
Например код вида
ctx.Stock.Where(s => s.Wharehouse == id).ExecuteUpdate(x => x.SetProperty(s => s.Quantity, s => s.Quantity - s.Reserved).x.SetProperty(s => s.Reserved, 0))

Является "оперированием объектами доменной модели"?

S>>>По-моему, даже на не ООП языках типа С люди стараются оперировать абстракциями в коде.

G>>Вы как-то слишком широко применяете слово "абстракция". Когда вы создаете класс с набором свойств это не абстракция. Реализация интерфейса это тоже не абстракция. Абстракция это то, что использует такие классы или интерфейсы. А писать такой код нет необходимости. Большинство полезных абстракций уже есть в библиотеках, зачастую стандартных.

S>Делаю какой-нибудь реалистичны автотренажер или игру для машин, есть в стандартной библиотеке класс автомобиль, мотор и т.п.?

Мы тут вроде как корпоративные приложения рассматриваем, которые оперируют данными в бд в многпользовательском режиме.
Думаю если бы мы рассматривали однопользовательскую 3д игру (видимо под ней понимается автотренажер), то там были бы объекты движка, которые представляют из себя "объекты на сцене", с "геомертрией", "текстурами" итд
Нужно ли из них делать классы вроде "автомобиль", "мотор" — я не уверен.

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

S>>>Давайте, а то мне кажется мы говорим о разном, подразумевая "модель предметной области".
G>>Начнем с простого, позже смогу вырезать кусок из реального проекта.
G>>Недавно делал пример для статьи на Хабре https://github.com/gandjustas/habr-post-stock-api, АПИшка для резервации заказов, работает с базой, содержит очень важную для бизнеса логику. Это как маленький кусок большого приложения

S>Ну мы ведем речь про явно более крупные приложения, а не про crud на 3 операции.

Вспоминаем закон Галла

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

Вот простая система есть, мы начнем дополнять функциями, а модель БД — сущностями\таблицами
Если функции пухнут — делаем Extract Method.
Если несколько методов имеют один и тот же набор параметров, то делаем класс с этими параметрами в конструкторе и переносим вызовы внутрь него.

Сколько нам нужно функций, чтобы DDD с его паттернами стало давать какой-то профит?


G>>Там даже есть абстракция — очередь запросов (она не шибко полезная в целом)

S>Зачем, лукавое это?
Да, в посте написано, что так делать не надо в подавляющем большинстве случаев.

S>А что стандартная библиотека, кстати, не помогла?

Помогла
Отредактировано 02.01.2026 1:38 gandjustas . Предыдущая версия .
Re[20]: Что если не разделять строго dto, entity, bo...
От: Sharov Россия  
Дата: 03.01.26 15:57
Оценка:
Здравствуйте, gandjustas, Вы писали:


G>>>Что там является "моделью предметной области", в чем её ценность, и как она влияет на остальные части кода?

S>>Ну как минимум https://github.com/gandjustas/habr-post-stock-api/blob/main/Model.cs
G>То есть "модель предметной области" это типизированное описание схемы БД, так?
G>Апологеты DDD как раз с этим спорят.

1)Сразу оговорюсь, я не апологет DDD. Я ни одно книжки по DDD не прочитал, и много знаю по касательной.
Я просто не считаю правильным отмахивать от DDD, как о бесполезной штуке. Оно большое, и люди частями или
целиком его вполне успешно применяют.
2)

То есть "модель предметной области" это типизированное описание схемы БД,

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

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

G>А кто сказал что отсутствие "объектов доменной модели" автоматически приводит к плохому решению задачи?

Никто не сказал, просто это, кхм, странно. Задача софта эмулировать соотв. процессы. Как можно эмулировать что-то без
соотв. сущностей?

G>И кто сказал что наличие "объектов доменной модели" автоматически приводит к хорошему решению задачи?


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

Я вообще не вижу противоречия между хорошим кодом и объектами доменной модели. Это прям какая-то странная дихотомия.

S>>Ну и самый главный вопрос, а как всему вышеперечисленному мешает оперирование объектами доменной модели?

G>Никак не мешает и никак не помогает. Хотя зависит от того, что входит в понятие "оперирование объектами доменной модели", так как это может давать ограничения
G>Например код вида
G>
G>ctx.Stock.Where(s => s.Wharehouse == id).ExecuteUpdate(x => x.SetProperty(s => s.Quantity, s => s.Quantity - s.Reserved).x.SetProperty(s => s.Reserved, 0))
G>

G>Является "оперированием объектами доменной модели"?

Скорее оперирование представлением в бд.

S>>>>По-моему, даже на не ООП языках типа С люди стараются оперировать абстракциями в коде.

G>>>Вы как-то слишком широко применяете слово "абстракция". Когда вы создаете класс с набором свойств это не абстракция. Реализация интерфейса это тоже не абстракция. Абстракция это то, что использует такие классы или интерфейсы. А писать такой код нет необходимости. Большинство полезных абстракций уже есть в библиотеках, зачастую стандартных.

Я несколько фривольно обращался со словом абстракция. Я под этим больше понимал идеи доменных объектов. Я за это слово
в данном контексте не держусь. Тут речь главным образом об "объектах доменной модели".

S>>Делаю какой-нибудь реалистичны автотренажер или игру для машин, есть в стандартной библиотеке класс автомобиль, мотор и т.п.?

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

Какая разница, софт есть софт.

G>Думаю если бы мы рассматривали однопользовательскую 3д игру (видимо под ней понимается автотренажер), то там были бы объекты движка, которые представляют из себя "объекты на сцене", с "геомертрией", "текстурами" итд

G>Нужно ли из них делать классы вроде "автомобиль", "мотор" — я не уверен.

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


S>>Ну мы ведем речь про явно более крупные приложения, а не про crud на 3 операции.

G>Вспоминаем закон Галла
G>

G>Любая работающая сложная система развивается на базе работающей простой системы. Сложные системы, созданные с нуля, никогда не будут работать в реальном мире, поскольку в процессе разработки на них не влияли факторы отбора, присущие среде

G>Вот простая система есть, мы начнем дополнять функциями, а модель БД — сущностями\таблицами
G>Если функции пухнут — делаем Extract Method.
G>Если несколько методов имеют один и тот же набор параметров, то делаем класс с этими параметрами в конструкторе и переносим вызовы внутрь него.

Вот цитата Б. Мейера отсюда -- https://bertrandmeyer.com/2012/11/27/why-so-many-features/

It is easy to complain about software bloat, and examples of needlessly complex system abound. But your bloat may be my lifeline, and what I dismiss as superfluous may for you be essential. To paraphrase a comment by Ichbiah, the designer of Ada, small systems solve small problems. Outside of academic prototypes it is inevitable that a successful software system will grow in complexity if it is to address the variety of users’ needs and circumstances. What matters is not size but consistency: maintaining a well-defined architecture that can sustain that growth without imperiling the system’s fundamental solidity and elegance.


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

G>Сколько нам нужно функций, чтобы DDD с его паттернами стало давать какой-то профит?


Какой-то дурацкий вопрос, если честно. Типа сколько нужно людей, чтобы лампочку вкрутить. Вы какую-то цифру ждете?
Она, скорее всего, у каждого будет своя.

S>>А что стандартная библиотека, кстати, не помогла?

G>Помогла

Само собой, но ее одной не достаточно.
Кодом людям нужно помогать!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.