Что если не разделять строго 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: Что если не разделять строго 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[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: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.11.25 12:46
Оценка: +1 -1
Здравствуйте, Shmj, Вы писали:

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


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


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

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

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

Для разработчика зачастую бонусы есть:
— возможность написать много кода, с разумным оправданием. Программисты зачастую испытывают удовольствие от написания кода и создания «архитектуры», даже если мела ной потребности в этом нет
— возможность дороже продать свою работу. написать одну строку стоит в 10 раз дешевле, чем написать 10 строк.
— возможность применить больше хайповых паттернов и библиотек, чтобы написать в резюме. В одну строку много паттернов не запихнешь, а в 10 уже можно.
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[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[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[4]: Что если не разделять строго dto, entity, bo...
От: Shmj Ниоткуда  
Дата: 29.11.25 18:19
Оценка:
Здравствуйте, 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[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[7]: Что если не разделять строго dto, entity, bo...
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.12.25 17:36
Оценка: +2 :))
Здравствуйте, gandjustas, Вы писали:

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

G>Может на сервере делать также? Просто скопипастить код в контроллерах, и поменять запросы?
Ну так это же и есть основной способ. Смотрите, как у нас всё классно — мы фигачим чотко по плану, два с половиной контроллера в человеко-день!
На каждую фичу нужно пять контроллеров, один DTO, один Entity, один репозиторий, один этот, как его, Aggregation Root, пять хранимых процедур.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
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[9]: Что если не разделять строго dto, entity, bo...
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 02.12.25 15:01
Оценка: 4 (1)
Здравствуйте, Kernan, Вы писали:

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


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

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

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

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

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

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

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

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

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

А если у вас вспомогательная утилитка "скопировать 5 юзеров из той бд в эту" то вам вообще хватит 1 файл + 1 main.
Re[10]: Что если не разделять строго dto, entity, bo...
От: Shmj Ниоткуда  
Дата: 03.12.25 12:47
Оценка:
Здравствуйте, Pauel, Вы писали:

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


Во! Кстати действительно веская причина — если одновременно несколько разных СУБД — тут да, нужны мапперы.
=сначала спроси у GPT=
Re[7]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 04.12.25 17:27
Оценка: -1 :)
Здравствуйте, Kernan, Вы писали:

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


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


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



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

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

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

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

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

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


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

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

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[10]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 04.12.25 18:19
Оценка: 78 (1)
Здравствуйте, 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[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[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[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[11]: Что если не разделять строго dto, entity, bo...
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 05.12.25 07:15
Оценка:
Здравствуйте, 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 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[9]: Что если не разделять строго dto, entity, bo...
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 05.12.25 08:35
Оценка:
Здравствуйте, Qulac, Вы писали:

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


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

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

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

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

Правила большого пальца:
1. нужно маленькое приложение — пишите как маленькое
2. нужно большое — пишите как большое.
3. в любом случае нужно прояснять ситуацию, что бы не ошибиться с принятием решения.
Отредактировано 05.12.2025 8:36 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[9]: Что если не разделять строго dto, entity, bo...
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 05.12.25 16:25
Оценка:
Здравствуйте, 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
Оценка:
Здравствуйте, gandjustas, Вы писали:

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

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


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


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

Сохранять простоту кода при разработке нетривиальных программ — сложный навык: требует концентрации, чтения существующего кода, постоянного изучения новых библиотек. Но эти затраты многократно окупаются на поддержке.
Если хорошо натренировать всегда выдавать максимально простой код, то это будет сильно быстрее, чем то, что фигачат DDD-программисты и всякие ИИ. Потому что есть предел количества строк отлаженного продуктивного кода, который может выдавать программист в единицу времени. И он почти не зависит ни от языка, ни от архитектуры.
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 08:26
Оценка:
Здравствуйте, gandjustas, Вы писали:

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


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

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

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

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

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

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

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

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


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

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

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

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

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

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

Корпоративные приложения очень разные. Например, практически везде разделяют дто ui и дто базы данных. А у вас это сходу "свернули не туда"
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 фиксов у других разработчиков будут заканчиваться неудачами. Так мины обычно и закладываются — находишь однострочник, а потом по всему коду попытки купировать, то тут, то там.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.