Хорошо давайте умножим на реальность Ваш пример. Каждое действие это не одно действие а группа действий которая вполне может состоять из подгруппы и даже подгрупп подгрупп. Допустим получение заказа требует не одного запроса а нескольких, еще и из разных бдшек, наша естественная реакция это разложить все это по разным сервисам, итого мы имеем следующее у нас есть вызов в нашем методе некого сервиса, он внутри вызывает пару других, внутри которых вызываются еще какие-то сервисы. Да все это относиться к заказу и часть целого но по факту эти части обрабатывают разные подразделения и собираются во едино они только во время оплаты. Допустим нам надо знать скидки из отдельной бд, количество товара со склада из еще одной бд, и персональные предложения для пользователя из еще одной бд, ну и вишенка нам надо дернуть есть ли баланс на внутрикорпоративной карте которая в еще какой-нибудь отдельной бд валяется. Итого если мы будем придерживаться во всем принципа выделения инфраструктуры то легко сможем иметь многоуровневые слои вызовов. Еще раз я просто указал что такая проблема возможна если ударяясь в крайности пользоваться данным советом. Сам по себе совет хороший.
Я же выше написал что это была ирония а Вы все приняли серьезно.
Программирование — это не искусство и не «каждый пишет как чувствует». Это инженерная дисциплина с накопленным корпусом правил, паттернов и антипаттернов. Их стоит изучать — ровно так же, как вы в своё время изучили синтаксис языка и работу рантайма.
Интересное мнение, вот только крайне опрометчивое, потому что иначе бы чего-то нового не появлялось в отрасли а появление чего-то нового обычно предшествует чье-то творчество. Например какой-то человек пользовался чем-то но это его не устраивало и он сделал свою версию которая работает по другому с решением проблем текущей, чем не искусство? К слову искусство это творчество тоже отчасти а большую часть времени творцы занимаются рутинными делами, например писатель стучит по клавишам, художник замешивает краски и мажет кисточкой и т.п.
Со статическим методом — для чистого switch это сработает, но это процедурный подход. В ООП логичнее инкапсулировать логику в сам объект. Логика принятия решения живёт в самом объекте решения — ни зависимостей, ни моков, ни статических утилит.
Еще раз, я говорю о том что Вы в Вашем примере вынесли по сути всю логику из PayOrderHandler и оставили там только вызовы пары методов из других классов. Это хорошо вот только теперь когда Вам надо протестировать этот код юнитами то что за тесты Вы напишите, которые проверяют что из одной пары моков вернется то значение которые Вы пропишите в arrange теста и что оно потом передастся в другой мок другого метода? Да Вы убрали инфраструктуру как зависимость из метода но факт в том что у Вас ничего и не осталось больше в нем. Представьте что Вы сами через полгода все забыв откроете этот код, как думаете все понятно что тут происходит, а это согласно Вашей же логике единый процесс т.е. обработка платежа.
Про «сколько слоёв нужно» — для большинства задач классических трёх слоёв из Clean Architecture хватает. Если становится тесно — стоит делить слой на фичи (vertical slices), а не добавлять новые слои. Да если весь сервис — это «взять из базы, вернуть клиенту» — одного слоя достаточно.
Эх, почему тогда столько человек делают черти что, наверно просто не в курсе о том что есть золотой грааль Clean Architecture. Это была ирония если что.
По поводу «вынести в приватные методы» — если вынести switch в приватный метод того же класса, класс всё равно зависит от dbContext, externalApi и _logService. Тестировать бизнес-правило отдельно от инфраструктуры не получится — моки тех же 5 зависимостей. Суть не в том, чтобы код стал короче, а в том, чтобы бизнес-логика не зависела от инфраструктуры.
Ну хорошо можно вынести switch в статичный метод и тогда зависимости и мокинг перестают быть проблемой.
Про обратную сторону — это может быть проблемой. Именно поэтому в статье написано «Слоёв нужно столько, сколько нужно. Для простого CRUD — может, и одного достаточно.» Если алгоритм линейный и тестов нет — вынос в 10 классов сделает только хуже. Но когда появляются тесты или меняется инфраструктура (другой банк, другой ORM) — цена «всё в одном месте» резко растёт.
"Слоёв нужно столько, сколько нужно" да вот только как понять сколько нужно? Это как раз фундаментальная проблема всех архитектур, когда люди начинающие проект думают что их слишком много или слишком мало а потом оказывается что наоборот, тут просело а там наоборот вылезло. И для архитектуры это выглядит как совет "не делай плохо, делай хорошо". Я к тому что что такие советы слишком абстрактны и очень вероятно что человек прочитавший такой совет не сможет применить его в своем проекте потому что ту грань о которой Вы говорите определить очень сложно.
Если с первыми двумя антипаттернами я согласен правда непонятно почему это архитектурные проблемы то вот третий стоит обсудить. Название "Доменная логика прибита к фреймворку" и Вы демонстрируете как в сложном примере просто вынесли часть кода куда-то еще, причем тут вообще неважно куда, можно было вынести и в приватные (или публичные если надо их тестировать) методы. Я к тому что во первых на архитектурную проблему это снова не тянет. По факту если на проекте хоть в каком-то виде пишутся тесты то такого кода скорей всего в принципе не будет написано. А в случае когда тестирование только ручное то когда наоборот алгоритм целиком в одном месте и все понятно сразу из одного места, в некоторых случаях это скорее хорошо чем плохо, почему потому что легко понять горизонт логики. Я видел обратную сторону такого подхода когда открываешь метод, там 3 строчки но чтобы понять логику что происходит надо прыгать по сотне других методов по перекрестным ссылкам.
Но если честно, ключевая перемена — в самой коммуникации. Теперь разработчик может задать вопрос в любом комьюнити и получить ответ за несколько минут. И это не поверхностная помощь: иногда там такие рассуждения, что диву даёшься. И что интересно: эти обсуждения заметно уплотняют путь к пониманию. Хочу спросить вас: когда вы в последний раз тратили несколько дней на поиски решения проблемы? Уверен, уже давно нет.
А ещё важно, что молодым не нужно преодолевать психологический барьер — им нормально писать в открытые сообщества, делиться прототипами, спрашивать мнение. Они выросли в этом.
То чувство когда я модерировал топики на программерском форуме для новичков и студентов в начале нулевых, где новички делали именно то самое о чем Вы написали.
отображения данных происходит через наследование модели qabstractitemmodel с переопределением методов
Это нужно для случаев когда нужен полный контроль над данными, но это не обязательно. В QML вообще не требуется его использование для большинства кейсов.
чтобы не трогать недоделанную архилогично допотопную технологию сложно модифицирующей кнопкой, слайдером и т.д. которая по современным стандартам UI не дотягивает
Не очень понятно о чем Вы, стандартных тем в Qt-е много, плюс можете сделать свою.
может быть поэтому разрабы телеграм десктоп версии рисуют все через qt painter
Если они допустим Android приложение телеги на Flutter будут делать также через painter рисовать это значит что Flutter это технология априори "допотопная" и "недоделанная"?
Вопрос был скорее об использовании выражения "пишем код один раз", обычно это выражение подразумевает что все самые важные кейсы покрыты пакетами от авторов инструмента и поддерживают все платформы которые собственно поддерживает сам инструмент (еще и всеми версиями инструмента). Дак вот в Flutter-е уже есть критическая масса таких пакетов которые покрывают большую часть кроссплатформенных потребностей (и я здесь говорю абсолютно про все заявленные платформы) сделанных авторами Flutter-а?
так как уже есть тысячи плагинов, которые закрывают любой кейс
Это прекрасно но вот пример JavaScript-а нам показал что это бывает скорее минусом чем плюсом. Потому что куча пакетов которые делают одно и тоже и половина из которых заброшена авторами а другая с кучей багов висящих годами и мейнтейнерами которые что-то делают для себя. Да есть и нормальные ребята которые делают хорошие пакеты но таких как Вы понимаете меньшинство. Просто чтобы Вы понимали контекст моего изначального вопроса выше.
Мы тогда разделили API - связанные записи писали отдельно.
Не всегда такое возможно чаще наоборот приезжает толстый JSON/XML в котором сразу и основная запись и связанные и надо все это записать единой логической операцией. Иногда и массив из основных записей плюс все сопутствующие. На моей памяти такое было довольно часто.
Как по мне ORM начинает сиять когда надо делать вставку связанных таблиц, например у нас таблица и 20 связанных таблиц с отношением один ко многим с одним и более уровнем вложенности и я хочу сделать вставку всего этого добра. В ORM-е это делается за одну строчку, а теперь попробуйте сделать это с использованием билдера. Тоже самое касается и обновления и удаления. Почему-то в контексте ORM все говорят в основном только о SELECT-е игнорируя остальные операции.
Так, представители старших поколений вспоминают: на первой работе им выдавали ноутбук и говорили «разберешься сам». Для них это стало стандартом, и теперь они транслируют тот же подход своим подчиненным. Сегодня, в эпоху бирюзовых компаний, холакратии и эмпатичного лидерства, все еще встречаются люди, которые рассуждают: «Меня никто не менторил и не поддерживал, почему я должен тратить силы на то, чтобы растить сомнительный ресурс?»
Как по мне это тоже стереотип, во первых если такое и было то далеко не у всех и во вторых тут большинство имеют ввиду следующую вполне реальную для любого поколения ситуацию когда пришел человек, так как он новичок на него тратят много времени другие люди у которых тоже есть своя работа но этот новичок через год остается на том же уровне что и был во время прихода на работу и требует столько же времени. От новичка ждут все же каких-то усилий с его стороны, т.е. да он не знает чего-то он может спросить о чем-то у ментора, но также неплохо чтобы он вначале попробовал сам решить несколькими вариантами а только потом шел с проблемой к ментору, да в первые месяцы вопросов и проблем будет много и это нормально но в последующие месяцы ожидается что новичок в каком-то количестве вещей сможет и сам разбираться даже если не чего-то не знает.
В целом по статье описаны люди которыми были миллениалы в том же возрасте сколько сейчас зумерам. Отношение к переработкам а также смена работы по опыту меня и моего окружения было абсолютно таким же как описано в статье. Перерабатывали в основном те кто хотел больше денег или хотел поскорее погасить ипотеку быстрее хотя многие из таковых потом нашли другие варианты например фриланс и просто шабашки для друзей. В 2009 году мне один мой друг сказал чего это я сижу на одной работе уже 3 года (3 года карл!) и не пора бы менять. Напомню это был следующий год после 2008. Я работаю с представителями поколения зумеров и у меня нет никаких проблем с ними (проблемы есть но они в большей степени из-за "юности" в душе но все мы такими были). Поэтому мой вывод таков не надо делать какие-то градации на поколения просто общайтесь и работайте вместе и принимайте всех такими какие они есть.
Но, при установке, она подтянется сама, если ее нет. Вопрос только дискового пространства.
Кто подтянется сам? При публикации NativeAot Вы получите собранный платформо-специфичный бинарь внутри которого будет затримленный рантайм. Для запуска такого приложения не требуется ничего подтягивать, для него будут нужны только системные зависимости но рантайм уже не потребуется.
Это утверждение просто нарратив чтобы потом сказать что-то вроде "они не согласились вот поэтому мы их отключим с нашей стороны"
Хорошо давайте умножим на реальность Ваш пример. Каждое действие это не одно действие а группа действий которая вполне может состоять из подгруппы и даже подгрупп подгрупп. Допустим получение заказа требует не одного запроса а нескольких, еще и из разных бдшек, наша естественная реакция это разложить все это по разным сервисам, итого мы имеем следующее у нас есть вызов в нашем методе некого сервиса, он внутри вызывает пару других, внутри которых вызываются еще какие-то сервисы. Да все это относиться к заказу и часть целого но по факту эти части обрабатывают разные подразделения и собираются во едино они только во время оплаты. Допустим нам надо знать скидки из отдельной бд, количество товара со склада из еще одной бд, и персональные предложения для пользователя из еще одной бд, ну и вишенка нам надо дернуть есть ли баланс на внутрикорпоративной карте которая в еще какой-нибудь отдельной бд валяется. Итого если мы будем придерживаться во всем принципа выделения инфраструктуры то легко сможем иметь многоуровневые слои вызовов. Еще раз я просто указал что такая проблема возможна если ударяясь в крайности пользоваться данным советом. Сам по себе совет хороший.
Я же выше написал что это была ирония а Вы все приняли серьезно.
Интересное мнение, вот только крайне опрометчивое, потому что иначе бы чего-то нового не появлялось в отрасли а появление чего-то нового обычно предшествует чье-то творчество. Например какой-то человек пользовался чем-то но это его не устраивало и он сделал свою версию которая работает по другому с решением проблем текущей, чем не искусство? К слову искусство это творчество тоже отчасти а большую часть времени творцы занимаются рутинными делами, например писатель стучит по клавишам, художник замешивает краски и мажет кисточкой и т.п.
Еще раз, я говорю о том что Вы в Вашем примере вынесли по сути всю логику из PayOrderHandler и оставили там только вызовы пары методов из других классов. Это хорошо вот только теперь когда Вам надо протестировать этот код юнитами то что за тесты Вы напишите, которые проверяют что из одной пары моков вернется то значение которые Вы пропишите в arrange теста и что оно потом передастся в другой мок другого метода? Да Вы убрали инфраструктуру как зависимость из метода но факт в том что у Вас ничего и не осталось больше в нем. Представьте что Вы сами через полгода все забыв откроете этот код, как думаете все понятно что тут происходит, а это согласно Вашей же логике единый процесс т.е. обработка платежа.
Эх, почему тогда столько человек делают черти что, наверно просто не в курсе о том что есть золотой грааль Clean Architecture. Это была ирония если что.
Ну хорошо можно вынести switch в статичный метод и тогда зависимости и мокинг перестают быть проблемой.
"Слоёв нужно столько, сколько нужно" да вот только как понять сколько нужно? Это как раз фундаментальная проблема всех архитектур, когда люди начинающие проект думают что их слишком много или слишком мало а потом оказывается что наоборот, тут просело а там наоборот вылезло. И для архитектуры это выглядит как совет "не делай плохо, делай хорошо". Я к тому что что такие советы слишком абстрактны и очень вероятно что человек прочитавший такой совет не сможет применить его в своем проекте потому что ту грань о которой Вы говорите определить очень сложно.
Если с первыми двумя антипаттернами я согласен правда непонятно почему это архитектурные проблемы то вот третий стоит обсудить. Название "Доменная логика прибита к фреймворку" и Вы демонстрируете как в сложном примере просто вынесли часть кода куда-то еще, причем тут вообще неважно куда, можно было вынести и в приватные (или публичные если надо их тестировать) методы. Я к тому что во первых на архитектурную проблему это снова не тянет. По факту если на проекте хоть в каком-то виде пишутся тесты то такого кода скорей всего в принципе не будет написано. А в случае когда тестирование только ручное то когда наоборот алгоритм целиком в одном месте и все понятно сразу из одного места, в некоторых случаях это скорее хорошо чем плохо, почему потому что легко понять горизонт логики. Я видел обратную сторону такого подхода когда открываешь метод, там 3 строчки но чтобы понять логику что происходит надо прыгать по сотне других методов по перекрестным ссылкам.
Толщина Вашего тонкого метакомментария поражает я бы █ █████ █████████ █████████████
Наверно все же холодильник
То чувство когда я модерировал топики на программерском форуме для новичков и студентов в начале нулевых, где новички делали именно то самое о чем Вы написали.
Это был сарказм если Вы не поняли
Не ну конечно шах и мат Qt на свалку Flutter победил :-)
в QML есть
Это нужно для случаев когда нужен полный контроль над данными, но это не обязательно. В QML вообще не требуется его использование для большинства кейсов.
Не очень понятно о чем Вы, стандартных тем в Qt-е много, плюс можете сделать свою.
Если они допустим Android приложение телеги на Flutter будут делать также через painter рисовать это значит что Flutter это технология априори "допотопная" и "недоделанная"?
Обе технологии позиционируются как "пишем код один раз" кроссплатформенность и UI. Сравнение полностью корректное.
Вопрос был скорее об использовании выражения "пишем код один раз", обычно это выражение подразумевает что все самые важные кейсы покрыты пакетами от авторов инструмента и поддерживают все платформы которые собственно поддерживает сам инструмент (еще и всеми версиями инструмента). Дак вот в Flutter-е уже есть критическая масса таких пакетов которые покрывают большую часть кроссплатформенных потребностей (и я здесь говорю абсолютно про все заявленные платформы) сделанных авторами Flutter-а?
Это прекрасно но вот пример JavaScript-а нам показал что это бывает скорее минусом чем плюсом. Потому что куча пакетов которые делают одно и тоже и половина из которых заброшена авторами а другая с кучей багов висящих годами и мейнтейнерами которые что-то делают для себя. Да есть и нормальные ребята которые делают хорошие пакеты но таких как Вы понимаете меньшинство. Просто чтобы Вы понимали контекст моего изначального вопроса выше.
"пишем код один раз. Так вот, это 100% про Flutter." весь платформо-специфичный код тоже обладает таким свойством?
Не всегда такое возможно чаще наоборот приезжает толстый JSON/XML в котором сразу и основная запись и связанные и надо все это записать единой логической операцией. Иногда и массив из основных записей плюс все сопутствующие. На моей памяти такое было довольно часто.
Как по мне ORM начинает сиять когда надо делать вставку связанных таблиц, например у нас таблица и 20 связанных таблиц с отношением один ко многим с одним и более уровнем вложенности и я хочу сделать вставку всего этого добра. В ORM-е это делается за одну строчку, а теперь попробуйте сделать это с использованием билдера. Тоже самое касается и обновления и удаления. Почему-то в контексте ORM все говорят в основном только о SELECT-е игнорируя остальные операции.
Как по мне это тоже стереотип, во первых если такое и было то далеко не у всех и во вторых тут большинство имеют ввиду следующую вполне реальную для любого поколения ситуацию когда пришел человек, так как он новичок на него тратят много времени другие люди у которых тоже есть своя работа но этот новичок через год остается на том же уровне что и был во время прихода на работу и требует столько же времени. От новичка ждут все же каких-то усилий с его стороны, т.е. да он не знает чего-то он может спросить о чем-то у ментора, но также неплохо чтобы он вначале попробовал сам решить несколькими вариантами а только потом шел с проблемой к ментору, да в первые месяцы вопросов и проблем будет много и это нормально но в последующие месяцы ожидается что новичок в каком-то количестве вещей сможет и сам разбираться даже если не чего-то не знает.
В целом по статье описаны люди которыми были миллениалы в том же возрасте сколько сейчас зумерам. Отношение к переработкам а также смена работы по опыту меня и моего окружения было абсолютно таким же как описано в статье. Перерабатывали в основном те кто хотел больше денег или хотел поскорее погасить ипотеку быстрее хотя многие из таковых потом нашли другие варианты например фриланс и просто шабашки для друзей. В 2009 году мне один мой друг сказал чего это я сижу на одной работе уже 3 года (3 года карл!) и не пора бы менять. Напомню это был следующий год после 2008. Я работаю с представителями поколения зумеров и у меня нет никаких проблем с ними (проблемы есть но они в большей степени из-за "юности" в душе но все мы такими были). Поэтому мой вывод таков не надо делать какие-то градации на поколения просто общайтесь и работайте вместе и принимайте всех такими какие они есть.
Кто подтянется сам? При публикации NativeAot Вы получите собранный платформо-специфичный бинарь внутри которого будет затримленный рантайм. Для запуска такого приложения не требуется ничего подтягивать, для него будут нужны только системные зависимости но рантайм уже не потребуется.