Как стать автором
Обновить

Комментарии 238

Бесить разгребать старый код (лет 15 ему). Когда из 3х(!) файлов C++ (.cpp,.hpp) получается 10 строк java (просто сформировать байтовый массив вида тип(1байт)+длина(2байта)+значение из 4-х аргументов).
Догадываешься, что тот кто это писал начитался учебных материалов по полиморфизму, "правильной" организации иерахии объектов и.. И создал все это для формирования (один раз!) блока с фиксированым (!) набором.
И глаза вытекают все это разбирать что бы понять а что и как хотел.

А уж боль с кучей абстракций, слоев данных, и все это разбросано по куче функцикций и файлов для ОДНОКРАТНОГО вызова - это вырви глаз типично. Потому что джун начитался гуру, которые советуют что длинна тела функции не должна быть более 20-30 строк, а в отдельном файле не должно быть более 100 строк и все нужно оформлять через абстракции и слои данных.
И все это размером в 10Кбайт и 5 файлов схлопыветеся (переписывается) в 200 строк линейного обозримого кода в одной функции. Не знаю уж как обяснить что не нужно писать "функциональные вызовы" типа calcXmultipyY() { return X*Y; } вызываемые только один раз. Есть какая то разумная граница принципа выделения в отдельный вызов, а не просто "потому что".
что бы про это "гуру" ни говорили.

просто поделился болью. не более.

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

Аналогично, но немного с иной позиции. Я начинал проект на js, хотя по чесноку, ни разу не писал до этого на js. Естественно, начал писать в парадигме мне привычной, аля C++., но на функциоанльном базисе (да в общем то иного и не требовалось, ибо в целом задачи были не такие сложные). Далее проект передали человеку, который решил привести мой "спагетти код" в парадигму ООП. Как итог, из 5 файлов, по каждому на отдельное окно, теперь их около 20, где даже вызов обработчиков событий нажатия на кнопку ведётся через статические методы отдельного специального класса, которые не очень хорошо в итоге обсфуркцируются! Ну и прочие "радости", которые придется теперь уже мне причесывать в хоть какой то логический порядок, чтобы потом продолжить расширять проект на новые задачи.
Так что, статья - зачет! И рекомендовал бы её почитать подавляющему большинству современных программистов.

Была ситуация, когда в ходе дописывания какого-то проекта приходилось тоже править 10+ файлов, а причиной было добавление нового типа какой-то сущности. Не помню, какой именно, но у этой сущности была иконка, название и, возможно, тоже фильтр. Использовалось это в нескольких местах, и везде, где оно упоминалось, были конструкции вида v-if, v-else, где проверялось название этой сущности, и в зависимости от названия устанавливались иконки, тексты и т.д. В первый раз я поворчал, но сделал так же, потому что как всегда всё нужно срочно и быстро, хотя на счёт быстро - это вопрос спорный, но когда чуть позже нужно было добавить ещё один вид, не выдержал, переписал всё, собрав все сущности и их параметры в одном файле, а везде, где они нужны были, просто брались по названию из этого файла. И код стал чище, и не нужно было потом править кучу файлов для добавления чего-то нового (ведь всегда есть шанс что-то упустить).

Только недавно добавлял колонку в таблицу на фронте для чего понадобилось дописывать код в 12-ти файлах. Причём данные уже фетчились на фронте, то есть их просто надо было отобразить. Потом я узнал, что эту таблицу изначально имплементировал embedded разработчик, который работал в компании фулстеком.

Нередко проблема заключается в том, что в компании нет экспертизы в сфере фронтенд-разработки, а контрибутят во фронтенд почти все включая менеджеров продукта.

называется стрельба дробью

Наверное, это был проект, написанный по FSD :)

под LSD

FSD как раз и призван решать все эти проблемы. По сути FSD это домен дривен архитектура адаптированная для фронта с его фронтовыми приколами

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

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

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

На что то сложно - да. А не на 2*2.
У меня глаза болят от выделения совсем мелкого функционала (10 строк например) в функцию.

  1. Когда она вызвается в одном месте.

  2. Сложно отделима от основной логики (= куча аргументов) и внятно придумать причину почему часть логики отделить нужно - невозможно. (ну кроме странного довода "так количество строк в этом файле будет поменьше")

Тут вопрос не о "нужно не нужно" а о грани разумности в этом "нужно".

Лично я, когда мне такой кусок (сложный) нужно оттестировать, его отдельно тестирую и отлаживаю и copy/paste в нужно место. Когда это действительно нужно оттестировать. НО один раз и все.

Видел жесть в реализации джуна. Которому видимо сказали, что нужно все @Test обкладывать.
Так он действительно ВСЕ обкладывал тестами. Каждую функцию класса (java) делал с возможность вызова отдельно и писал на нее тест. "Заставть дурака богу молится.."
Код этих тестов был больше прикладного. А как изюминка.. в целом (как программа в комплексе) это все равно нифига не работало.

У меня глаза болят от выделения совсем мелкого функционала (10 строк например) в функцию.

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

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

Половина стандартной библиотеки из таких состоит.

Ключевой пункт, который я упоминал в аргументах "против", Вы не заметили или проигнорировали.
"вызыватеся в одном месте" = "ОДИН РАЗ ИСПОЛЬЗУЕТСЯ".
Точнее Вы все (оба) пункта причин/условий почему я против выделения чего то в функцию проигнорировали.

Ну нельзя же аргументировать только со своим понимание прочитанного. Не в обиду :)

"вызыватеся в одном месте" = "ОДИН РАЗ ИСПОЛЬЗУЕТСЯ".

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

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

Неа. Редко.
И всегда видно контекст "это мы хотели потом пере использовать, но потом передумали".
Довольно часто в исходниках библиотек приходится копаться и JDK то ж.
Ну по моему опыту
SpringBoot, Hibernate, Kafka client, jdbc Рostgre, bouncy castle - исходники из основных за проследний год.

"вызыватеся в одном месте" = "ОДИН РАЗ ИСПОЛЬЗУЕТСЯ".

Это не страшно, что она один раз используется, если выделеная функция формирует некий цельный логический блок, который коротко и информативно можно описать в её названии.
Предположим, у вас есть код, выполняющий некий математический рассчёт и в нём всего один раз решается квадратное уравнение. Можно оставить это вычисление внутри основного кода, ведь там всего то 2-3 строки, а можно вынести в функцию solveQuadraticEquation и читать основную функцию станет немного проще.
Если вы пишете код один раз и не трогаете его годами, то логично оставить код внутри. Если код живой и с ним приходится регулярно работать, то вынесенная функция упростит работу.

Я полностью согласен с тем что вы сказали.
Но вы аргументируете не со мной. А со своим представлением что я сказал.

см.

Сложно отделима от основной логики (= куча аргументов) и внятно придумать причину почему часть логики отделить нужно - невозможно. (ну кроме странного довода "так количество строк в этом файле будет поменьше")

Это не попадает под приведенный Вами пример.

Просто в вашем комментарии сложно понять, пункты 1 и 2 соединяются через И или через ИЛИ. Нужен рефакторинг комментария.

"и".
оба условия одновременно.

  1. Если переиспользуется - отднозначно лучше без copy|paste кода. Т.е. выделить в отдельную.

  2. Если функционально можно кусок кода выделить то то же желательно в отдельную завершенную функцию.

Я булькал по поводу практики резать линеный код ТОЛЬКО из соображений (слышал такой довод), что бы общая длинна была не более 30-50 строк. Без какого либо учета логики. Просто резать на части.
Ну и НЕ выделять в функцию логику (п2.) состоящую из 1-2 строк кода. Причем примитивную. типа X*Y. Утрировано. Но похожие по смыслу примеры выделения видел.

(слышал такой довод)

Я такой довод от сонара слышал, да приходилось дробить длинный код, чтобы просто QG пройти.

Ну а откуда этот довод произрастает @Rsa97 неплохо изложил.

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

Но давайте поговорим о чем-то среднем. Сегодня разбирал класс, у него в основе несколько списков (to_update, to_create) и пара хэш таблиц, в которые по ключам расставляются данные.
Сам класс пытается сравнить две последовательности: то, что пользователь пытался заказать и то, что поставщик в итоге в посылку положил. Если чего-то нет, то отметить, если что-то разделили на товары из разных партий, разделить это и в заказе. И т.п., логики много, есть позиции с дочерними позициями, есть виртуальные позиции.

Так этот класс аккуратно порезан на функции, функции какими-то флагами обмениваются между собой, но все обращаются к общим переменным, постоянно туда что-то добавляя. Оформлено тщательно и хорошо, а читать тяжело, 600 строк туго переплетенного месива на python: хоровод с циклами, списками и словарями. Было бы дерево в основе, было бы куда его растить.

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

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

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

Ну да — там, похоже, хуже уже некуда.

например, сделали, Func1, который делает X*Y, но потом кто-то сделал Func2, который вызывает Func1, но при этом делает ещё что-то полезное, все постепенно начинают использовать Func2, но и Func1 не убирают.

да и вообще, в результате "эволюции кода" одни функции худеют, другие толстеют, одни обрастают вызовами, другие их теряют... в общем живут жизнью :), пока их рефакторинг не приберёт...

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


а можно вынести в функцию solveQuadraticEquation и читать основную функцию станет немного проще.

Зато собственно код вместо полезной работы будет под капотом заниматься кучей служебных вещей, вроде выделения/освобождениея места на куче, переключением фрейма туда‑сюда, и т. д. и т. п. Особенно «эффективно», если эта самая трёхстрочная функция вызывается в цикле 100 500 миллионов раз.

Стоит ли брать на себя работу компилятора?

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

(Строго говоря, речь шла не о компиляторах, а о (полу)интерпретируемых языках вроде Ruby и PHP).

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

Например, формулу расчета какого то бизнес-значения вынести, дать осмысленное название и подписать комментарием где посмотреть откуда это значение взялось (иногда вплоть до указания ФЗ №XXX от DD.MM.YYY, таблица №105 или указания в какой документации, ТЗ или чем-то еще её найти) звучит на мой взгляд прекрасно, даже если она вызывается один раз и занимает 1-2 строчки.

В принципе, если функция вызывается один раз, но имеет "единую" идею, почему её не вынести (читать часто потом удобнее)? Тут основная проблема что думать надо. А думать часто лень...

(только потому увидел что вы в принципе ответили человеку с примерно такой же мыслью как у меня)

Так и пишем. Покрытие юнитами 98%, покрытие интеграционниками всех рест контрактов, всех запросов к БД и нетривиальных операций с DI/спрингом, покрытие блекбоксами всех happy path, обязательное разделение ДТО по слоям (рест/кафка, бизнес-логика, кэш, энтити), обязательное документирование и ручное тестирование по переданной документации при приёмке фичи. Плюс тестирование апдейта, взаимодействия разных инстансов при частичном апдейте и отката.

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

Я коротко работал на проекте, где были абстракции, в которых я не без труда разбирался, с очень сложными типами. На мой вопрос "зачем так усложнять?", сказали "для удобства тестирования", там были все эти абстракции с сервисами и репозиториями с DI, в приложении на React (sic). При этом тесты не писали вообще. А багов я там нашёл немало, которые при неочевидных условиях валили приложение.
Сам я поддерживаю вынос элементарного кода в функции, чаще всего для повышения самодокументируемости кода.

И все это размером в 10Кбайт и 5 файлов схлопыветеся (переписывается) в 200 строк линейного обозримого кода в одной функции.

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

Не знаю уж как обяснить что не нужно писать "функциональные вызовы" типа calcXmultipyY() { return X*Y; } вызываемые только один раз. Есть какая то разумная граница принципа выделения в отдельный вызов, а не просто "потому что".

Действительно трудно объяснить человеку, что есть контекст функции. Разумная граница: если функция занимается отправкой сообщения по личной скидке, то, внезапно, запрос в БД, расчёт скидки, метрики, локализация текста и т.д. не должны быть сплошной портянкой кода в сотни строк. Даже если каждая из линий кода вызывается строго один раз.

Вы серьезно считаете что микросервис, который просто берет 5 параметров из БД (обычный select из одной/двух таблиц) и формирует Json в ответ на GET /blabla
должен:

  1. содержать обязательно слой пердставления данных (отдельный JPA класс в отдельном path)

  2. Отдельно класс, который вытаскивает из БД.

  3. Отдельный класс, который заворачивает в Json (НЕ json model. а отдельный блин класс)

  4. json model класс.

А еще это выко нагруженный сервис.
После убирание всего получися код в Resource классе, который просто дергает через jdbc коннект, полученный из пула, обычный select и (о стыд) собирает строку json через конкатенацию (даже не через String.format, который ооочень медленный).

Вот пусть другие пишут в таких случаях строго по учебнику. А в данном вариант важны были единицы ms и kb в хипе.
GC JVM не дергается, судорожно пытася собрать мусор от всех этих классов которые "нужны" были для обработки запроса. И ко мне не прибегаю с криком почему так много жрет сервис при пиковой нагрузке.
Это не типично конечно. Если что то сложное, то такое упрощение во вред пониманию кода.
НО догматизм в любой области мне не нравится.

Сказать, что для кода из 100-200 строк разбитого на блоки комментариями и линейно выполняющего запрос в БД и формирование json без либ нужно 3 монитора..

Сказать, что для кода из 100-200 строк разбитого на блоки комментариями и линейно выполняющего запрос в БД и формирование json без либ нужно 3 монитора.

На мой горизонтальный монитор прямо сейчас помещается 63 строки. Минимум один вертикальный монитор на 100-200 строк кода точно нужен будет, возможно два. Для разбивки кода на смысловые части гораздо удобнее иметь функции (java умеет ведь в inline?), а не комментарии.

Вы серьезно считаете что микросервис, который просто берет 5 параметров из БД (обычный select из одной/двух таблиц) и формирует Json в ответ на GET /blabla должен:

...

После убирание всего получися код в Resource классе, который просто дергает через jdbc коннект, полученный из пула, обычный select и (о стыд) собирает строку json через конкатенацию (даже не через String.format, который ооочень медленный).

Я ничего не говорил про микросервис. Я говорил про мега функцию в 200 строк кода. Но да, в 99% случаев, за запрос в БД и за формирование JSON отвечают разные классы.

Вы в свою очередь описываете типичный говнокод. Я не программирую на java. Давайте я просто приведу аналогию из мира php. Вы сейчас описали самые худшие практики, которые были в ходу 20+ лет назад. Внутри "вьюхи" (шаблонизатора) или экшена контроллера (http обработчика) вы предлагаете: сделать сырой sql запрос, собрать вручную json, и сделать что то ещё.

А еще это выко нагруженный сервис.
...
Вот пусть другие пишут в таких случаях строго по учебнику. А в данном вариант важны были единицы ms и kb в хипе.

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

На мой горизонтальный монитор прямо сейчас помещается 63 строки. Минимум один вертикальный монитор на 100-200 строк кода точно нужен будет, возможно два. Для разбивки кода на смысловые части гораздо удобнее иметь функции (java умеет ведь в inline?), а не комментарии.

Скажите, пожалуйста, у Вас рыбки гуппи в родственниках не числятся? От того, что код выходит за границу экрана, лично я не забываю о нём немедленно — я помню, что он там есть, и что он делает. Мне 50 строк за уши хватает (хотя монитора и на 120 хватило бы).

каждая из линий кода

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

Расскажите, почему линии? У вас русский — родной язык, или вы его выучили позже?

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

Не знаю, у меня от функций на 200 строк изжога, читать их потом не легче. Декомпозицию никак нельзя провести, обязательно 200 строк?

нашел. заглянул в код.. того примера, что я описывал. Про 200 я загнул.
89 строк по факту вместе с анотациями @GETT) до последней "}"

У меня в экран IDE влазит 50 строк (обычный шрифт который я вижу без напряга с дистанции от 0.4 до 1 метра.
неужели понять функцию длинной в 2 экрана это настолько большая проблема?!
У меня как то логика функции и в 200 строк в голове умещается. Особенно если она разбита на логические блоки (коммент или хотя бы пустая строка).
Хотя, 200 конечно перебор. Это я сгоряча (субъективно).
больше чем один/1.5 экрана не использую.

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

Чего там 200, часто видел и по 500-700 строк с 6-8-ю уровнями вложенности if. Править такое - ещё то удовольствие.

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

в каждом конкретном случае, где что удобней - там и нужно.

Да еще бы с терминологией определится. Каждый свое подразумевает по "ООП".
не буде дискутировать по поводу "что такое ООП". Это как спорить "сколько ангелов на конце иглы поместится". Выродились все эти дискусси в схоластику. IMHO

Не знаете три свойства/черты ООП? Это как не знать три источника и три составные части марксизма. Стыдно должно быть)

В, допустим, прототипном ООП свои свойства и черты. В какой-нибудь CLOS — вообще свои.

У всех млекопитающих есть пара общих определяющих черт, хотя у дельфинов свои черты, а у ленивцев свои. Зачем уводить тему?

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

Вот Вы же как мыслите: ну надо бы было - переписал бы функцию на другие 10 строк. Так вот Вам и надо стало - перепишите, в чем вопрос?

Понимаю вашу боль, как свою, но при чем тут С++ и Java? Как бы походя идёт намёк, что и С++ тут подкачал как язык. В чем я лично сомневаюсь - именно в случае формирования всяких битовых штучек.

А что по статье...

садись в угол на гречку

Ну кто ж так пишет?? Иди в угол и встань на колени. На гречку. На сушеную. - вот как надо.

C++ в данном случае - этопереписывание строго ПО на java. Иногда проще переписать относительно простой модуль на кросс платформенное, чем возится с..
Java мне больше нравится чем C/C++. И на том и на том давно пишу.
но очень не люблю тратить время на разбор неуловимых причин core dumbped С++ программ и возню с big|little endian, байтовыми/word выравниваниями/упаковками данных.
А это есть было и будет, если в качетве серверных платформ испольхуется не тольк x86

И глаза вытекают все это разбирать что бы понять а что и как хотел.

Особенно когда в конце понимаешь/вспоминаешь что этот 15-и летний код писал сам

Вы уверены что обладаете правом испытывать бешенство от того что вам пришлось править код которому 15 лет...

Вы точно не испытываете бешенного уважения к тому с чем столкнулись?

из 3х(!) файлов C++ (.cpp,.hpp) получается 10 строк java

Не про ваш конкретный случай, но бывает так, что в "3-х файлах на С" заложена вся логика. А "10 строк на Java" тащат за собой паровоз зависимостей, кучу скрытых в них абстракций и в итоге работает в 5 раз медленнее как только нагрузка чуть увеличилась.

Тут всякое бывает...

Прочитал первые пару предложении, нормально так полыхает у автора.
Дочитаю, пожалуй :D

Пойми, брат

я так понимаю, автор написал этот пост в надежде, что тот, кому он не может сказать эти слова в лицо (друг зумер, судя по всему), прочитал это здесь :D
Но читают ли зумеры Хабр?:)

Очевидные вещи, но человеческая суЧность всегда радуется от чтения нытья других) Автору терпения, зумерам - знаний)

Да, я читаю Хабр

Да в статье клише на клише, вывод на эмоции и полыхание. Скорее всего 75% там написано AI.

Еще как читают

Ошибаешься, браток. Я всегда все говорю в глаза как есть. Просто зумеров так много, что со всеми по-отдельности времени не хватит поговорить. Я один раз указал одному на ошибки, так он решил ПОЖАЛОВАТЬСЯ менеджеру, типа как мамку позвать и сказать, что его раскритиковали. Волна лавандовых лате

Просто интересно, а на что пожаловался? На харрасмент?))

ну он обиделся, к такому видимо жизнь его не готовила) но да, что-то типа харрасмента)

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

Вы указали ему на ошибки с целью помочь или с целью унизить? Указать можно по-разному. Можно: "Ты сделал вот так, а я бы в этом случае сделал иначе, потому что то-то и то-то", но можно и: "Ты пьяный что ли писал? Я 20 минут в 10 строчках разбирался, формошлёп профнепригодный!!!!11".

Даже добавление слов "братишка" и "кореш" не влияют на окраску сообщения. Согласись же, браток, безоговорочную фигню написал, без вриантов, тут даже обсуждать нечего, друг.

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

Это важное уточнение.

Главное начать фразу со слов "Я конечно никого не хочу обидеть, но.."

После этого можно смело выдавать любые обидные вещи ))

Для полного сендвича надо добавить "без негатива" в конце

Вы указали ему на ошибки с целью помочь или с целью унизить? 

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

Я тоже зумер. И был даже джуном в одной из контор. Пока не началась сильная апатия, и пошло-поехало... Просранные сроки, увольнение по собственному, походы по врачам, подбор терапии... Сейчас я более-менее чувствую себя, но всё равно.

Читают, мы тут)

Крик души) или как у автора накипело)

Могу обобщить еще сильнее

Делай нормально — будет нормально ©

Делай хорошо - херово само получится.

Скрытый текст

"Нормально делай - нормально будет" © "Пневмослон"

Простота и простата — это признак зрелости.

Простата - признак мужского пола, не более того. Простатит - может и быть признаком зрелости, но больше похож на её проблему.

Простатит - может и быть признаком зрелости, но больше похож на её проблему.

Это признак перезрелости.

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

Откуда вы это знаете? Можно статистику посмотреть, раз уже вы ее упомянули? Какой стартап или стартапы конкретно вы имеете в виду? Что вы делали в этом стартапе, пока зумеры его дрючили? Если вас там не было, то снова: откуда вы это знаете?

Я был в десятке разных проектов совсем разного направления. Почему меня туда занесло ? Потому что платят нормально, а мне без разницы где говно чистить. Если говорить конкретно про такие стартапы, тогда общее число разработчиков там доходило наверное до 50. Но реально их там должно было быть 5. Все как один делали свою идеальную архитектуру. Часто бывало, что наступал день Х, приходил жирный инвестор, предлагал дать денег, но либо 100500 сервисов еле тянули онлайн в 100 человек, либо делали анализ кода и говорили потом "до свидания"

Ой, как знакомо :) Недавно участвовал в подобном. Небольшая система мониторинга задолженностей. Порядка 30-40 тысяч транзакций в месяц (в месяц, подчеркиваю). С системой в общей сложности работало 30 пользователей. Нагрузки - никакой. Когда я подключился к проекту, в нем было уже около 40 "микросервисов", причем деплоить их надо было в определенной последовательности, иначе не взлетало и становилось колом. Т.е. микросервисов было больше, чем людей, которые с этим продуктом должны были работать. Возможно, за то время, что меня нет, в систему добавили еще пару-тройку микросервисов.

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

Вышло довольно грустно. И, кстати, до сих пор проект не завершен.

ну вот это типичный среднестатистический стартап о котором я писал) половина этих приложений наверное может работать на aws t2.micro, но "исторически сложилось", что для этого проекта теперь нужна инфраструктура на тыщи баксов и еще целая команда для обслуживания

Во, спрошу знающего человека, раз такой есть.

Я не тащу модные технологии в текущую работу, делаю всё по заветам предков, но из-за этого застрял в легаси, я даже на вёрстку дивами с таблиц перешёл лишь в 2009. Когда я в последний раз писал на PHP году в 2019, то не знал, что такое composer, просто слышал, что он есть. В дргих областях похожая ситуация. Все пишут про микросервисы, но я только в обших чертах представляю, что это. В вакансиях хотят умение настраивать webpack, а мне он всегда попадался настроенным, с нуля же я беру parcel (уже нет), vite или что-то готовое из прошлых проектов. Взять хоть package.json, там есть какой-то exports, но я так и не узнал точно, что он делает (если попадётся между делом, то почитаю, но нарочно искать не хочется), есть только эмпирическое понимание, но сам никогда такого не писал; полагаю, он больше нужен библиотекам.

Вопрос такой: как расти профессионально, где получать опыт работы с этим всем, чтобы можно было сменить работу? А то, всё меньше компаний предлагают условия работы по древним лекалам. Например, на прошлой работе у нас gitlab сам собирал то, что мы в него пушим, и отправлял на сервер. На нынешней — сборка иногда где-то имеется, но потом на сервер нужно отправлять вручную. Чувствую, что технологии опережают меня всё сильнее, а нет никого на нашей работе, кто взялся бы обучать меня новому.

На пет-проекты нет сил. Иногда бывают, правда, в отпуске, раз в году.

В этом году стал применять элементы <dialog> вместо самодельных попапов, вышло весьма удобно. Но это был эксперимент за счёт заказчика. А как иначе?

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

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

Да и со сменой работы морока тоже. Месяц въезжать, что как работает, трудовую книжку почтой пересылать, 2-НДФЛ всякие туда-сюда слать. Я хочу уж сменить работу, так сразу на 5 лет, чтоб хорошая была. У меня за 18 лет три места работы без всяких хитростей. Проблема в том, что навыки отстают, нужно сейчас пробовать внедрять что-нибудь новое. Но тогда будут и неоптимальные приложения тоже. С другой стороны, если я попаду на работу, которая сложнее моих умений, то тоже будет неоптимально. А где человек уже умеет оптимально, там меньше платят.

Жизнь - она одна. Если боятся что-то сделать не так, можно пропустить все. Когда есть семья или какие-то факторы требующие стабильность, средств для маневра мало. Описанные ребята в статьи как раз таки не боятся экспериментировать, просто это надо делать под присмотром и не увлекаться.

Но если не пробовать, тогда никогда и не получится. Риск всегда есть. Можно попробовать найти себе "вторую" работу, если обе на удаленке. В таких проектах, о которых я писал, многие умудряются работать на несколько компаний не подавая виду. Это некрасиво от слова "совсем", но реальность это позволяет делать. Если качество твоей работы будет удовлетворять "начальство", тогда пусть этих работ хоть 5 будет. Иногда нужно просто найти "свою" компанию и это не обязательно значит, что там собеседования проходит намного сложнее или требования выше.

У меня был один пример, где человек работал в достаточно крупной региональной аутсорсинговой компании, где ему на позиции "тим.лида" платили около 100к рублей. Он даже и не думал, что мог получать больше. В итоге он случайно попал в другую компанию на "сеньйора", где ему сходу платили 200к за намного меньшие требования, а еще через полгода он в этой компании понял, что на самом деле его зарплата должна быть около 300к. А все просто потому, что первый работодатель оказался полным мудаком и специально вешал ему лапшу на уши. В итоге за год он "прокачался" от 100к до 300к фактически ничего не делая, а просто найдя "свою" компанию.

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

П.С. Если что, суммы были актуальны где-то лет 6-7 назад

У меня была одна работа в течении 19 лет. Я поменял её, причём с геологии на программирование.

Нет способа справиться с тревогой, не нужно с ней справляться.

Справляйся с новыми библиотеками, языками, проектами, книгами, не с тревогами

Когда я сменил работу, мне было 49 лет и трое детей..

скажу по своему опыту. в работе всегда есть место проектам которые было бы неплохо сделать но и так норм. И вот эти мини проекты можно пробовать делать на новых технологиях. Например телеграм бот который вас уведомляет о какой то ситуации. или есть какой-то рест апи который можно выделить в микросервис а не в монолите дописать роуты итд.

У меня всё настолько однообразно, что выбирать особо не из чего. Компания специализируется на битриксе, я фронтендер, но почти всё время только верстаю. Я предлагал сделать что-то на nuxt, который я уже успел забыть (ещё и 3-я версия успела выйти), но те, кто заказывает битрикс, хотят его визуальную админку, а она требует переплетения фронтенда с бэкендом.

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

Прикольно. Одной БД и пары программистов хватило бы за глаза. Пару программистов - чтобы было кому подменить, когда другой в отпуске.

У тебя, скорее всего, 10 ошибок на 100 строк. Твой усложнённый код только добавляет баги и делает отладку еще сложнее.

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

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

Ой не факт! Если ошибка зарыта, например, в логике действий пользователя. которую ты изначально не предусмотрел то никакой стаический анализатор, линтер и прочие ИИ её не отловят, это к гадалке не ходи! И да, можно с колосальным опытом в трех строчках ловить ошибку, которая воспроизводится при "нелепом" стечении факторов, например при обработке асинхронных запросов.

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

Как бы с 2 строками в час определить где ты находишься?

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

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

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

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

Ха, в период, когда я болел плюсовыми шаблонами, никто не ревьюил мой код. Как же они были неправы

Ха! был и у меня такой период, коллега. Шаблоны, макросы...
Это было чертовски увлекательный и крайне изощренный способ выстрелить себе в ногу

Как узнать, что код сложный? Для меня может быть сложно в JS, что функция возвращает функцию, которая возвращает промис. Мне нужно поломать голову, чтобы понять, запускается этот промис, или мне нужно его выполныть. То есть, p.then() или p().then()? Но это я вижу сложным, а для кого-то это самый простецкий шаблон, у которого ещё и имя какое-нибудь есть, и вообще, "это общепринято". Ну, как термины "вью", "контроллер", все же их знают. Кроме меня :(

Обычно это должно быть более-менее очевидно из названия функции. Ну то есть, условно, fetchOrders должна сделать запрос на список заказов и вернуть промис, а createOrdersFetcher — вернуть собственно функцию fetchOrders (даже если её имя явно не указано). Ну и если есть типы, то в первом случае это будет () => Promise<Order[]>, а во втором — () => () => Promise<Order[]>.

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

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

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

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

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

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

Частая причина костылей - когда требования развиваются вместе с продуктом и нет времени (и других ресурсов) на рефакторинг.

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

"Причесывание кода" может кратно увеличить объем регресс-тестирования. А, соответственно, и его сроки. Вы же не будете выкатывать в прод неоттестированный код? Или будете?

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

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

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

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

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

На моей практике "причесывние* поэтапно намного эффективнее, чем глобальный рефакторинг в ущерб доставке функционала.

На моей практике "причесывние* поэтапно намного эффективнее, чем глобальный рефакторинг в ущерб доставке функционала.

С какими проектами вы работаете?

У нас - то, что крутится на центральных серверах крупного банка. Mission Critical система. Причем, очень большая. Как по объему логики, так и по объему данных. И очень нагруженная.

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

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

Помимо собственно разработчика в процессе задействовано огромное количество людей. А работы много - плановых проектных задач висит на пару кварталов вперед. И заниматься уборкой ради уборки просто физически нет времени.

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

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

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

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

Масштаб системы:

  • около 30тыс программных объектов

  • более 15тыс таблиц и индексов

  • более 150 программных комплексов

Это то, что работает на центральных серверах. А есть еще порядка 60-ти "внешних систем", так или иначе взаимодействующих с центральными серверами.

До банка работал в небольшой команде, занимались разработкой "Системы мониторинга инженерного оборудования зданий". Тоже был достаточно сложный и долгоиграющий проект, который начинали с абсолютного нуля (когда начинали, аналогов не было, по крайне мере в стране точно).

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

Ну и там тоже была недопустима ситуация "поставим как есть, глюки потом поправим". Потому что на систему была завязана диспетчеризация лифтов, а для них есть ПУБЭЛ в котором сказано что без работающей системы диспетчеризации лифты надо останавливать. А это, на секунду, 300-500 лифтов на диспетчерскую И остановка запуск каждого делаются руками силами аварийной бригады...

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

из-за боязни быть уволенными

Самая частая и при этом невероятно глупая причина. Где-то в культурном коде, причем не только в нашей стране, прописано, что увольнение это - катастрофа. А на практике частенько это благо как для компании так и для уволенного сотрудника. Особенно в IT.

Ну когда есть чем банки и семью кормить, то в принципе, не катастрофа )

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

Вспомнился код от уволенного программиста #define true false // счастливой отладки где-то далеко-далеко за правой границей окна.

Эту фигню сравнительно легко найти будет.

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

А разве на собеседованиях спрашивают как вы сделаете что-то попроще? Все хотят знатоков всего того, что вы описываете в статье.

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

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

ведь 99% таких интерфейсов и остаются лишь с одной имплементацией

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

зачем мы на каждый сервисный класс лепим интерфейс и потом его имлементим одним классом

Тут еще зависит от того на каком языке пишете и как реализуете юнит-тесты, ведь далеко не в любом языке можно замокать конкретную реализацию

java

Ну, на сервисные классы, вероятно, и правда интерфейс не нужен, раз в него только делегирование из контроллеров прилетает

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

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

Единственная причина использовать интерфейсный класс (java) - это множественная имплементация. IMHO.
Остальное дает только геморой и бессмысленное время, потраченное на нажатие на клавиатуре.
В 90% случаев.

Вот сначала не пишут интерфейсы, а потом удивляются, почему спагетти-код получился...

Вопрос: как ты unit-тесты пишешь на классы, у которых все внутренние депенденси - это другие классы, а не интерфейсы?

это другие классы, а не интерфейсы?

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

Просто инструментарий пошел по другому пути.

Можно-то, наверное, можно, вообще практически что угодно и как угодно можно сделать, но нафига? Зачем городить велосипеды и усложнять там, где есть стандартные пути решения?

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

Мне, например, ближе стили и подход bouncy castle (ну и больше всего в нем копался по ряду причин). И по использованию интерфейсов и по использувнию тестов.
Функциональный тесты (org.junit.Test) не на классы и отдельный функции, а не функционал целиком. Типа загрузить ключ из файла/кода->подчитать криптограмму->проверить. Включая даже запуск сервера в рамках теста и TCP/IP соединения с ним.
ни одного @Test на отдельный класс (как сферический конь в вакуме) там нет.
Интерфейсы - это API через которое можно вызывать разные реализации. и не более.

назвавать эту либу "спагетти кодом" - ну как то язык не повернется.

А можно привести пример широкоиспользуемой либы с исходниками, написанными под твой подход?

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

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

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

Причем тут хобби...
Это все в рамках основной работы.

  • bouncy castle - Когда возникают противоречивые требования "нельзя вставлять bouncy castle либы в дистрибутив" (типа не кошерно по некоторым треованиям понятно кого). Но будь добр поддержи "это и то" там где нет КриптоПро и прочих покупных (PKСS#7 стандарт, например, и пр.) и... ну не писать же с 0. Приходится "не явно" использовать.

  • jdbc. - а какого фига возгникает то или это непонтяное при переходе с Oracle (когда нужно на переходной период что бы там и там работало). Лезу в код Postgre jdbc и разбираюсь (исходники кода Postgre jdbc это мноooго лучше/красивее чем кривой код Oracle jdbc)

  • kafka client - который неожиданно менятся внутрений подход к организации TCP/IP соединения в новой версии либы и просто переход на новую либу приводит к тупняку и росту потребления ресурсов сервера kafka при пиковых нагрузках. Ни где про это не написано! Только по исходникам и понял что делать и в чем причина.

  • Spring Boot - запрос от эксплуатации "а дайте нам вот такие метрики (хочу и все)". Ан нет их в SpringBoot штатно. Приходится копаться в исходниках и находить куда влезть через рефлексию к найденым функциям и.. и.д. В недрах..

И это все только за последний год..

Примеры, pls, opensource (массового использования а не просто что то с Github) кода который Вам лично нравится и содержат (Вы же на этом настаиваете):

  1. Тесты на все отдельные классы не в рамках общих функциоанльных тестов

  2. Интерфейсные классы не для класических целей описать API для разных реализаций интерфейсов.

Без этого Ваши аргументы субьективно эмоциональные и не иллюстрированы.

Кстати, исходники SpringBoot мне как раз не очень нравятся. Чисто субъективно. Как раз пример того, что я не очень люблю. Когда функциоанл размазан по куче классов. Но и не крайний случай. В коридоре норм..нравится. Т.е. лучше чем мое субъективно "треш код"

Ох, сочувствую. Звучит как что-то занудное и неинтересное. И довольно low-левельное

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

Итого:

  1. Билд занимал минут по 15. Запускаешь билд и можешь хоть гулять пойти. Никакого состояния потока, постоянно отвлекаешься на что-то

  2. Если ты вносишь какие-то изменения, и что-то где-то ломаешь, то вместо внятной и простой ошибки "сломалось то-то, там-то и по такой-то причине" ты получаешь HTTP 500, и good luck have fun дебажить весь этот флоу в попытках найти, что и почему сломалось

  3. Никакого контроля за внутренними состояниями классов. Поскольку они ещё и пытались в Clean Architecture, то у них были классы вида ЧтотоТамUseCase, в котором было по 1000 строк кода, 50 методов и по 20 филдов. Добавляется какой-то новый use case? Просто лепим 51-ый метод, а к нему и ещё 2 депенденси, потому что существующих 20-ти не хватает. Мои попытки хотя бы те места в коде, которые затрагиваются какими-то изменениями, выносить в отдельные классы с ограниченным скоупом, убирать уродливые switch-case и instanceof и покрывать это дело тестами, встречались в штыки "это слишком сложно, нам такое не нужно"

Интерфейсы они, кстати, использовали. Жаль только не так, как надо

Я на этом low-level отдыхаю. Только я и код и никто третий не мешает. И задачи на самом деле не тривиальные.

И это лучше, чем попытки понять что клиент хочет, да еще через менеджера посредника. А особенно, если выясняеся, что клиент сам не понимает чего хочет.
И ревизия чужого кода. простановка задач и т.д. и т.п.
И типичное затыкание дыр в работе со скучным "возьми из БД и отдай json в HTTP(s)"

Считал их дорогими в обслуживании, и что они слишком фиксируют внутреннюю логику, в то время как проверять надо процесс целиком

И я его понимаю. Потому что на его месте. С теми же аргументами.

Все эти аргументы можно свести к одной фразе "Сроки выпуска дистрибутива".
А все что этому мешает подлежит кастрированию.
В том числе и оптимизация, которая займет несколько дней, но позволит вставить красиво 51 метод за 5 минут, вместо пол дня. Но.. вероятность, что появится 52-й метод неизвестна в принципе. Да и оптимизация наверняка что то сломает неожиданное (плавали.. знаем).

Цели все же не выпустить красивый код. А просто выпустить в сроки работающее и не фатально ломающееся на основных ветках логики ПО.

Хорошо быть просто разработчиком и писать в соотвествиие со своими "внутренними потребностями прекрасного".

Я бы может быть то же писал бы юнит тесты на каждую функцию/класс (не.. не писал бы. скучно и монотонно это), но тогда это чаще всего придется делать по ночам. Так что, если есть функциональные тесты для "чернового тестирования" перед передачей в тестирование, а потом в эксплуатацию - уже хорошо.
Написание тестов отдельных классов и функций отнимают времени как бы не больше чем на код, который они тестируют. А наличие таких элементарных тестов вообще не гарантирует, что хотя бы "прямой функционал" без ошибок.
А функциональный тест дает хотя бы какую то уверенность, что на бою у 90-98% клиентов (которые пойдут по основной ветки логики) проблем не возникнит и сервис не ляжет.

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

А все что этому мешает подлежит кастрированию.

Проблема этого подхода в том, что он оптимизирует время локально, но катастрофически продалбывает его на длинной дистанции. Забив на какое-то место в начале, сделав как проще, и забивая на него в дальнейшем, когда из раза в раз приходится залезать в один и тот же код и вносить изменения, в конечном итоге можно получить что-то крайне сложно понимаемое и поддерживаеиое. А если такое место ещё и без тестов, то и сломать что-то неочевидное и относящееся вообще к чему-нибудь другому, но по воле случая плохого кода зависящего от этого же кода

В том числе и оптимизация, которая займет несколько дней, но позволит вставить красиво 51 метод за 5 минут, вместо пол дня

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

А наличие таких элементарных тестов вообще не гарантирует, что хотя бы "прямой функционал" без ошибок

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

интеграционые тесты (ну в моих реалиях) которые в коде @Testt) - это, как правило подготовленные по документации примеры "прямого пути". Т.е. пути, по которому пойдет платеж (мои реалии) для 99% клиентов. Интеграционые, потму что проверяется не функционал отдельных кусков. А все в целом (эмуляция как бою, включая работу с БД, kafka и пр.).

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

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

Но практика показывает, что такой подход рабочий и коэф. готовности вполне укладывается под требования ЦБ.

А так, да.. гарантие отсутвие проблем в ПО - это обесточнный ЦОД с сломавшимся аварийным генератором. В остальных случаях поведение ПО предсказуемо с точностью 50 на 50 (либо работает - либо сбой). Как с динозавром на улице из анекдота.

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

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

По моей статистике, в случаях, когда судьба продукта не ясна на старте, в 90% случая он либо умирает либо не требует особого развития (живет себе и живет корявым архитектурно).
Конечно это не касается тех продуктов, судьба которых известна на старте. Типа СБП :)

Именно по моей статистике, вкладываться в архитектуру нового с расчетом, что оно взлетит это на 20% не угадать с "направление взлета" и выбранная архитектура ПО не подойдет под.
И 70% - вложения окажутся не нужными (умрет или не будет развиваться)

Остается 10% на "угадал". Печальная статистика. Чаще всего приходится переделывать практически с 0 при росте нагрузки и/или измененрия/увеличения функционала. Или мирится с корявостями, если особой оптимизации под производительность не нужно и не понятны перспективы "что дальше то с этим будет"
Потому что "не угадал" (ясновицем нужно быть что бы учеть будущие требования клиентов о которых они сами еще не знают).

Вот Ваш пример попадает под "не угадали". (ну или сделали на авось. контекста я не знаю).

нет "золотой пули"

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

Какая у вас там сложность возникла при навешивании @Autowired аннотаций на класс, а не интерфейс? В чем сложность у вас? У спринга нет сложности создать бин из класса без интерфейса

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

Так @SpringBootTest сам умеет автовайрить зависимости, хоть моканые, хоть реальные. Правда один раз таки придется тестовый контекст настроить.

Да даже и с классическими юнит-тестами, мокать хоть интерфейсы, хоть реальные классы, разницы нет.

Не, с интерфейсами все-таки проще, у них физически нет депенденсей внутри, которые надо будет мокать

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

Прям дежавю какое-то, буквально на этой неделе с лидом обсуждали такой же вопрос.

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

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

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

Вообще, разделение логики на слои "что можно сделать?" и "как это делается" - это очень мощный концепт

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

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

Но всегда придет умный лид, который говорит: "Полиморфизм благо, на все сервисные классы нужны интрефейсы"

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

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

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

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

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

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

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

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

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

Каждый раз эта альтернатива - или понятно как читать (функцию на 200 строк сверху вниз), или понятно как расширять (когда этих функций 20 в пяти классах), но тогда фиг прочитаешь и контекст в голове соберёшь. FizzBuzz Enterprise Edition получается. Была бы у IDE функциональность "inline кода для чтения программистом", чтобы все эти микрофункции можно было бы слепить в кучу, убрав параметры и return и посмотреть на большое полотно - было бы проще.

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

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

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

Так не бывает. Даже тупое чтение данных с локального диска (раз имплементация) и откуда-нибудь с сети (два имплементация) - могут выдавать разные ошибки и проблемы. А входные данные (имя, откуда читаем) и выходные (что, собственно, прочитали) - одинаковые, да. Принцип подстановки Лисков, вещь, конечно, хорошая, но далеко не всегда выполняется и даже может выполняться.

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

Вот почти мой случай. Только у меня в имплеменатации №1 реальный входящий поток, а в №2 - восстановленный из таблиц БД. Нескольких. И в какой-то момент нужно добежать и перепрыгнуть на основной. Но бежать как-нибудь так, чтобы не уронить SLA на реализацию, загрузив на 100% CPU. Весело...
Но `throws Exception` в сигнатуре интерфейса решает

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

В чем проблема внутри имплементации ловить exception и обрабатывать его нужным образом

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

Да-да-да. Интерфейс клиента модуля -> клиент модуля -> Интерфейс сервиса -> сервис -> интерфейс репозитория -> репозиторий -> еще пачка "внутренних" репозиториев с со своими интерфейсами -> где-то там внутри код выборки. Тихий ужас. А еще миддлвары, в которые новый метод тоже надо руками прописывать каждый раз.

это вы еще с JPA Repository не сталкивались, там вовсе никакой реализации может не быть, голый интерфейс описал и готово.

Если у вас строго типизированный язык, то могу предположить, что с интерфейсами проще тестировать. Например, используя dependency injection. Но у меня контекста мало, поэтому это только предложение)

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

Сейчас "дефоултная общепринятая" структура кода подразумевает, что ради десяти строчек кода надо создать целую инфраструктуру. И create-react-app, springboot и т.п. в этом помогают.

"На случай роста", говорят.

Хотя я, по совести, написал бы всё в 2 файла по 50 строк. 99% софта всё равно дальше расти не будет.

А то цепочка"визуал-fetch-контроллер-сервис-репозиторий-entity-база" ради одной таблички, конечно, удручает.

да, еще лучше это отражается в современном веб-фронте. Там обычно можно удалить процентов 80 кода. Для меня когда-то было открытием, что какой-то начинающий фронт мог собрать приложение на Vue.js, но не понимал, что можно сделать в html блок с кодом и что-то в нем выполнить... ???

Тут есть проблема. Упростить все обратно после экспериментов 'сделать так, чтобы делало то, что надо, а не выполняло бесформенные пожелания' - это отельное время. Потому что писать сразу просто - это порядком сложно.

На фоне того что написанный сложный код - уже работает, а упрощение его по дороге неизбежно пару раз поломает -- этим не занимаются.

Простота хуже воровства

Архитектуры проектируют потому что их (внезапно) необходимо проектировать, а не ляп-ляп и в продакшн

Все зависит от проекта. Чтобы построить сарай, не нужен Гауди.

ничего не зависит от проекта.

что сарай что дворец строят по типовым нормативам, по сметам, по документации, по договорам подряда, по реестрам егрн - это все рутина пятикратно пережеванная

так же как в айти типовые фреймворки, типовые паттерны проектирования и пр.

автор в противовес заявляет: если есть говно и палки то ПРОСТО построй сарай из говна и палок

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

Да, я тоже через это прошел в 22 года. Начитался много книжек по C++ и строил многослойное с темплейтами, сложной иерархией классов итд - работало на порядки медленнее чем надо и вместо простого кода на несколько строк требовало кучу файлов. Потом от этого отказался в 25 лет и стало так хорошо. Сложность должна быть не в этом месте.

Вообще это стадия через которую многие проходят. Самое стремное когда коммерческая компания берет трех недавних студентов и они строят таким образов важный продукт компании. Например такое случилось с MIPS Technologies и их симулятором CSim в районе 2005-2010 годов. Симулятор имел два режима - на уровне инструкций и на уровне моделирования конвейера. И студенты не понимали хардвера - боже что они нагородили - это страшно глючило и имело неверные абстракции аппаратных объектов, в пять раз больше кода чем нужно и ломалось при каждой новой фиче. И от этого продукта было очень тружно избавится, так как есть стали использовать клиенты и они не хотели переходить на новые, а хотели починить старое.

Тоже нашёл свой код, который написал в ~22 года

Это когда я прочитал всего один учебник "PHP+MySQL", и не факт, что до конца.

Медленно работало или медленно собиралось? Так-то темплейты в рантайме не дают оверхеда, вроде. Зато на сборке...

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

Оптимизирующий компилятор дает прирост 5-10% максимум. А вот плохой алгоритм или сильный оверхед по причине избыточного количество уровней абстракции может понизить производительность в разы.

Отличная статья. Сделать проше, в наше время это "не модно". Сделать проше это значит сделать без фреймворков, а это уже плохо (кто потом разберётся в этом всём). Проше это когда всё понятно, читаемо, подержимаемо и легко изменяемое. Сделать проше и чтобы оно работало, это мастерство (как в теории ТРИЗ).

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

Проше, в наше время, никому не нужно.

Когда поддерживаешь какие либо продукты очень долго (> 5..10лет. Представляете.. и такое бывает), то вдруг узнаешь, что:

  1. Фреймвоки умирают или трансформируется принципиально (GXT например). А коду то на пол ляма строк..

  2. Предыдушая версия не поддерживается, СИБ требует переходит на новую (дырки обнаружены). А в новой вылезают неожиданные баги или приходилось заклаываться на внутренние особенности, а они уже другие.

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

Иногда оказывается что старое ПО, написанное без фреймворков поддерживать гораздо проще чем...

Это означает, что есть внутренний фреймворк. Где на новую версию не просят перейти потому что версий никто не считает.

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

конечно есть..
Если подумать и покопаться в истории всех фремворков то они все родились как чей то внутренний и потом стали "общественными". Просто внутренние не всегда дорастают до общественных. Чаще по причине НДЛ или "это наше ПО".

Кстати, слышал такую позицию на конференции одной. Причем достаточно агресивную от разработчика. Типа "мы" в это денги вложили. никакого opensource.
Хотелось у разработчика спросить "а ты акционер что ли". А если нет, то нафига вообще с докладом вылез по продукту который ни OpenSoure делать не собираетесь ни продавать. Кому интересны ваши внутренние "шаги на пути к просветлению".
Но не стал обострять..

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

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

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

А что такое "проще"?

Да, тоже об этом подумал - что вообще-то, книги и опыт как раз учат тому как сделать сложные вещи простым образом, т.к. программирование in big (то что касается архитектуры) как раз заключается в борьбе со сложностью. И если кто-то неверно это понял, то это лишь его проблемы.

И не стоит путать простоту в хорошем смысле с наивной реализацией, заточенной под простейшие случаи. Хороший программист все-таки думает о краевых случаях, в уме прокручивает всевозможные сценарии, и поэтому его код более жизнеспособен. А студенческие поделки это не production-ready, в проде это просто упадёт или будет сломано первым же кулхацкером.

опять "в хорошем смысле", "жизнеспособен". Сплошная вкусовщина.

Но на самом деле "Просто" - объективная характеристика. Из математики, из теории автоматов. Ее можно измерить. И, самое главное, она хорошо коррелирует с субъективной простотой (можно почитать исследования "What makes rules complext" или McCabe "Cyclomatic complexity")
Мы должны разделять простоту объективную и субъективную. Субъективная обычно основывается на знакомости. Знаешь код, знаешь шаблон - для тебя легко. Не знаешь, новое - сложно.

Берешь переписываешь - становится легко. Но упростил ли ты или просто узнал? Стало ли лучше объективно?

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

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

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

Ключ к хорошим решениям не упороться в идеальную архитектуру или упороться в противоположную мега простоту. Ключ в золотой середине. Именно по этому это так сложно.

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

а что далеко ходить, вот пришел я на новую работу как-то, ознакомился с бизнес-задачами, и потребовалось ввести несколько новых операций помимо зашитых в коробку. Я запрашиваю IT - ребята, а "операция" - это, по-уму, отдельный объект, который в реквизитах документа зашивается, где у него справочник, я его не вижу? И мне приходит ответ, что операции - это просто перечисление, соответственно пользователь ни с какими правами не может создать ни новой операции. ни документа с реквизитом новой операции, чтобы эти операции учитывались как-то. Только корежить коробку, только хардкор. Код-то простой как три копейки, а калькуляцию нарисовали 260 тыр добавить одну складскую (!) операцию. в WMS, потому что они все разнесены на конечное количество регистров, каждому свой, и там глубокая доработка. Одним словом - меняется физический процесс в организации - добавляется дополнительная операция обработки груза, например, ваккумирование пленкой, все бегут к фирме-разработчику и за 100500 денег просят добавить операций, потому что архитектурно они прибиты к стенке гвоздями на уровне разработчика, тупо перечисляются через запятую, и пять копипащенных стандартных обработок в теле, отличающихся только элементом перечисления.
За такое вырывал бы руки и пришивал бы к плечам без наркоза.

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

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

а я-то тут при чем? Не я ж разработчик. Я пользователь на уровне технолога по складу и WMS, мне надо кастомизировать коробочный продукт под процессы, понадобилось добавить операций в WMS, а там архитектурно такое, что если писать как по-уму должно быть, то это глубокая доработка, коробка слетает с поддержки автоматом.

Зато у конкурентов есть ниша для конкуренции.

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

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

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

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

Анекдот эпохи моей юности

Старый доктор оставил вместо себя сына, недавно окончившего мединститут, и уехал в отпуск. Возвращается, а сын ему заявляет:

- Я тут Павла Моисеевича вылечил. Ты его тридцать лет лечил, а я его - за один месяц!

- Идиот! Я на его почках тебя выучил, машину купил, дачу построил... А ты его... вылечил!!!

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

чтобы пилотам скучно не было, они начали бочки крутить на высоте

Опять кренделя выделывать?! О не-е-ет!

Автор, а что Вы скажете про Clean Architecture? Контроллеры, сервисы, репозитории, сущности, адаптеры, вот это все.

Где оно нужно (если нужно), а где нет?

как я и написал в статье - где иначе сделать невозможно. Маленькие проекты, если хорошо идут, становятся рано или поздно большими. Обрастают определенным кол-вом полезных функций для конечно пользователя. Будь-то веб-приложение или та же ОС. На определенном этапе появляются похожие структуры, поддержание каких-то простых вещей становится с каждым разом сложнее. Вот тогда, ПО МОЕМУ МНЕНИЮ, ТОЧЕЧНО пора использовать определенные паттерны и другие подходы. Иногда частично это может проявлять себя и в простых проектах, например модульный подход к написанию веб-приложений часто себя оправдывает на достаточно большом интервале времени даже если сразу начать его применять, но, к сожалению, даже такой распространенный подход очень часто реализовываеться неправильно и многие начинают запутывать модули между собой вызовами API или на уровне хранения данных сложными запросами с джоинами (которые надо будет переписывать, если модуль действительно надо будет в будущем отделить в полноценный сервис)

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

это не про рефакторинг. Рефакторинг - это когда что-то давно упустили и теперь не знаете что с этим делать. В следующий раз, когда надо будет добавить что-то новое - посмотри на старый код, возможно его как-то можно объединить или переиспользовать. Изменения должны происходить постоянно. Это определенный навык красноречия должен еще быть. Нужно уметь обьяснить менеджеру, тил.лиду или вообще об этом не сказать, а сделать как должное (это некрасиво, но если уверенность 120%, тогда иногда можно). Для этого нужно знать хорошо кодовую базу либо не лениться шерстить по проекту. Ревью кода в теории должно помогать избегать таких проблем.

Хорошо вам, когда есть, кому сделать ревью. У меня за 10 лет таких людей не нашлось :) То ли мне доверяют, то ли всем всё равно.

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

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

Это и есть рефакторинг.

Лучше так: "Решай простые задачи"

Ну, и риторическое: "Код, который сложен для одного, может быть простым для другого"

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

качественная оценка должна быть. Сколько полезных функций в приложение ты можешь добавить за единицу времени? Если немного, тогда проблема не в том, что ты долго разбирался, а в том, что это написано сложно. Разработчик разработчику рознь. Если ему 40 лет и он уже 20 лет пишет код - это еще ничего не значит. Может он все это время на пыхе шаблоны для Wordpress настраивал

Напомню, что джуном (в западных компаниях) считается человек с менее 6 годами опыта.

Будет пруф на это утверждение?

Что считать опытом? Я годами ковырял чью-то самописную CMS на PHP, дописывая примерно треть для каждого следующего магазина, так как там не было даже AJAX-корзины; затем забросил PHP, 3 года писал на 2-м vue, потом уволился как раз когда весь мир переходил на 3-й vue, а после этого всего один проект сделал на 3-м, но никто даже не проверил качество того, что я написал, так как нет человека с нужным опытом. Кроме того, это ещё и первый раз, когда я писал на TS, вынося типы так, как мне казалось удобным.

Правда, всё равно потом сам стал путаться, хорошо хоть догадался типы называть с буквы T. Но даже user типа TUser, который получается из того, что прислал сервер, с помощью userConverterFromAPI(serverAPIUser: TAPIUser): TUser создаёт мельтешение в глазах, а всё это ещё нужно импортировать из правильного места, плюс у меня там генератор пустых юзеров, чтобы приложение не ломалось, пока API шлёт ответ.

Сколько лет у меня опыт?

Нужно ли приплюсовать к опыту 5 лет сисадмином-эникейщиком-поддержкой? А лет так 6 вёрстки на таблицах с onmouseover вместо :hover?

Тут надо всем любителям паттернов напомнить что есть ещё один - KISS: Keep it Simple Suka! /s

И YAGNI - You ain't gonna need it.

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

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

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

"Я не переусложняю код. Просто я не знаю как сделать ПРОЩЕ!"

Я конечно дико извиняюсь, но как мне тогда получать опыт? Если я условный Джун, и работодатель не сильно торопится повышать мне зарплату, мне никто не даёт код ревью, и моим обучением целенаправленно никто не занимается, то разумеется, я буду выжимать максимальную ценность в виде опыта, из предоставленного проекта. Чтобы потом на следующем собеседовании, на которое я пойду из-за того, что зарплату мне повышать откажутся (проще ведь потом искать нового сотрудника), мне было что рассказать.

Разумеется всё в рамках разумного, но, да, я буду делать mvc, даже если там лучше подошёл бы mvp. Чтобы потом на собеседование рассказать какие плюсы и минусы я нашёл в таком подходе.

для этого нужно писать свои проекты. Сообрази себе на досуг простую онлайн игру и тренируйся сколько влезет. На роботе учись КАК ДЕЛАТЬ НЕ НАДО, просто выполняя свои задачи, я думаю на любом проекте можно найти места, которые открывать страшно. А вот в домашнем проекте делай так, как считаешь нужным. Все равно ты потом перепишешь это 5 раз так и не найдя того самого идеального решения. Но зато попробуешь много других способов и будешь опять знать КАК ДЕЛАТЬ НЕ НАДО

"If you'r homeless, just yourself a house" 😁Блин, иногда хочется немножко поспать, чесслово. Плюс выгорание никто не отменял. Если после 8-часового рабочего дня сидеть ещё сверху часа четыре над петом, можно расхотеть программировать вообще. Не подумайте, я не наношу целенаправленный вред в угоду себе. Просто если где-то вижу возможность сделать посложнее и поинтереснее, например реактивный стейт на rxjs вместо зуштанда, то я лучше сделаю как интересно, и лутану опыта.

Это буквально называется CV driven development. С огородом, который ты городишь, будет разбираться по итогу другой чел, ни в чём не виноватый. Если у тебя есть совесть и ты не хочешь, чтобы из-за тебя страдали другие, то ты прекратишь этот кринж

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

Пожалуйста, не пишите за всех. Пишите хотя бы "большинство" или "почти все", так вас хотя бы сложно будет опровергнуть. А сейчас опровергнуть легко: я никогда не приписывал компетенций. Да у меня в резюме их особо и не было указано. Если я буду писать, я напишу там JS (Vue), TS, вёрстка. Что ещё туда можно добавить? React же я туда не напишу, ведь я по нему не отвечу ни на один вопрос, я вообще его ни разу не трогал. Один раз открывал документацию по Lit, тогда же и закрыл, не стал забивать себе голову.

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

Долой перфекционизм, виват минимализм!

Тяп-ляп и готово. Работает? Переходим к следующему проекту.

Какие баги? Это заботы следующей команды. Ну или я могу посмотреть... За отдельную плату...

Тут кроме ппкс сказать нечего, автору зачет.

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

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

Попробовали? Не получилось, или получилось, но так, что самим непонятно?

А в реальности оно так и есть.

Так а вывод-то в вашем комментарии какой?

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

Вот это вот всё приходилось реализовывать, полагаясь на здравый смысл и опыт наломанных дров? Или всё же нашлась пара другая умных книжек, которые поспособствовали осмысленному созиданию? Истина где-то посередине?

А в реальности оно так и есть.

Что есть в реальности (я не понял)?

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

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

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

Тут в целом нужно избегать крайностей. Это касается и ситуаций, когда у нас сплошной текст вместо комфортного кода. В целом, такие советы не являются универсальными. Например, можно вспомнить вечный спор о собственной реализации паттерна Repository поверх ORM.

И типизацию, типизацию не забудьте!
У серьезных пацанов типы должны включать по крайней мере тройную вложенность дженериков с использованием keyof, Record, Partial и Omit.

все эти подвыперты в типах возникают из-за того что разработчик js библиотечки сделал ПОПРОЩЕ - и теперь в зависимости от фазы луны возвращает или bool или string или объекты в пяти разных вариациях. Как это типизировать без тройной вложенности, объясните?

Представленный подход вызывает ассоциации с известным антипаттерном «Золотой молоток», где универсализация инструмента приводит к неоптимальным решениям.

1) Да, есть такие проекты, где 2/3 IT отдела можно уволить без потери качества продукта

2) Но тогда IT менеджменту не кем будет руководить. Останется 1/3, которые и так понимают, что нужно делать.

3) И даже если 2/3 "экспериментаторов" уволить, а 1/3 "практиков" оставить - "практики" от этого больше денег не получат. Поскольку зарплаты по грейду.

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

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

Т.е. получается конфликт интересов заказчика и исполнителя, по сути. Такое можно наблюдать и в строительстве/ремонте - так же постоянно сроки срывают, делают по 100500 проводов на 2 комнаты и пр.

Бизнес же не оценивает количество строк, он смотрит на количество закрытых задач. У меня менеджер вообще не в курсе, что я добавлял, что удалял. Есть задача и есть время, которое я на неё истратил.

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

он смотрит на количество закрытых задач

Так тут же обратная связь. Оценивает срок задачи кто?

Если дашь оценку 2 дня. Бизнес такой - а чего так долго? Смотрит по итогам 2 дня и 10 срок кода. Балду пинал. А если 2 дня и 600 строк кода - значит все ОК, разработчик был прав а бизнес не знает всех нюансов, значит в следующий раз для подобных задач нужно планировать больше времени.

Если будут сокращать или увольнять по статье, то вряд ли будут смотреть на сложность кода

Будут смотреть сможет ли тебя кто-то заменить или нет.

Если там 10 простых строк, то не оценивайте в два дня. У вас задача в том, чтобы дать такую оценку? А если эти строки требовали того, чтобы два дня разбираться, то можно так и сказать начальству. И заметить, что теперь следующая такая задача потребует просто 10 строк, а не двух дней и 600 строк.

Если там 10 простых строк, то не оценивайте в два дня.

А здесь дело вот в чем. Люди переоценивают свои когнитивные способности за счет копирования. Когда копируешь - кажется что ты решаешь почти сам. Но нет, ты просто копируешь.

Вера в то что 10 строк за 2 дня мало - незыблема. Скопировать 10 строк - мало. Прийти своим умом - может быть и норм.

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

Дело вот в чем: к реальной картине мира бизнес сам не готов. С одной стороны бизнес хочет чем проще - с другой стороны все-равно есть вера в то что 10 строк за 2 дня это 100% мало.

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

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

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

Один человек нашел начальника - писал мало, но получал все-равно высокую оплату. И он подсчитал - получат 7 долларов за нажатие кнопки и 7 долларов за отжатие. Готов ли бизнес к этому? Думаю - ответ очевиден.

В корне всего вера что нажатие и отдельно отжатие кнопки НЕ может стоить 7+7 долларов. Под эту веру приходится подстраиваться.

И заметить, что теперь следующая такая задача потребует просто 10 строк, а не двух дней и 600 строк.

Дутых 10 строк? Ну дутых 10 не бывает - там же множитель. Даже одно мелкое значимое изменение займет около 100 строк.

Не поверят

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

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

Вы хотите идти против тренда. Тренд всеобщий - раздувать. Вся наша цивилизация дутая. Смысла мало.

Вам придется доказывать что вы правы.

К примеру, вместо фреймворков - использовать голый чистый JS, не тянуть 100500 библиотек в проект, как все это делают.

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

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

Сейчас принято делать видимость - чем больше видимости и чем меньше смысла. Все мы так живем, все погрязли в этом. А против тренда идти всегда тяжело.

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

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

Она не то что усложняется - когнитивная нагрузка такая же. 10 чистых строк написать так же сложно для мозга, как 600 дутых.

Но дело вот в чем. Бизнес не поверит что 10 строк это сложно. 600 дутых - да, поверят. 10 - не поверят.

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

Т.е. реальность такова: либо писать 5-10 строк в день чистых за те же деньги. Либо 200-300 дутых. Но не получится писать 200 чистых. Бизнес, как правило, не готов принять первый вариант - хочет чтобы и дутости не было но и объем работ не падал. А так не возможно. Когнитивные способности среднего человека очень не велики на самом деле. Устанет, запутается. И будет смешно что там всего 20 строк а он над ними 2 дня пыжится. Когда 600 - хотя бы не так позорно.

Кому действительно нужно будет усложнить твой код — тот и усложнит, может это даже будешь и ты, но пока твоя задача — написать свой кусок так, чтобы его можно было прочитать, понять и модифицировать за 5 минутЕсли тебе не хватает 5 минут, чтобы внести простой фикс на 3 строки, — ты где-то явно свернул не туда.

Э, брат, не гони гусей! Только понимание бизнес-логики стоящей за кодом может протребовать 5 дней. А уж за при понятной бизнес-логике увидеть паттерны кода ее реализующие вот задача кодера, думающего о других. И паттерны эти могут быть сложнее. И думать о других это опция, не обязанность. В ЕГО, автора, представлении он то вообще не знал, что другие вообще будут править этот код. И думал так же как и Вы - кому надо будет "упрощать/усложнять/разбираться/править", тот и сделает.

Пока все с его стороны честно. А за техдолг да, платить не принято. Но это возможно совсем не к автору претензия.

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

У меня был и есть проект, который был собран на коленке для менее чем 10 клиентов и до 1000 документов в месяц на всех. Не было никакого анализа, архитектура тоже на коленке, лишь бы работало. Это был придаток к другому продукту, который просто принимал json и перекладывал их в БД или отправлял дальше.

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

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

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

Так что нет, и еще раз нет. Сначала предварительный анализ, вот типа как на собесах по системному дизайну:

  • Вопрос: сколько потенциальных клиентов, ответ: ну как минимум все те, кто уже есть у компании и пользуются существующими продуктами компании

  • Вопрос: а какая нагрузка? Ответ: ну если посмотреть наши другие продукты, то вот тут например 500 000 документов (не запросов, один документ - это десятки-сотни запросов в базы данных и другие системы, пока он проходит весь воркфлоу) в день

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

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

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

ЗЫ: и в первую очередь надо закладывать логирование и телеметрию запросов (чтобы потом не гадать на кофейной гуще) и авто-тестирование (чтобы потом не было мучительно больно дорабатывать фичи).

просто != тупо. Я думаю даже в вашем случае это все равно было лучше, потому что переписать запутанный код намного сложнее, чем то что у вас получилось. Ну и видимо разработка все таки велась достаточно оперативно. Если с другими проектами угадали - ребята возможно более опытные делали или просто угадали. Если в конце ничего не переписывали, значит вначале хватало гибкости для каких-то серьезных изменений. Тупой код - он тоже плохой, но лучше запутанного. Бизнесу нужна гибкость - куда ветер дует, то и делаем. Если сходу заложить что-что сложное и прибить гвоздями, потом тяжело будет следовать за ветром и будут те же костыли, что и с тупым кодом, только покрыты кучей слоев абстракций. Есть крупные проекты, которые стоят миллиарды долларов и скорее всего выглядят как ваш пример. Никто просто не знает об этом. Дело в том, что они может и стоят столько, потому что в начале было более правильно распределение ресурсов внутри компании между всеми проектами и это сыграло определенную роль в таком вот росте.

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

Это всё началось с изобретения слова “бойлерплейт” в 2012 году. Всем было страшно, что им придётся писать аж по три строки вместо одной. Поэтому все начали насиловать компиляторы и добавлять в них новые функции — только бы (НЕ ДАЙ ГОСПОДЕ БОЖЕНЬКА!!!) не писать дополнительно два символа.

В 2025 году у нас есть ЛЛМ. И не надо врать — я знаю, что вы не набираете код, за вас это делает ЛЛМ. Я не говорю, что вы не вычитываете этот код и не перепроверяете всё. Нет. Но печатает за вас ЛЛМ. И это — нормально.

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

Пусть ЛЛМ за вас напишет файл с 500 строками кода, где каждому URL дан чёткий метод. И если вам надо будет переименовать 300 из этих методов, то пусть ЛЛМ это и сделает. Не велика проблема.

В 2025 году можно смело откатить все нововведения Яваскрипта до 2016 года — и не париться больше в попытках улучшить язык. Просто сделайте его стандартом и больше не меняйте. Пусть ЛЛМ будет страдать. Нам не страшно.

Зато потом это будет проще понять и прочитать, чем вспоминать, что делает последовательность символов ?./\ ﷼ℬ в вашем коде и какой транспайлер мне надо поставить, чтобы это компилировалось в Google Chrome версии 18384572.

Красавчик. Такие аналогии ни одному ИИ недоступны.

Этим сильно страдает unity геймдев в СНГ, особенно мобильный. Их карго zenject-культ, когда всё натянуто на фабрики, сервис провайдеры, декораторы и прочие интерфейсы ради интерфейсов, только потому что так написано в книжечке.

Хотя почти все культовые игры на Unity и C# (Ori, Inside, Valheim, Terraria, ...) по максимуму используют синглтоны, GetComponent() в рантайме, статические переменные где только можно и вообще пишут максимально связный, но простой и понятный код.

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

Паттерны, слои и DI - это лекарство. Но в плохих руках - яд. Что я понял за свой галерный опыт: документация - лучший паттерн.

Осталось понять, что такое простой код.

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

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации