Да, это очередная статья по чистому коду. Но по разным источникам, соотношение времени, затрачиваемого на чтение и написание кода, может достигать 7 к 1 и даже больше. Когда вы исправляете ошибку, добавляете новую функциональность или проводите рефакторинг, вы сначала погружаетесь в логику, написанную другими людьми (или вами же, но несколько месяцев назад). Именно поэтому читаемость кода становится более важным фактором, чем скорость его первоначального написания. Нечитаемый код — это технический долг, который замедляет всю команду и увеличивает стоимость разработки в долгосрочной перспективе.

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

Основные принципы читаемого кода

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

Я не хочу чтобы эта статья была еще одной сводкой по «правильному коду». Если хотите писать чисто академический код(что априори не возможно), то рекомендую почитать Роберта Мартина »чистый код». Поэтому моя статья пропагандирует только «рациональную чистоту кода». То есть только там, где это надо (проекты которые поддерживаются).

"Лучший код - это тупой читаемый код."

Код, который не заставляет вас напрягаться, чтобы понять его замысел.

Итак, начнем с очевидного:

  • Понятные имена переменных и функций. Да, это повторили уже 1000 раз и я повторю в 1001. Но все же это основа основ. Имя должно раскрывать намерение. Если вы видите переменную d или list1, вам придется лезть х*й знает куда или прокручивать код вверх, чтобы понять, что это. А если переменная называется elapsedTimeInDays или activeUsers, вопросы отпадают сами собой. Цель — сделать так, чтобы код читался как проза.

  • Принцип единственной ответственности (SRP). Функция должна делать что‑то одно и делать это хорошо. Когда вы видите функцию handleUserData, которая и получает данные из формы, и валидирует их, и сохраняет в базу, и отправляет email, — это красный флаг. Такой код сложно тестировать, изменять и переиспользовать. Разделите ее на validateForm, saveUserToDatabase, sendWelcomeEmail. Сама функция теперь становится дирижером, а каждый кусок логики изолирован и понятен.

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

Современные подходы к code review

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

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

    • Логика: Решает ли код поставленную задачу? Обработаны ли все пограничные случаи?

    • Читаемость: Понятны ли имена? Не слишком ли сложна структура? Сможет ли новый разработчик в команде разобраться в этом коде через месяц?

    • Архитектура: Не нарушает ли код общие паттерны проекта? Не создает ли он костылей?

    • Тесты: Есть ли тесты? Покрывают ли они основной и альтернативные сценарии?

  • Пусть роботы работают. Человек не детерминирован. Рутинные проверки на дублирование кода, потенциальные баги, уязвимости лучше делегировать автоматике. Инструменты вроде SonarQube, CodeClimate встроенные в ваш CI/CD пайплайн , поймают 90% типовых проблем еще до того, как код попадет на ревью к человеку. Это освобождает время ревьюера для анализа более важных вещей - архитектуры и бизнес-логики.

  • Фокус на обучение, а не на критику. Главная цель ревью — сделать код лучше и поделиться знаниями. Вместо директивного «Переделай это» лучше использовать формулировки, которые поощряют диалог: «А что, если попробовать здесь такой подход? Мне кажется, это упростит поддержку в будущем» или «Я не до конца понял этот момент, можешь пояснить, почему выбрано такое решение?». Так ревью превращается из стрессовой проверки в совместную работу.

Паттерны и антипаттерны: объясняю на котах

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

Глубокая вложенность (Arrow Code)

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

Как это выглядит в коде (антипаттерн):

если (кот хочет играть) {
  если (он в гостиной) {
    если (на диване лежит плед) {
      если (под пледом есть коробка) {
        если (в коробке лежит мята) {
          // Ура, кот обдолбался!        
        }
      }    
    }  
  }
}  

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

Как сделать лучше (паттерн «Ранний возврат»):

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

если (кот НЕ хочет играть) {  
// выходим, миссия отменена
}
если (он НЕ в гостиной) {  
// выходим, он занят другими делами
}
если (на диване НЕТ пледа) {  
// выходим, негде искать
}
если (под пледом НЕТ коробки) {  
// выходим, нет нужного укрытия
}
если (в коробке НЕТ мяты) {  
// выходим, цель не найдена
}
// Ура, кот обдолбан!  

Этот подход называется »Guard Clauses». Мы сразу проверяем все негативные сценарии и выходим, если условие не выполнено. Код становится плоским, чистым и понятным, словно прямой путь кота к цели, без лишних поворотов.

Загадочное поведение кота

Что, если поведение вашего кота описывается числами?

Как это выглядит в коде (антипаттерн):

если (состояние_кота === 1) {
// Гладить
} иначе если (состояние_кота === 2) {
// Кормить
} иначе если (состояние_кота === 3) {  
// Не трогать, кот умер
}  

Что значат эти цифры 1, 2 и 3? Это и есть магические числа. Сегодня вы помните, что 2 - это «голоден», а через месяц вам придется лезть в документацию (если она есть), чтобы расшифровать это послание из прошлого. Это затрудняет понимание программы и усложняет её доработку.

Как сделать лучше (паттерн «Именованные константы»):

Дадим этим числам понятные имена.

сonst СОСТОЯНИЕ_МУРЧАЩИЙ = 1;
const СОСТОЯНИЕ_ГОЛОДНЫЙ = 2;
const СОСТОЯНИЕ_МЕРТВЫЙ = 3;

if (состояние_кота === СОСТОЯНИЕ_МУРЧАЩИЙ) {
// Гладить
} else if (состояние_кота === СОСТОЯНИЕ_ГОЛОДНЫЙ) {
// Кормить
} else if (состояние_кота === СОСТОЯНИЕ_МЕРТВЫЙ) {
// Не трогать, кот умер
}  

Теперь код говорит сам за себя. Именованная константа служит живой документацией. Если в будущем значение для голодного кота изменится на 5, вам нужно будет поправить это лишь в одном месте, а не искать магические двойки по всему проекту.

Кормление двух одинаковых котов

У вас два кота, Барсик и Мурзик. Их гастрономические предпочтения абсолютно идентичны.

Как это выглядит в коде (антипаттерн):

// Кормим Барсика
положить_в_миску("Барсик", "сухой корм");
налить_в_миску("Барсик", "вода");
позвать_кота("Барсик");

// Кормим Мурзика
положить_в_миску("Мурзик", "сухой корм");
налить_в_миску("Мурзик", "вода");
позвать_кота("Мурзик");  

Этот подход всем известен как копипаст. Что если вы решите добавить в рацион котов витамины? Вам придется вносить изменения в двух местах. А если котов будет десять? Вы рискуете забыть обновить логику для одного из них, что приведет к гарантированному багу (и голодному коту).

Как сделать лучше(DRY) :

Создадим одну общую инструкцию для кормления.

function покормить_кота(имя_кота) {
  положить_в_миску(имя_кота, "сухой корм");
  налить_в_миску(имя_кота, "вода");
  позвать_кота(имя_кота);
}

покормить_кота("Барсик");
покормить_кота("Мурзик");  

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

Читаемый код и документация

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

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

Для документирования публичных API отлично подходят инструменты, генерирующие документацию из кода, вроде JSDoc, Sphinx, Swagger/OpenAPI.

Практические советы по внедрению культуры читаемого кода

Ну и перед завершением дам парочку советов:

  1. Регулярные мини-рефакторинги. Увидел плохо названную переменную — переименуй. Заметил длинную функцию — разбей на две. Оставляй код немного чище, чем он был до тебя. Это культура маленьких, но постоянных улучшений.

  2. Парное программирование. Это, по сути, код‑ревью в реальном времени. Один пишет, второй смотрит, задает вопросы и предлагает идеи. Это отличная возможность обмениваться знаниями и сразу писать более чистый код. Ну или устроить дебаты о скорости квик сорта и мерджа.

  3. Создайте внутренние гайды. Договоритесь внутри команды об общих правилах и зафиксируйте их. Это снимет большинство споров на код‑ревью и создаст единый стандарт.

Заключение: прагматизм превыше всего

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

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

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

Цель не в том, чтобы писать чистый код ради чистоты, а в том, чтобы писать поддерживаемый код там, где это действительно нужно. Ищите баланс, думайте о будущем вашего проекта и всегда задавайте себе вопрос: «Сделает ли это усложнение жизнь следующего разработчика (возможно, меня же) проще или сложнее?».

Я все. Гудлак!

Комментарии (128)


  1. atues
    01.10.2025 05:31

    Разумно. С этим "чистым кодом" задрали уже. Помнится, пару лет назад на каждом втором (если не чаще) собеседовании спрашивали мнение о книжке дядюшки Боба. Принципы SOLID сами по себе ни хороши, ни плохи: их, действительно, полезно знать и где возможно - применять. Но в отрыве от практики и реальности они - все та же всем известная сферическая лошадь в вакууме. Нормальная книжка, во-многом поучительная, но не надо делать из нее очередной объект поклонения вроде цитатника Мао. Сейчас, хвала небесам, немного успокоились, хотя порой и проскакивает.

    Мне, к примеру, симпатичнее следовать https://ru.wikipedia.org/wiki/YAGNI. "Наворотить" сложное - дело не хитрое, но читать это, а тем более править и развивать, тоска зеленая. Например, у многих начинающих java-программистов, наслушавшихся гимнов во славу ООП, весьма распространен подход: каждый класс должен имплементировать какой-то интерфейс. Да, интерфейсы полезны - кто спорит. Но зачем доводить дело до маразма - ну никак не пойму. Программы по самые ноздри засраны (простите) кучей кода "на всякий случай" - а вдруг понадобится. В 99% случаев - не понадобится. Но мусор останется, в котором кому-то потом придется разбираться


    1. panzerfaust
      01.10.2025 05:31

      Разумно. С этим "чистым кодом" задрали уже

      Автор буквально пересказывает "чистый код" своими словами с шутеечками. Так "разумно" или "задрали"?


      1. maks_demin
        01.10.2025 05:31

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


      1. Enfriz
        01.10.2025 05:31

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


        1. Gromilo
          01.10.2025 05:31

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

          Ещё сама фраза "чистый код" давит: если у тебя не чистый код, значит грязный, а если грязный, значит плохой.

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


        1. Zalechi
          01.10.2025 05:31

          Больше того…

          Я хоть и сам перфекционист, документацию люблю, к унификации всего и вся стремлюсь, но тут меня озарило:

          Давайте возьмем легкую промышленность и тяжелую. Шо, там, станки унифицированы? Ты как инженер перейдешь с одного завода на другой, — а там вообще другой вендор тех-процесс. Все надо перестраивать в своей голове. (Так же и пилоты самолетов, кстати. Когда пересаживаешься за другую модель).

          Или я как инженер связист. То ты в «циске» что-то крутишь, то «джупитер», то китайцы со своим интерфейсом заполонили… (да, это немного другое, но рядом)

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

          И возникает то ли вопрос, то ли ответ — унификация это хорошо, но везде ее не впихнуть, видимо.

          Мой внутренний перфекционист всплакнул.

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


      1. tryamk
        01.10.2025 05:31

        Да! Я надеялся увидеть разумную критику "Чистого кода" - не раз на хабре такие статьи проскакивали, особенно, когда нужна производительность, - а прочитал пережеванный тот же "Чистый код" :(


      1. muhachev
        01.10.2025 05:31

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


    1. Alex_RF
      01.10.2025 05:31

      "Чистый код" это всегда не обязательное требование. К нему лучше стремится - так как за каждым принципом стоит, чей-то пот и чьи-то деньги. А то что про него вместе с ИИ, нанотехнологиями и прочей ересью из каждого репродуктора кричат, то это совсем не чего не значит. Например солидная контора РосАтом(ГринАтом) на собеседование про SOLID спрашивают, в должностных обязанностях стоит - знание SOLID - но проекты у них написаны так, что там про SOLID даже не слышали. Какая единственная ответственность? Там что не функция - так Шива восьмерукая, какой принцип открытости закрытости? Там уже столько наменяли внутри, без расширений - что ногу сломаешь. В результате, как правило после выдачи результатов кандидаты сами с испытательного срока с проекта сбегают или их пинком высаживают за неэффективную работу. Есть конечно "гении" которые умудряются код писать, не боясь что все вокруг осыпятся. Но это же не правильно!!!!!


      1. vater_nicht
        01.10.2025 05:31

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


        1. Alex_RF
          01.10.2025 05:31

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


          1. atues
            01.10.2025 05:31

            Мне кажется, это потому, что нет разумных метрик оценки работы программиста. Количество строк кода? Да элементарно, сколько надо в день: 200/300/500/800? Скорость реализации? Давайте вспомним выбор между скоростью разработки (временем), качеством и стоимостью. Никак больше 2-х не выбирается. Качество? Как его оценить, по результатам тестирований? Пока код не попадет в прод - все это, по большому счету, некое приближение и надежды, что оно не слетит, не развалится под нагрузкой и т.д. А безопасность, устойчивость, пригодность к развитию? Вот честно, я не знаю. Как по мне, главное - качество, пусть за счет скорости реализации. Тогда не будет искушения вставлять пробелы на пару с подельником. Но система устроена так, что только успевай одни дыры латать другими и городить велосипеды. Видел проектик на java как-то. В одном классе было штук 5 методов по 3-4 тысячи строк достаточно плотного кода. Какой там SOLID )))


            1. Alex_RF
              01.10.2025 05:31

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


              1. atues
                01.10.2025 05:31

                Единственное можно сказать если стараешься писать чистый и понятный код - то KPI у тебя будет падать

                Верно. И меня мой же руководитель зачпокает, поскольку его KPI тоже упадет. Со всеми вытекающими


            1. Moog_Prodigy
              01.10.2025 05:31

              Я видел, верю. Были скрипты, которые

              a = 1

              Превращали его то в True, то в char, проверки на валидность (Сотнями раз туда сюда), и затем

              If a = 1 then

              Что то сделать.

              Машина Голдберга.

              Написал дипсику: Есть функция в языке питон, ее смысл - принимает на вход число X и выдает Y. Функция сама по себе X = Y. Задача - написать на питоне эту функцию, чтобы не менее тысячи строк и минимум преобразование (речь идет о целых числах)

              Ответ я приводить не буду, но он его дал и оно работает. И это ужасно, поверьте.


              1. 4kirill20
                01.10.2025 05:31

                Зачем вы там работаете… выходит только ради денег? Или как такая работа может приносить хоть какое-то удовольствие… Мне правда интересно, не со зла, если ответ доход, то окей, пойму


                1. Moog_Prodigy
                  01.10.2025 05:31

                  Я программистом вообще не работаю и не работал. Когда я работал в АСУТП и пришлось разбирать древний код на Сях, который крутился на 486 компьютере. Кто его написал, мне неведомо, но видимо платили именно за количество строк, и это примерно середина 90ых. Или я не знаю, по какой причине можно так делать. Но делали же. И оно работало. И это была почти система реального времени (насколько это возможно под DOS), комп этот управлял самодельной платой на 51 контроллере, которая уже управляла через мощные внешние ключи термопласт-автоматом.

                  А еще могу рассказать короткий анекдот: Итальянцы-программисты. Конец анекдота ))


            1. Dhwtj
              01.10.2025 05:31

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

              сколько времени они выделяют на рефакторинг чтобы обеспечить качество кода


  1. Zara6502
    01.10.2025 05:31

    Код, который не заставляет вас напрягаться, чтобы понять его замысел

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

    А если переменная называется elapsedTimeInDays или activeUsers, вопросы отпадают сами собой

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

    Разделите ее на validateForm, saveUserToDatabase, sendWelcomeEmail

    Главное потом не забыть везде в коде писать по три строчки вызовов подряд (вы кстати дальше сами с этим же и боритесь)

    Создадим одну общую инструкцию для кормления

    а вот выше вы написали что нельзя так делать )

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

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

    Регулярные мини-рефакторинги. Увидел плохо названную переменную - переименуй. Заметил длинную функцию - разбей на две. Оставляй код немного чище, чем он был до тебя.

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

    Создайте внутренние гайды. Договоритесь внутри команды об общих правилах и зафиксируйте их

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

    Читаемый код ускоряет разработку в долгосрочной перспективе

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

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

    Жаль что так мыслят не те кто задаёт тон.



    1. kukovik
      01.10.2025 05:31

      Разделите ее на validateForm, saveUserToDatabase, sendWelcomeEmail

      Главное потом не забыть везде в коде писать по три строчки вызовов подряд (вы кстати дальше сами с этим же и боритесь)

      Не надо не забывать. Функция handleUserData никуда не делась и как раз состоит из этих трех строчек вызовов.


      1. Zara6502
        01.10.2025 05:31

        так автор пишет про "function покормить_кота(имя_кота)"

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

        по такой логике заливая фундамент под одноэтажный дом лучше залить его сразу под трехэтажный, а вдруг через 50 лет ваши внуки захотят 3 этажа строить?

        если у меня задача хранить вектор 8 бит, то я не пишу софт под 64-битные векторы для "а вдруг".


        1. kukovik
          01.10.2025 05:31

          Я возразил по совершенно другому приведенному вами примеру. И возразил справедливо, кмк. До кота мы еще не дошли, мы юзердату хэндлим пока )


          1. Zara6502
            01.10.2025 05:31

            Я возразил по совершенно другому приведенному вами примеру

            одно связано с другим. если вы что-то еще имете в виду то объясните.


            1. kukovik
              01.10.2025 05:31

              В мире вообще все связано. Однако вы пишете такое:

              Тут вы предполагаете, что автор предлагает ЗАМЕНИТЬ функцию handleUserData на вызовы трех производных функций по ВСЕМУ коду. Не знаю, как иначе можно трактовать ваше замечание.
              Тут вы предполагаете, что автор предлагает ЗАМЕНИТЬ функцию handleUserData на вызовы трех производных функций по ВСЕМУ коду. Не знаю, как иначе можно трактовать ваше замечание.

              Однако же у автора написано совершенно другое:

              Разделите ее на validateForm, saveUserToDatabase, sendWelcomeEmail. Сама функция теперь становится дирижером, а каждый кусок логики изолирован и понятен.

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

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

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


              1. Zara6502
                01.10.2025 05:31

                теперь я вас понял, да, это мой недогляд, претензию снимаю.


      1. Spyman
        01.10.2025 05:31

        Главное, чтобы это была единственная публичная функция. Если все 4 доступны - всё становится ещё запутаннее.


    1. theult
      01.10.2025 05:31

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

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


    1. werymag
      01.10.2025 05:31

      при чтении чужого кода я 99% времени трачу на понимание логики кода, а так как логика у каждого программиста своя, то не существует единого подхода. 

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

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

      Почему-то введение вами "первичного" критерия автоматом сделало "вторичный" критерий бесполезным. Понимание логики программы в том числе и строится на понимании что делает каждая её часть, а для этого и нужны такие имена. Нет хуже вещи, чем однобуквенные константы (если контекст не 5-10 строчек, конечно, ну или если это не что-то фундаментальное типа "i","j), особенно если их несколько штук, мгновенно начинаешь в них теряться.

      а вот выше вы написали что нельзя так делать )

      Неверно. Действие "покормить" - оно вполне одно. Тут речь когда есть концептуально разные по смыслу вещи.

      То есть программист абсолютно не владеющий алгоритмом шифрования просто зайдя в код тут же магическим образом его изучит? Это так не работает.

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


      1. Zara6502
        01.10.2025 05:31

        Понимание логики программы в том числе и строится на понимании что делает каждая её часть

        нет. "чужая душа - потёмки". чтобы понять логику вам нужно знать как минимум глобально что делает этот код, то есть вы знаете что например это функция которая применяет к картинке алгоритм Собеля. Но внутри у вас черный ящик. Погружаясь внутрь вы видите авторское исполнение алгоритма, если оно отличается от "классического по учебнику" то именования переменных возможно дадут вам информацию что как-то где-то что-то, но чтобы раскурить саму реализацию нужно именно знать ход мыслей автора, а если он при этом пользовался хаками двоичной арифметики, то вам и про эти хаки нужно уже знать, иначе вы увидите строку a = b & #AA7755FF и будете гадать что это за константа такая, при этом в самом Собеле об этом ни слова. Ну назовёт он не a, а FormatEdge и что вам с этого? Какой формат, какого ребра?

        Нет хуже вещи, чем однобуквенные константы (если контекст не 5-10 строчек, конечно, ну или если это не что-то фундаментальное типа "i","j), особенно если их несколько штук, мгновенно начинаешь в них теряться.

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

        Я для примера уже давал код архиватора ZX0, до сих пор тишина, так никто ничего и не понял.

        Именно так и работает, программист не знающий шифрования зайдёт в код, сразу поймёт, что тут происходит шифрование, что за шифрование и с какими параметрами

        Какие волшебные у вас программисты ) Прям сразу? )))) Ну-ну.

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

        А, вон вы про что. Ну так и я могу - зайти, прочитать названия переменных и сказать - шеф, тут происходит шифрование. Мне дадут пирожок и премию 100 млн рублей. Так? Если вы не в курсе что там за шифрование и вы в этом не специализировались, то вы ничего там не поймёте. Знаний на планете чуть больше, ВСЕГДА, чем в вашей голове. Если вы ожидаете что кто-то будет писать код расписывая все детали и подписывая каждый чих - то удачи вам. В 90% случаев вы максимум получите те самые переменные состоящие хотя бы из пары букв, но вам даже такая красота ничем не поможет.

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

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


        1. werymag
          01.10.2025 05:31

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


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

          Ну вот вам пример выше про FormatEdge - что вам это даст? В Собеле нет ни слова про форматирование граней и загуглить вы ничего не сможете.

          Если код самоописываемый то всё шифрование будет вынесено в отдельную функцию, которая будет называться по типу CustomImplementationSobelEncrioption (с передачей "говорящих" параметров) - (тема не моя не знаю как конкретно надо назвать, думаю вы сможете назвать лучше).
          То есть вы ещё даже не зашли в функцию, но уже понимаете что примерно она будет делать, вам даже код читать не надо - а что гуглить вы уже знаете.
          А теперь представьте, что вы не знаете что тут должно быть шифрование и видите функцию (или, что ещё страшнее - просто кучу кода внутри основной функции), с названием "GetStr(a,b,c)". Насколько быстро вы вообще поймете что там есть шифрование, что это реализация Собеля, да ещё и с кастомной реализацией.

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

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

           В 90% случаев вы максимум получите те самые переменные состоящие хотя бы из пары букв, но вам даже такая красота ничем не поможет.

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

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

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

          Именно так всегда и будет. 

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


          1. Zara6502
            01.10.2025 05:31

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

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

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

            И как вы подтвердите этот тезис?

            если вы не работает с каким-то специфическим набором знаний

            любые знания - это знания, обладание этими знаниями совсем не обязательный стандарт для вас или кого-то еще, только если вы не сидите на самописном проекте по 20 лет.

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

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

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

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

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

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

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

            А теперь представьте, что вы не знаете что тут должно быть шифрование и видите функцию (или, что ещё страшнее - просто кучу кода внутри основной функции), с названием "GetStr(a,b,c)". Насколько быстро вы вообще поймете что там есть шифрование, что это реализация Собеля, да ещё и с кастомной реализацией.

            (алгоритм Собеля никак не связан с шифрованием)

            А чем принципиально для вас будут различаться два названия GetStr(a, b, c) и GetEncryption(a, b, c)? Для меня, кто не понимает что тут происходит, именование вообще не даст никакой подсказки.

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

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

            Быстрое понимание кода - быстрое решение поставленных задач

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

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

            Поэтому я не работаю программистом, потому что я не понимаю что пишут другие.

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

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

            Если у вас так - ну чтож, плохо. Особенно плохо - что вы продолжаете и множите это в своём коллективе.

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

            И опять

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

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

            У меня нет привязки к каким-то конкретным языкам и проектам, я в силу своей увлеченности пархаю как бабочка от цветка к цветку, и разброд и шатания присущи всем, за 30 лет моего прибывания в интернете и чтения кода я не увидел никакого прогресса в сторону удобочитаемости и документированности, отсюда я склонен считать что ваши подвижки на личном фронте никак не влияют на средний показатель читаемости кода. Во всяком случае сколько я не коллективов прошёл, а доброе и светлое в организации работы никогда и никому нужно не было. Поэтому роль Дона Кихота я забросил лет 15 назад. А с приходом молодёжи, у которых по милларду IDE с ИИ в заду - я сижу в уголку и не отсвечиваю. Главное чтобы до пенсии дотянуть, а в постулаты правильности я не верю - всем на это плевать, особенно руководителям.


            1. Rsa97
              01.10.2025 05:31

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

              Ну если для вас понимание кода никак не связано с названиями переменных и функций, то попробуйте назвать все переменные var1, var2, ... var99, а функции, соответственно, func1, func2, ... func99.
              Когда я вижу запись nameLen = strlen(name), я понимаю, как сформировано имя переменной и в дальнейшем по коду сразу вижу, что в ней находится. Когда я вижу zzz = myfunc1(xxx), то я должен сначала вспомнить, что же лежит в xxx, затем залезть в myfunc1 и понять, что она делает, и, наконец, запомнить, что именно будет храниться в zzz.


              1. Zara6502
                01.10.2025 05:31

                ну ок, вы знаете что в nameLen лежит число - дальше что? проблема в том что дальше этого знания вы не продвинитесь. поэтому если написано l = strlen(n) - это даст столько же информации, так как к моменту прочтения этой строки вы уже знаете что такое n, потому что где-то выше по коду вы встретили n = Strings.GetName(x);

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

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


                1. Rsa97
                  01.10.2025 05:31

                  если написано l = strlen(n) - это даст столько же информации

                  Ровно до тех пор, пока у вас только одна переменная с похожим именем. Как только у вас появляются l1, l2, l3, l4 и l5, запутаться в них проще простого.

                  Зайдите в github проекта ZX0 и расскажите мне в деталях что же делает функция optimize(), а то независимо от именования мне совсем непонятен алгоритм.

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

                  Вы же утверждаете что щелкает алгоритмы как орешки

                  Где я такое утверждал? Вы меня с кем-то путаете.


                  1. Zara6502
                    01.10.2025 05:31

                    Ровно до тех пор, пока у вас только одна переменная с похожим именем. Как только у вас появляются l1, l2, l3, l4 и l5, запутаться в них проще простого.

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

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

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

                    Где я такое утверждал? Вы меня с кем-то путаете.

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

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


                    1. Rsa97
                      01.10.2025 05:31

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

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

                      прочитать и понять чужой код это очень сложно

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


                      1. Zara6502
                        01.10.2025 05:31

                        В том коде, что вы привели, есть функция elias_gamma_bits. Собственно, если вы знаете, что такое гамма-код Элиаса, то названия функции вам хватит, чтобы понять, что она делает

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


                      1. Rsa97
                        01.10.2025 05:31

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

                        Базовый анализ

                        Внешний цикл идёт по всем байтам данных (текущий байт).
                        Внутренний перебирает смещение в обратную сторону максимум на определённую в offset_limit глубину (старый байт).
                        Если текущий и старый байты не совпадают, то проверяется гипотеза копирования литерала.
                        Если байты совпадают и есть литерал с таким смещением, то проверяется гипотеза копирования с последнего смещения.
                        Если байты совпадают и длина совпадающей цепочки больше 1, то проверяется гипотеза копирования с нового смещения.
                        Для проверки гипотезы вычисляется длина блока при соответствующем варианте копирования и, если она меньше, чем уже найденная, то старый оптимальный вариант заменяется на найденный.
                        Последняя построенная цепочка (optimal[input_size - 1]) считается оптимальной и возвращается для записи в архив.
                        Функции assign и allocate нужны для ручного управления памятью и в языках с автоматическим контролем памяти могут быть заменены на присваивание и new соответственно.

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


                      1. Zara6502
                        01.10.2025 05:31

                        то есть вы код оформили в виде псевдокода и считаете что это и есть понимание алгоритма?


                      1. Rsa97
                        01.10.2025 05:31

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


                      1. Zara6502
                        01.10.2025 05:31

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


                      1. Rsa97
                        01.10.2025 05:31

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


                      1. Zara6502
                        01.10.2025 05:31

                        не хочу.

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


            1. werymag
              01.10.2025 05:31

              Хотел было ответить построчно, но понял, что это как плохой код - нечитабельно :).

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

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

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

              Мне кажется тут всё более чем прозрачно.

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

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


              1. Zara6502
                01.10.2025 05:31

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

                Это разные вещи, разного уровня сущности!

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

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

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

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

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


  1. qark
    01.10.2025 05:31

    Главное потом не забыть везде в коде писать по три строчки вызовов подряд (вы кстати дальше сами с этим же и боритесь)

    Где написано "везде в коде три вызова подряд"?

    а вот выше вы написали что нельзя так делать )

    Да где?!

    То есть программист абсолютно не владеющий алгоритмом шифрования просто зайдя в код тут же магическим образом его изучит?

    ad absurdum


    1. Zara6502
      01.10.2025 05:31

      Где написано "везде в коде три вызова подряд"?

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

      Да где?!

      Ну давайте вы будете внимательно читать и статью и мои комментарии.

      ad absurdum

      bet betmurdum


  1. panzerfaust
    01.10.2025 05:31

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


    1. Alex_RF
      01.10.2025 05:31

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


      1. panzerfaust
        01.10.2025 05:31

        Он говорит про необязательность этих принципов

        А тогда кто говорит про обязательность?


        1. Alex_RF
          01.10.2025 05:31

          Отрицания НЕТ. Говорится что SOSAL должен преобладать над SOLID. Ну видать явные сторонники идей дядюшки Боба у него на проекте так идеи внедрять криво стали, что код не понятным стал. Хотя странно такое внедрение. Все пять принципов наоборот направлены на то, что бы код был структурирован и от этого читаемый.


    1. Vav1r
      01.10.2025 05:31

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

      Не могу не отметить, буквально сейчас претерпеваю именно этот процесс =)


  1. Botanegg
    01.10.2025 05:31

    Забавно, что в самом первом примере рефакторинга: arrow code продолбались и вместо мяты стала мышка, теперь кот обдолбан мышами
    (LLM были здесь?)


    1. OyminiRole1776 Автор
      01.10.2025 05:31

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


  1. Kerman
    01.10.2025 05:31

    Это значит, что его структура и именования настолько ясны, что комментарии, объясняющие, что он делает, становятся излишними.

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

    Иногда таких комментариев хватает и нет необходимости писать `//`.


  1. checkpoint
    01.10.2025 05:31

    -- Дорогой, покорми кота.

    -- Он сыт.

    -- Ну как поссыт, покорми.

    Извините, навеяло.

    По существу. На мой взгляд конструкиция вида:

    если (КОТ_ХОЧЕТ_ИГРАТЬ &&
          КОТ_В_ГОСТИННОЙ &&
          ПЛЕД_НА_ДИВАНЕ &&
          КОРОБКА_ПОД_ПЛЕДОМ &&
          МЯТА_В_КОРОБКЕ) {
        // запустить кота в коробку
    } иначе {
        // что-то пошло не так
    }

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


    1. Cfyz
      01.10.2025 05:31

      Очень часто вложенные условия как бы уточняют друг друга и выполняют промежуточные действия:

      if (data != NULL) {
          response = request(data)
          if (response.succeeded) {
              result = process(response)
              if (result.valid) {
                  store(result)
                  и т.д. и т.п.
              }
          }
      }

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


      1. Seenkao
        01.10.2025 05:31

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

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

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

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

        Так что разных факторов полно и для их перечисления понадобится многотомник.


        1. funca
          01.10.2025 05:31

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

          Меньше кода это не всегда хорошо. Опыт Perl и прочих хаскелей не даст соврать. Лесенку условий из примера выше можно легко переписать в столбик, типа:

          processData data = do
              response <- MaybeT $ request data
              result <- MaybeT $ process response
              lift $ store result

          Легче стало? - сомневаюсь. Кто же в здравом уме захочет потом в этом всем разбираться.


          1. Seenkao
            01.10.2025 05:31

            Потому я и написал: "Но это может не ко всему коду относится."


        1. SpiderEkb
          01.10.2025 05:31

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

          Да, и при этом еще может быть много ветвлений - Если соблюдены условия A, B, C - одна ветка, если A, B, D - другая, если A, C, D - третья... И так далее.

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

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


    1. Sau
      01.10.2025 05:31

      А теперь нужно возвращать сообщение почему нельзя запустить кота в коробку.




  1. pavelsc
    01.10.2025 05:31

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

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

    Защитники этой хрени аргументируют типа якобы рефакторить и вносить изменения проще. Да уже никто не пишет в тех отсталых IDE, в которых писал автор жёлтых книжек. Да и метрика какая-то тупая: код написан хорошо, если в меньших местах надо вносить изменения. Бред. IDE сама эту работу делает давно, мне только кнопку нажать.


  1. apevzner
    01.10.2025 05:31

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

    У этой палки есть и обратная сторона.

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

    Коты в среднем не одинаковые.


    1. anshdo
      01.10.2025 05:31

      Особенно часто эти грабли в в КИСах встречаются ;-)


      1. apevzner
        01.10.2025 05:31

        Что такое КИС?


        1. kenoma
          01.10.2025 05:31

          KISS


    1. JBFW
      01.10.2025 05:31

      Вот да. И там может быть столько разных if ....


    1. Kerman
      01.10.2025 05:31

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

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

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


  1. R0bur
    01.10.2025 05:31

    Имя должно раскрывать намерение. Если вы видите переменную d или list1, вам придется лезть *** знает куда или прокручивать код вверх, чтобы понять, что это. А если переменная называется elapsedTimeInDays или activeUsers, вопросы отпадают сами собой.

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

    for (indexOfElement = 0; indexOfElement < sizeOfArray; indexOfElement++)

    array[indexOfElement] = ...

    а вот так:

    for (i = 0; i < n; i++)

    array[i] = ...


    1. SpiderEkb
      01.10.2025 05:31

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

      dsYPS01LFk - структура ключевых полей индекса YPS01LF

      dsYPS01LFi - структура записи индекса YPS01LF используемая для чтения

      dsYPS01LFo - структура записи индекса YPS01LF используемая для записи

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

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

      Даже во вложенных циклах

      for (i = 0; i < 10; i++) {
        for (j = i; j < 10; j++) {
          ...
        }
      }

      читается хуже чем

      for (i = 0; i < 10; i++) {
        for (n = i; n < 10; n++) {
          ...
        }
      }

      потому что визуально i и j схожи, а i и n отличаются по начертанию.


      1. janvarev
        01.10.2025 05:31

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

        А n... я бы напрягся, подумав - "а может оно определено выше и это общий размер массива?"


        1. SpiderEkb
          01.10.2025 05:31

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

          Не нравится n - пусть будет k. Главное, чтобы начертание отличалось от i.

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

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


  1. thank_accept
    01.10.2025 05:31

    Приятно встретить здравомыслящего человека :)

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

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

    Я бы тут поставил под сомнение еще пару вещей: SRP и код.ревью

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

    Здравый смысл и антихрупкость всем!


  1. thank_accept
    01.10.2025 05:31

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

    Есть у него и здравые идеи, за что ему спасибо, например та же схема круговая Clean Architecture.

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

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

    P.S. Кстати я почти не встречал проектов которые действительно реализуют Clean Architecture. В основном люди тащат переусложнение и часть профита, но не понимают идеи в целом. Это же слои, Торт как сказал бы Осёл или Лук как сказал бы Шрек! А на проектах делают из этого селедку под шубой, тоже есть слои, но больше похоже на винегрет.


  1. Maliglood
    01.10.2025 05:31

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


  1. MagDen
    01.10.2025 05:31

    Автор не отрицает Чистый код и не агитирует за Чистый код. Автор про баланс. Сам как то написал модуль, где все как дядюшка Боб завещал. Опытный коллега сказал - "Нужен баланс". Через год переписал модуль - выкинул 90% интерфейсов, объединил слишком раздробленные обязанности и код стал намного проще в поддержке.
    А про переменные/комментарии - не редко встречал, когда комменты безнадежно устаревали, а имена переменных/функций непросто "не о чем", а прямо лгут о своем намерении. При чтении такого кода приходится опускаться до деталей. Аж до уровня стрингов и интов. По итогу - мозгоусилий потратил столько же, сколько если бы сам реализовал фичу.

    Баланс - его начинаешь чувствовать со временем.


  1. SquareRootOfZero
    01.10.2025 05:31

    если (кот хочет играть) { если (он в гостиной) {

    Помнится, в 16 лет, на лабораторной по программированию в среде Турбо-Паскаль мне тоже не понравилось писать длинный развесистый if-then, и я вместо каждой булевской переменной завёл битовый флаг внутри целого числа: допустим, кот хочет играть было 00000001, он в гостиной было 00000010, а оба этих условия проверялись конструкцией если (это == 3). Вышло, действительно, сильно короче (насколько оправданно - другой вопрос), но препод охренел и отказывался ставить пятёрку, утверждая, что не будет работать. Наверное, это был "хитрожопый код".


    1. goodbear
      01.10.2025 05:31

      Возможно, потому что это не очевидно и не всегда может работать. Флаги состояния могут расшириться, добавится какой-нибудь кот хочет есть = 00000100, и проверка может поломаться, кроме того проверка должна быть не на 3 а что-то вроде:
      обстоятельства = кот хочет играть | он в гостиной
      если ( это & обстоятельства == обстоятельства ) ...
      Или что-то в этом роде, давно побитово не писал...


      1. SquareRootOfZero
        01.10.2025 05:31

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

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


        1. KReal
          01.10.2025 05:31

          В функциональщине (или, с вашего позволения, type driven development) каждый кейс можно представить в виде типа и воспользоваться pattern matching. Скажу честно, я последнее время так и делаю.


          1. SquareRootOfZero
            01.10.2025 05:31

            А вместо побочного эффекта по обдалбыванию кота возвращать его обдолбанную копию?


  1. cosmichorror
    01.10.2025 05:31

    Не читал никакого Мартина - мой код и архитектура и так всегда были чистыми.


    1. Astrowalk
      01.10.2025 05:31

      мой код и архитектура и так всегда были чистыми

      Вот он, вот, наконец-то найден! Идеальный программист: https://habr.com/ru/companies/ruvds/articles/946084/


  1. iroln
    01.10.2025 05:31

    1. funca
      01.10.2025 05:31

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


  1. StrawberryPie
    01.10.2025 05:31


    1. Grey83
      01.10.2025 05:31

      через «о» же пишеццо
      и кто такие «программиасты» и нафига им «бибмотека»?

      неромазня в тексты всё ещё слабовато умеет



  1. resolution07
    01.10.2025 05:31

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


  1. diakin
    01.10.2025 05:31

    Функция должна делать что-то одно

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


    1. Rsa97
      01.10.2025 05:31

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


      1. diakin
        01.10.2025 05:31

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


        1. Rsa97
          01.10.2025 05:31

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


          1. janvarev
            01.10.2025 05:31

            Слишком длинную сложнее воспринимать.

            Зависит от.

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


            1. Rsa97
              01.10.2025 05:31

              Однако проще читать функцию, если она вызывает несколько функций с говорящими названиями, чем то же самое, но в виде простыни кода. Например, если вы видите функцию string strToUpperCase(string s), то вряд ли вам надо погружаться в её код, чтобы понять, что именно она делает. А если к ней ещё и добавлен doc-блок, отображаемый IDE, то описание функции и её аргументов вы увидите при наведении на её вызов.
              Тут надо только, чтобы разбиение на подфункции не было искусственным. Они должны быть достаточно самодостаточными и законченными по смыслу.


              1. janvarev
                01.10.2025 05:31

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

                Вот-вот.

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

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


                1. Rsa97
                  01.10.2025 05:31

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

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


                  1. janvarev
                    01.10.2025 05:31

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

                    Имхо вот тут уже на вкус....
                    Я бы тупо обрамил этот кусок комментариями. Читающий специалист поймет: "инициализация" (а неспециалисту лезть в этот код не надо).

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

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


                    1. Rsa97
                      01.10.2025 05:31

                      Есть шанс, что неверная инициализация проведена.

                      Для этого есть покрытие тестами. И сделать тест инициализации гораздо проще, если она вынесена в отдельную функцию.


                      1. janvarev
                        01.10.2025 05:31

                        Покрытие тестами - да, аргумент - и я писал об этом здесь, чуть ниже: https://habr.com/ru/articles/952300/comments/#comment_28910320

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


                      1. Rsa97
                        01.10.2025 05:31

                        Но даже покрытие тестами означает, что функция используется минимум ДВА раза - т.е. повторно.

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


        1. polearnik
          01.10.2025 05:31

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


          1. janvarev
            01.10.2025 05:31

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


        1. Pand5461
          01.10.2025 05:31

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


  1. astenix
    01.10.2025 05:31

    Ооо, начинается (очередная) революция!



  1. Yura_PST
    01.10.2025 05:31

    Кто-нибудь вообще видел чистый код в каком-нибудь рабочем проекте?


    1. Greyson
      01.10.2025 05:31

      Видел) В паре проектов за последние лет пять. Но есть нюансы.

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

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


  1. vasiliy_moscow
    01.10.2025 05:31

    Уже можно не париться по поводу понятного кода, расслабьтесь. Завтра ваш любой код будет читать - интерпретировать и документировать в понятном виде llm-агент. «Теперь можно срать на ковер - робот-пылесос все приберет за вас»


    1. Grey83
      01.10.2025 05:31

      Теперь можно срать на ковер - робот-пылесос все приберет за вас

      Ну или размажет по всей комнате тонким слоем =)


  1. 2medic
    01.10.2025 05:31

    Дадим этим числам понятные имена.

    сonst СОСТОЯНИЕ_МУРЧАЩИЙ = 1;
    const СОСТОЯНИЕ_ГОЛОДНЫЙ = 2;
    const СОСТОЯНИЕ_МЕРТВЫЙ = 3;


    Есть же Enum…


    1. aabzel
      01.10.2025 05:31

      Не знаю как в Go, но на Си в РФ 70-80% программистов с 15+ лет опыта не знаю, что такое Enum, битовые поля и объединения. Среди них 60-70% не знают про оператор switch.
      https://habr.com/ru/articles/837396/


      1. diderevyagin
        01.10.2025 05:31

        Микроконтроллеры свой, отдельный мир. И очень странный в плане качества. Достаточно вспомнить результат анализа кода Toytota от NASA в связи с известной историй про педаль газа...


  1. Greyson
    01.10.2025 05:31

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

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

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


  1. sergey_prokofiev
    01.10.2025 05:31

    покормить_кота("Барсик"); покормить_кота("Мурзик");

    голодные_коты = ["Барсик", "Мурзик"];

    голодные_коты.forEach(кот => покормить_кота(кот));


    1. oco
      01.10.2025 05:31

      голодные_коты.forEach(покормить_кота);


      1. KReal
        01.10.2025 05:31

        в .net до некоторых пор лямбды сильно выигрывали в производительности у method group (MS накосячили, сейчас потихоньку фиксят).


  1. diderevyagin
    01.10.2025 05:31

    Проблема в том, что очень многие неправильно воспринимают эти подходы.

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


  1. sepulkary
    01.10.2025 05:31

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

    Боюсь, вы не понимаете SRP. Почитайте, даже здесь, на "Хабре", этот вопрос разжевывался много раз.


  1. AndreyFr
    01.10.2025 05:31

    Постоянно все нацелено на скорость и бабки, а не на качество и оптимизацию...


  1. af7
    01.10.2025 05:31

    Вот это я понимаю, популярная тема. Все кому не лень написали своё мнение. Теперь моя очередь, хотя вряд-ли кто-то его вообще прочитает среди такого количества.

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

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

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


    1. Gromilo
      01.10.2025 05:31

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

      Кроме того, когда работаем с многими человеками, лучше создавать согласованное решение. Иначе каждый начинает писать кто во что горазд. Особенно это заметно, когда команда меняется. Правда не всё так просто: чем больше приложение, тем подробнее и сложнее становятся регламенты и соглашения в своей попытке закрыть все аспекты разработки. Хорошо, если есть возможность сделать приложения поменьше (микросервисы?), тогда согласования будет попроще и следовать им будут из-за этого чаще.


  1. identity_not_established
    01.10.2025 05:31

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


  1. WASD1
    01.10.2025 05:31

    Худшее, что можно сделать с guard clauses - это смешать их с вложенными условиями, особенно попеременно.

    Особенно попеременно. После этого код становится абсолютно нечитаемым и крайне осложнённым для понимания.