company_banner

Как писать читаемый код

    Бывает, что посмотрев на старый код, мы говорим: «Его проще переписать, чем поменять». Печально, если речь идет о нашем собственном коде, с такой любовь написанном несколько лет назад. Head of Developer Relations в Evrone Григорий Петров в своем докладе на TechLead Conf 2020 разобрал проблемы, которые приводят к такой ситуации, и рассказал, как бороться с Software complexity problem.

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

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

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

    Художник рисует мазками

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

    Можно сказать, что программисты тоже пишут код своеобразными «мазками»: идентификатор за идентификатором, оператор за оператором, expression, statement, строчка за строчкой получаются творения в 10, в 100, в 1000 строк кода.

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

    Поэтому одна из главных проблем, существующих в разработке софта — это то, что мы называем Software complexity problem, что можно перевести на русский как «проблема сложности программ».

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

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

    Проблемы программирования

    • Нулевая цена копирования;

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

    • Нет понимания «как правильно»;

      Индустрия программирования очень молода, мы еще не успели подготовить лучшие практики и не знаем, как «правильно» писать софт. Прямо сейчас можно наблюдать, как монолит объектно-ориентированного программирования, который последние 20 лет был незыблемым, сдает позиции функциональному программированию. Многие топовые разработчики сейчас говорят о том, что наследование — это не очень хороший способ декомпозиции кода. А в языках программирования последнего десятилетия (например, в Rust) в принципе нет классов, как таковых. И они неплохо себя чувствуют.

    • Отсутствие фундаментального образования;

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

    • Сложно посмотреть, «как делают другие».

      Художник может прийти в картинную галерею, посмотреть на разные топовые картины и сказать: «Вот это круто нарисовано. Я сейчас повторю и буду рисовать так же хорошо!». Для этого у него есть интуитивное мышление.

    Интуитивное мышление, когнитивные искажения

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

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

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

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

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

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

    Борьба со сложностью

    К сожалению для нас, сложность из кода нельзя убрать. Ведь она — это та польза, которую приносит написанная нами программа. 

    Но сложность можно перераспределить! Именно об этом пойдет речь в статье. 

    • Память;

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

    Как это происходит, не совсем ясно.  Но существует такая закономерность, как «Кошелек Миллера»: когда человек смотрит на новые для себя объекты, в среднем, он может удержать в фокусе внимания от 5 до 9 из них. 

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

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

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

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

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

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

    Если программист много лет пишет на Python и использует requests, он к ним привыкает. Типичные конструкции использования requests — как сделать запрос, как передать и получить JSON, как решать вопросы скорости и задержек — ему привычны. Код, который использует библиотеку, становится для программиста читаемым. В таком коде больше нет сложности. По крайней мере, для этого конкретного программиста.

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

    Точно также работает стандарт кодирования, «coding style». Код разработчиков может быть читаемым друг для друга, но только если они хотя бы несколько месяцев поживут с ним. Нейрофизиология утверждает, что несколько месяцев и несколько сотен повторений нужны нашей памяти, чтобы выстроить долговременные связи long-term potentiation, чем бы они ни были.

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

    Но память — это долго. Это самый простой, но и самый длительный по времени способ борьбы со сложностью.

    • Декомпозиция;

    Второй по популярности способ — это декомпозиция на части по 5 элементов.

    Посмотрим на эволюцию типичной сферической программы в вакууме.

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

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

    Через некоторое время, когда абстракции языка программирования исчерпывают себя, и строчек становится несколько десятков тысяч, разработчики начинают с интересом смотреть в сторону DSL:  YAML, JSON, Ruby, XML и т.д. 

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

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

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

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

    • Метаинформация.

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

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

    Главный, основной, фундаментальный дорожный указатель — идентификаторы. 

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

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

    竜宮の乙姫の元結の切り外し или Мосгорводоканалстрой — это одна сущность для нашего мозга.

    Идентификатор здорово помогает писать читаемый код, если отвечает на вопрос «что это?». Программист пришел в проект, посмотрел на идентификатор, и ему сразу понятно, что. В современных языках программирования для этого есть PascalCase, camelCase, snake_case. Выбирая конкретный стиль, мы выбираем то, что привычнее нашей команде.

    В Go все очень тяжело со сложностью, потому что язык практически не предоставляет синтаксического сахара. В книге «Как писать на языке программирования Go» есть параграф про эволюцию идентификаторов. Там написано о том, как бороться с когнитивной сложностью в коде. Выбирая имя для идентификатора, авторы предлагают смотреть на то, что находится рядом с этим идентификатором. Если там что-то очень простое (функция, 2-3 строчки кода, которые очевидны), то идентификатор может быть i или v:

    v => users => admin_users

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

    После идентификаторов идут комментарии, которые отвечают уже на вопрос «зачем это?».

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

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

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

    Например: 

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

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

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

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

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

    В последние 5-10 лет в динамические языки программирования пришли типы. Они выполняют роль своеобразных «капканов» для ошибок. Когда программист пишет код, он может воспользоваться Gradual подходом современных языков. И там, где сложность повышена, добавить типы, чтобы в коде расставились несколько «капканов». 

    Если программист через какое-то время (например, спустя полгода) воспользуется этим кодом неправильно, «капкан» сработает, подчеркнет ему  строчку в IDE красным, и все сразу станет понятно.

    Gradual подход к перераспределению сложности

    Gradual подход к написанию читаемого кода по больше части вращается вокруг цифры 5. 

    Есть несколько способов перераспределения сложности:

    • Gradual decomposition;

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

    • Gradual meta information;

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

    • Gradual typing.

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

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

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

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

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

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

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

    Конференция, полностью посвященная инженерным процессам и практикам, TechLead Conf 2021 пройдет 12 и 13 апреля. Билеты можно приобрести здесь. Вы можете успеть купить их до повышения цены!

    А пока мы все ждем апреля, приглашаем вас на Quality Assurance Webinar. На нем поговорим о пирамиде тестирования, узнаем, как найти UI тесты, которые легко могут быть перенесены на более низкие уровни, и разберемся в инфраструктуре тестирования в браузерах.

    Мероприятие начнется 21 января в 18:00 мск. До встречи!

    Конференции Олега Бунина (Онтико)
    Конференции Олега Бунина

    Похожие публикации

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

      +1
      Много букв, но осилил, при этом не понял, как правильно именовать переменные
      моему коду это бы помогло, а то от переменных типа
      х, хх, ххх1, temp, tmp, xxbw и так далее подустал.
        +2
        Мне понравилось про это читать у Макконела, Совершенный код.
        Вот здесь на хабре вроде неплохо написано про именование
          0
          спасибо, читаю
          +1

          Автор приводит Golang как пример, речь вот об этом:
          https://dave.cheney.net/practical-go/presentations/qcon-china.html#_identifiers

            +1
            спасибо за ссылку, полезно будет прочитать
            0

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


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

            +1
            В целом, полезно было, но под конец уже не стал дочитывать. Текста слишком много… а так, спасибо)
              +3
              И, конечно же, в ней поднимается тема сложности кода. Вы узнаете о том, откуда она берется, почему ее нельзя убрать и как с ней жить.

              *Вот это поворот*

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

              Но несмотря на двадцатилетний опыт в программировании, Григорий признается: писать читаемый код до сих пор тяжело.

              Этот Григорий пишет юнит тесты, использует DDD-подход? Я вижу в своем окружении программистов, которые не смотря на 10+ летний опыт пишут ужасный код, с которым тяжело работать. Но это происходит только потому, что они и не пытаются писать хороший код. Отсутствие самокритичности — своеобразное проклятье для человека.

              P.S.
              Складывается впечатление, что автор путает понятия «объем кода»/«читаемость кода»/«сложность кода». Объемы коды — да, убрать трудно, чаще всего его количество только растет за счет использования фреймворков и библиотек, но вот читаемость и сложность решается на ура.
                +1
                А ничего, что сами языки программирования (и соответственно код, написанный на них), за последние десятилетия стали сильно проще и удобнее? Не говоря уже о тысячах библиотек, которые легко подключаются и дают удобный интерфейс для использования.

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

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

                  Вы перескакиваете из одной темы на другую. В программировании есть нормальные и токсичные области. Разработка на Windows или web frond-end — это токсичные области. Даже если человека, по незнанию, занесло в эту область — никто не заставляет там оставаться.

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

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

                      0
                      Непонятна ваша язвливость.

                      Все же просто и очевидно: становитесь ценным специалистом чтобы за вами стояла очередь из HR, закрываете финансовый вопрос (чтобы выбирать работу по принципу «нравится/не нравится»), определяете свои интересы и четко озвучиваете их работодателям (например, если у вас неприятие сторонних библиотек — прямо озвучиваете, что я все что нужно напишу сам, так будет проще и быстрее).

                      И… готово. Работаете в компаниях и проектах, которые вам нравятся, с технологиями, которые вам нравятся.

                      А если, этого нет — то, может быть, проблему нужно искать в себе?
                        +2

                        Непонятна ваша незамутнённость. Почему незамутнённость? Потому что -


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

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


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

                          –1
                          Этот тезис может существовать в стране фей и единорогов, но не в реальности

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

                          Ему говоришь о том, что можно жить по другому, но для этого нужно приложить усилия и соответствовать требованиям — начинаются разговоры «ну вот все мои знакомые тоже страдают, значит вы врете»

                          В реальности вы практически нигде не пишете «всё сам»

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

                            Да, а вам говорят о том, что ваше "по-другому" означает не независимость, и не какое-то другое распределение ответственности за код (о чем в этой ветке комментариев и ведется разговор). Ваше "по-другому" — это "у меня такая же нога, и не болит". У вас никогда в жизни не было проблем из-за внешнего по отношению к вам кода? Рад за вас, но вы — исключение из правил, а не правило. И более того, у меня есть обоснованные подозрения, что у вас не было проблем не в силу тех причин, которые вы живописуете (собственной офигенности), а в силу некоторых куда более банальных вещей:
                            1) Вы решаете сугубо типовые проблемы проверенными инструментами для решения этих сугубо типовых проблем;
                            2) Вы решаете их не так долго, чтоб столкнуться с проблемами окружающего вас кода;
                            3) Вы работаете на достаточно старом проекте, и проблемы окружающего кода уже порешал кто-то другой за вас.


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


                            Если вы работаете с кривым стеком — это ваши проблемы.

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

                              –1
                              У вас никогда в жизни не было проблем из-за внешнего по отношению к вам кода?

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

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

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

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

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

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

                              Мне надоел этот диалог.
                                +1

                                Люблю людей, которые сами придут сверкать белым пальто, и сами тут же обижаются. Passive-aggressive как оно прям по учебнику.


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

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

                +2

                Внятный доклад, соответствующий, кстати, критериям в нем описанным.
                И первые же комментарии: "много букв...".
                "Кошелек Миллера" худеет. ;)

                  0
                  Пресловутое клиповое мышление.
                  +1
                  Но, в отличие от художника, программисты не могут «отойти на шаг назад».

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

                    0

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

                    +4
                    Несколько мыслей на тему сложности, на оригинальность и тем более истину не претендую:

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

                    2) Не зря великие говорили, что если отладка сложнее написания кода, то не получится отлаживать код, который написал на пределе доступной тебе сложности. Но я бы сказал ещё, что грамотный разработчик не создаёт решения сложнее, чем на 90% от своей способности со сложностью справляться.

                    3) Нельзя сложные программные системы переписывать с нуля потому, что они тебе не нравятся своей сложностью. Если кто-то приходит к тебе и говорит «да тут у вас слишком сложно, мы напишем с нуля» — нельзя его к написанию подпускать, надо чтобы сначала он продемонстрировал, что старую систему срефакторить сможет. Если ты не можешь справиться с той сложностью, которая уже есть, методом постепенного рефакторинга, то когда начнешь писать сам — наворотишь сложность еще хуже и в итоге задачу не решишь. А всё почему? Потому что нельзя понять, что именно ты не понимаешь и недооценивашь, по определению.

                    4) Главное для опытного программиста — умение управлять сложностью. Обычно мы сложность только добавляем (нельзя же заниматься только рефакторингом), но горе тому, кто так до рефакторинга (по сути, упрощения!) и не доходит. Тогда вместо того, чтобы наводить порядок и упрощать, такой разработчик накручивает костыли на костыли и остановиться не может, потому что костыли писать проще. Со временем костыли писать становится всё сложнее и сложнее, но фишка в том, что в каждый момент времени написать очередной костыль хоть и всё сложнее и сложнее, но всё равно всегда проще, чем расчистить конюшни и навести порядок. И всегда есть эта иллюзия (?), что по причине дедлайнов оптимальное решение — писать костыли. Увы, это оптимальное решение в моменте, но очень неоптимальное в долгосрочной перспективе.
                      0

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

                        +1
                        Да. Как известно, новичка оценивают по количеству строк, которые он добавляет для того, чтобы появилась новая функциональность. Профессионала оценивают по количеству строк, которые он удаляет для того, чтобы появилась новая функциональность :).
                        0
                        Если часть изложенных мыслей ваша, или же если формулировка ваша, то вам стоит начать писать книги, ну а если это и не так, то хотя бы дать ссылки на ресурсы, которые формируют такое мышление =)
                          0
                          Спасибо на добром слове :). Я преподаватель, и формулировать понятно — это моя работа :)
                        0

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

                          +2

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

                            0
                            Интересно, спасибо! Понимание причин высокого уровня сложности программ помогает спокойнее к этому относиться в работе.

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

                            Самое читаемое