Come work in Estonia – the most advanced digital society. Many Ukrainians already know that Estonia is affordable – become one of them and check out the jobs available!
×Закрыть

Как понимать чужой код

Прежде чем перейти к куче текста, посмотрите на код и поймите, что он делает:

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

Когда мы вынуждены читать чужой код?

1. Код достается по наследству. Когда вы дописываете за кем-то, и вам нужно оценить, сколько времени займет доработка.
2. Ваш код, дописанный кем-то, в который вносили изменения другие разработчики, и вам необходимо понять, что они там дописали.
3. Code review. Отличается от первых двух тем, что его нужно проводить до того, как код попадает в репозитарий/продакшн.

Что нужно для понимания чужого кода?

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

Проблемы

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

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

Третья проблема — непонятная логика. Вы можете прочитать код, но не понимаете, зачем было сделано именно так.

Как найти нужное место в коде?

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

Нашли нужное место, но как понять логику?

Есть у нас вот такой код:

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

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

Пример сложный из начала статьи:

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

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

Причины возникновения сложного кода

— Разработчики не придерживаются Code Conventions. По-нашему — отсутствие правил и договоренностей.
— jsDocs. Это формат комментирования джаваскриптовых методов. Разработчик думает «назову функцию по-понятному — getDocument, меня поймут» и реализовывает сложную логику внутри метода, о которой мы не знаем. Мы надеемся получить документ, используем этот метод, а он делает еще кучу всего, что стоило бы описать в комментариях.
— Ключевые моменты бизнес-логики. Как в предыдущем примере с getDocument, сложные операции с массивами, циклы, условия — все должно быть прокомментировано.
— Code Review, а именно его отсутствие. Джуниоры тоже могут ревьюить сеньоров.

Как мы называем плохой код?

— «Спагетти-код». Не самый распространенный вариант. Три метода, каждый из которых что-то делает. В теле функции идут вызовы других методов, и даже глазами невозможно проследить цепочку, что откуда вызывается. Код перепутан, как спагетти в миске.

— «Костыли». Такого в коде очень много. Разработчик написал цикл, в котором он что-то делает с элементами массива, по которому идет этот цикл. И предупреждает, что вызов метода doSomething при определенном значении вываливает ошибку. И он просто пишет, что если значение массива — 4, надо пропустить его и перейти к следующему. Он предусмотрел эту ситуацию и сделал «подпорку», чтобы не валилась ошибка. Но этим он создал другие ситуации, которые создадут другие исключительные ситуации, когда что-то не покажется или покажется лишнее. Разработчик же продолжит дописывать другие костыли, перекрывая созданные ошибки.

— «Велосипед»

Это — пузырьковая сортировка массивов. Когда разработчик пишет такой код, он не задумывается, что на JavaScript есть собственная сортировка массивов, которая вызывается элементарно .sort(). Он заново придумал код, который уже где-то есть. Такое часто бывает в работе в команде, когда один разработчик уже написал метод, а вы не знаете об этом и пишете еще один такой метод. И код разрастается одинаковыми методами.

Как дальше жить?

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

Code Conventions и комментарии экономят нервы и время.

GodLevel чтения чужого кода — github.com/torvalds/linux

Читать джуниорам перед сном:
— Стандарт оформления кода
— Комментарии
— Рефакторинг

Лучшие комментарии пропустить

где-то на просторах хабра встречал:
«Ехал цикл через цикл
Видит цикл в цикле цикл
Сунул цикл цикл в цикл
Цикл цикл цикл цикл» ©

" Как понимать чужой код? Читайте в сери книг «Никак, бл@ть!», где вы также найдете бестселлеры «Как лечь спать в 3 ночи и проснуться в 6 утра?», «Как за одну ночь подготовиться к сессии?» и «Как успеть до дедлайна?»"

К сожалению, текст не очень соответствует названию. Эта статья не про «Как понимать чужой код», а «Перестаньте гавнять, сцуги!» (и тут я вас полностью поддерживаю).
.

Это кусок кода из алгоритма md5. И я сам не знаю, что он делает. Единственный способ его понять — знать сам алгоритм md5, уметь в уме рассчитывать md5 и пройти код пошагово, сопоставляя с тем, что выполняется в самом алгоритме.
Та не надо его понимать. Его надо вынести в отдельную «абстракцию», назвать понятно, добавить тесты (про которые в статье почему-то ничего нет) и стараться туда не лазить без понимания внутренностей (то есть если вы не являетесь спецом по хеш-функциям и тд).
.
И тут часть ответа на то как понимать чужой код:
Его не надо понимать! Если код гуано, его надо или переписать (надо объективно оценивать свои навыки и обстановку), или отрефакторить (но тут таки уже надо понимать что делает код), или «законсервировать» (вынести в отдельные файлы/функции/классы, добавить тестов и не лазить туда).

82 комментария

Подписаться на комментарииОтписаться от комментариев Комментарии могут оставлять только пользователи с подтвержденными аккаунтами.

Есть такое понятие — самокоментирующийся код.

возможно и непонятно выражение

function doSomething( param) {

    if( param === 3) {
        doAnother();
    } else {
        doAnother2();
    }
}


Но если изменить название переменных и констант вот так:

function auth( status) {

    if( status === STATUS_NO_ERROR) {
        login();
    } else {
        sendBadPassword();
    }
}
Станет намного понятней и не так важно как и куда идет логика, за пределами функции auth, она находится в другой области видимости, вероятно кем-то написана и вероятно работает.

Предположу, что эта часть кода находится на сервере и участвует в логике авторизации пользователя. То есть, непосредственно логика определения верного пароля находится вне метода auth, а сам метод auth определяет, обозначить пользователя как вошедшего или «отправить плохой пароль»?
Ну, конечно же, я вас понял, sendBadPassword будет отправлять сообщение об ошибке о неверном введенном пароле, при этом, если на текущий момент времени у нас не будет доступна база данных, то вместо «попробуйте позже» пользователю покажем сообщение «неверный логин или пароль».
Я правильно понял логику написанного вами кода?:)

Вероятно, это ведь пример. Для плохого конекта можно добавить что-то такое

if( status === STATUS_BAD_CONNECT) {
    sendError( STATUS_BAD_CONNECT)
}
тут sendError стандартный ввод любых ощибок

Ще одна причина для прочитання чужого коду: навчатись програмуванню для початківців, а також як не варто робити (у випадку з поганим чужим кодом, на якому основний акцент у даній статті).

Інколи поганий код виникає в результаті етапу прототипу, який потім ніколи не допилюється у продакшин варіант.

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

Есть. Лови:
double magic_constant = 3.3752*32768;
size_t numcep = algobs.get("params.mfcc_ord", 20);
size_t modelorder = algobs.get("params.modelorder", 0);
bool dither = algobs.get("params.dither", true);
bool sumpower = algobs.get("params.sumpower", true);
bool usecmp = algobs.get("params.usecmp", true);
std::string fbtype = algobs.get("params.fbtype“, “fcmel”);
double minfreq = algobs.get("params.minfreq", 0.);
double maxfreq = std::min(fs/2., algobs.get("params.maxfreq", 8000.));
double lifterexp = algobs.get("params.lifterexp", 0.6);
Понятные имена наше все.

З.Ы. И не надо обобщать — это в аутсорсерах-бодишоп плодят индусский код.

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

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

Проект, де є наприклад метод на 600 лінійок, у якому рахується наприклад репорт, і от за певних умов у певному аккаунті, у певній ситуації він генерується із помилками. Треба пофіксити. І такі всі таски, щось десь не працює, і треба це фіксити. Або у певному аккаунті статуси продукту відображаються погано. Ти дивишся у код, а у тебе у продуктів нема поля статус, ці статуси рахуються на основі наявності чи відсутності у продукта певних даних. Код, який рахує ці статуси скаладається із each і чотирьох владених IF, плюс методи у IF мають це свої IF. Не проблема знайти що змінити, проблема зрозуміти логіку (яка може у коді різнитись від логіки проекту), внести зміни, і ще нічого не поламати, щоб за інших умов працювало. Тестів нема.

Метод на 600 рядків на рубі? Трошки дивно, м’яко кажучи.

Саме так, на ROR. Там просто...

Згадалось як дебажив mPDF. Там схожий код + основний файл на більше, ніж 30000 рядків. PhpStorm впадав у часті фрізи.

Как дальше жить?
дрючком по рукам пока не выровняются.

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

В смысле, названия переменных, методов, синтаксис? Поделитесь правилами ваших Code Conventions:)

Спасибо:)
И все-таки, если названия переменных не соответствуют Code Conventions, то вы, вероятно, вчитываетесь в код, понимаете его, и только после этого сможете дать корректное название переменной, правильно?:)

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

Как, как. Как всегда: скрепя сердце, скрипя зубами :)

работает же, вот и не трогай. че туда лазить?

«Работает — не трогай», так можно отвечать тем, кто интересуется, стоит ли рефакторить или переводить рабочий код на новые библиотеки.
Другое дело — когда мы вынуждены в чужой код вносить изменения.

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

где-то на просторах хабра встречал:
«Ехал цикл через цикл
Видит цикл в цикле цикл
Сунул цикл цикл в цикл
Цикл цикл цикл цикл» ©

Автор привёл в качестве примера код после минификации. Думаю, оригинал несколько понятнее.

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

К сожалению, текст не очень соответствует названию. Эта статья не про «Как понимать чужой код», а «Перестаньте гавнять, сцуги!» (и тут я вас полностью поддерживаю).
.

Это кусок кода из алгоритма md5. И я сам не знаю, что он делает. Единственный способ его понять — знать сам алгоритм md5, уметь в уме рассчитывать md5 и пройти код пошагово, сопоставляя с тем, что выполняется в самом алгоритме.
Та не надо его понимать. Его надо вынести в отдельную «абстракцию», назвать понятно, добавить тесты (про которые в статье почему-то ничего нет) и стараться туда не лазить без понимания внутренностей (то есть если вы не являетесь спецом по хеш-функциям и тд).
.
И тут часть ответа на то как понимать чужой код:
Его не надо понимать! Если код гуано, его надо или переписать (надо объективно оценивать свои навыки и обстановку), или отрефакторить (но тут таки уже надо понимать что делает код), или «законсервировать» (вынести в отдельные файлы/функции/классы, добавить тестов и не лазить туда).

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

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

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

Предположение, что если код непонятен, то он гуано, неверно
Верно, ибо
наверняка некоторые из переменных внешнего контекста из примера с md5 — это какие-то lookup таблицы
Про оптимизации: Эти однобуквенники можно было назвать lookupТаблицаИлиТипаТого.
Про непонимание автором предметной области:
1) Если автор исходного кода не понимал ее и допустил ошибки, то таки гуано.
2) А человеку который читает код и не надо понимать предметную область, если код написан хорошо (та самая инкапсуляция, которая должна была оградить читающего от __необходимости__ понимать тот или иной код).
.
Есть оговорка: Однобуквенники могут оказаться «общепринятыми обозначениями», но тогда просто пример автора не очень удачный.
человеку который читает код и не надо понимать предметную область, если код написан хорошо
только когда предметная область не уходит далеко от преобразования XML в стектрейсы.

Если lookup таблица будет называться, например, sinLUT, то вам от этого алгоритм редко станет понятнее, по крайней мере пока вы не прочитаете код, который эту таблицу инициализирует. Придумывание хороших и понятных имен и правда является одной из самых важных и нередко самых сложных задач, но глупо думать, что до минификации яваскриптового кода о его красоте можно было судить не понимая что он делает и насколько сильно его автор вынужден был жертвовать читабельностью ради скорости. Вы же не думаете, что, например, факториал в реальной жизни считают как function factorial(n) { return n ? n * factorial(n - 1) : 1; } ?

Если lookup таблица будет называться, например, sinLUT, то вам от этого алгоритм редко станет понятнее, по крайней мере пока вы не прочитаете код, который эту таблицу инициализирует
Ок, а если в придачу к sinLUT (я так понимаю таблица синусов) добавить еще и понятные названия для других сущностей? Это автоматом дает ключевые слова для поиска и тем самым облегчает понимание алгоритма.
Если с синусами угадал, то почему бы ее не назвать sinLookupTable/sinTable, что таки улучшило бы читабельность.
насколько сильно его автор вынужден был жертвовать читабельностью ради скорости. Вы же не думаете, что, например, факториал в реальной жизни считают как function factorial(n) { return n ? n * factorial(n — 1) : 1; } ?
И снова пример «мимо кассы».
Наивное итеративное решения будет оптимальнее, при этом __читабельность__ не ухудшится.
Добавление банального кеша так же не ухудшит читабельность.
Применение более эффективного мат аппарата (если я все правильно помню то что-то там с Гамма-функцией) так же не ухудшит читабельность и понятность, при условии что называться будет понятно, а не G или какое-то k123.
.
Не надо путать «читабельность» и «изящность».

LUT — это таки стандартное обозначение, понятнее, чем table. Но даже когда вы знаете, что там синусы (чего-то), то вы в название не вложите то, что это sin((2n + 1)*PI/6) например. Названия не всесильны, надо понимать что там делается.

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

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

Но даже когда вы знаете, что там синусы (чего-то), то вы в название не вложите то, что это sin((2n + 1)*PI/6) например.
А как конкретная формула влияет на читабельность? По словам «md5 sin table» я смогу что-то нагуглить в отличии от «k h» (или какие там были буквы в примере).
Способов посчитать факториал много, но ни один из имеющих практическую пользу не будет выглядеть как факториал для человека, который не понимает стоящей за этим теории.
Если все сведется к «закодить формулу с 10-ком констант», то таки да без теории тут не понять. Но его и не надо понимать, надо будет просто сверить формулу (название которой долго было бы быть в коде, например в названии конкретной имплементация).
Во многих случаях и в комментариях прийдется писать статью достойную википедии чтобы что-то попытаться прояснить читателю не знакомому с предметной областью.
Так же хороший пример гуанокодинга, тут конкретно гуанодокументирование. Если ваш комментарий превышает 5-10 строк, то его надо было выносить в вики страницу, та же самая инкапсуляция :)
Иногда приходится жертвовать и тем и другим.
А можно реальный пример того когда __необходимо__ жертвовать читабельностью?

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

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

Я не пытаюсь сказать, что все равно как что называть и переменные h, v, a, G являются отличными и универсальными. Просто не возводите самодокументирующий код в абсолют.

Make things as simple as possible, but not simpler.

Реальные примеры легко найти
Можете почитать если интересно.
То есть реального примера (хорошо бы еще и с указанием того что вот тут мы назвали функцию ххх, а тут проинлайнили 100500 строк) нет и не будет?
.
UPD.
Последнее, что помню точно видел из открытого кода — boofcv.
Вот смачный кусок гуана. Если я правильно нашел.
github.com/...ockPyramid.java
Что тут сделано для оптимизации?

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

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

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

Ищущий да найдет.
Нятно: у вас нет аргументов, но признать свою неправоту ЧСВ не позволяет.
Этот код работает очень быстро
А он станет медленно если в 123-124 строках дать нормальные имена переменных (а не x1)? А если переменную w (строка 92) назвать больше чем одним символом, как это просадит производительность?
В 190-193 вынести дублирование в методы и объявить переменные константами?
Большие циклы вынести в методы?
.
Код вполне может быть быстрым (я не замерял), но вот не вижу где тут потерю читабельность можно оправдать оптимизацией. Если вы укажете, а не сольетесь, было бы интересно просто увидеть пример.
.
UPD.
Если вы, все же, считаете, что нет прощения написавшему эти строки, то предлагаю прекратить дискуссию как безблагодатную.
Прощение есть, автор скорее всего не программист, а математик-или-типа-того.
Вопрос в том считать ли такой код нормой, или принять как прототип, а потом отдать программистам, на доведение до ума?
Предположение, что если код непонятен, то он гуано, неверно.
в таких случаях хорошая практика как минимум написать комент как работает. а если смотришь в код, а оттуда аж штыняет экскрементами это чистейшее гуано.

Иногда объяснение занимает статью в Википедии. Известный пример — Fast inverse square root.

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

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

А если она таки есть, то это действительно хороший вариант.

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

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

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

Начнем с того, что я никогда не возьму на проект, в котором есть нетривиальная логика, формошлепа Васю — пусть себе пишет опердень.
Возьмете. Когда проект в саппорт скатится. Как раз именно формошлепа. А потом он как раз на тему рефакторинга начнет читать. И увидит, что код без коментов. И давай все «гуано» переписывать на «гуано2». Почему он этим будет заниматься? Да потому, что код без коментов — «гуано». В целом правильно писали выше про Code Conventions и Code Review. Облегчает жизнь.

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

Я же тут не умозрительные гипотезы в голове сочиняю.
Но при этом не привели не одного примера или доказательства. Хм.
Я прекрасно знаю какие места у меня в коде будут 200 раз менять и рефакторить, а куда никогда не ступит рука человека.
Сударь предсказывает будущее?
И последние покрыты тестами так, чтобы уж точно туда лазить не пришлось, а если кто и залезет и поломает, то тесты упадут.
А код который постоянно меняется не надо покрывать тестами? ... Ах да я забыл, вы то знаете где что поломают.
вы можете придумать разумную ситуацию в которой формошлеп решит рефакторить работающую функцию подсчета md5, принципиально при этом не разбираясь предварительно как она работает?
А вы знаете определение понятия «рефакторинг»?
С другой стороны «формошлеп» как раз и не будет лезть рефакторить ни md5, ни банальный CRUD, на то он и «формошлеп» (и тут не важно «формошлеп» или «матаношлеп»).
А то тут же предлагают мне писать код CV библиотеки так, чтобы его менял человек, который не знает алгоритма, реализацию которого меняет,
Более того вам указали что именно там надо изменить, хотя это не было целью.
и ниоткуда кроме названий переменных этот алгоритм изучать не желает.
То вы рекомендуете не вдаваться в крайности (не возводить самодокументирование а абсолют), а то вдруг «ниоткуда кроме». Вы уж или крестик снимите, или штаны оденьте ©

По-моему, это все крайности. Но что я могу сказать: на грабли народ наступает исправно. И сколько не пиши «правильного» кода, практически всегда можно написать «правильнее». По разным причинам. Кому-то надо продемонстрировать свой вклад в проект, кто-то книгу прочитал и давай все улучшать, кто-то не так понял задачу «ревью», «клинап», «рефакторинг» etc. Суть моего высказывания — что будут и формошлепы менять многое вплоть до архитектуры, будут и неожиданные куски кода переписываться (и не только формошлепами, а когда, например, схлестнутся адепты различающихся подходов), будут и тесты переписываться, чтобы «новый код проходил — после изменений» а то и вовсе удаляться. Но вот если давать человеку вводные: Code Convention — до, Review — после, то некая направленность у него будет. То есть, «гуано» он, конечно, будет продолжать генерить, но это будет «гуано», к которому привыкли на проекте/у заказчика/в компании.

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

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

само их использование не гарантирует «красоту», а можеть так же легко прирвести к гавну в архитектуре, что еще хуже

Ну любой дев имеет право их не использовать ;-)

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

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

Когда человек привык следовать принципам Clean code — он уже не может без них. Грамотного человека трудно заставить писать с орфографическими ошибками. Ему будет неприятно.

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

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

но рабочий код никогда не будет красивым и книжным
Це не є вірним твердженням. «Красивий» та «книжковий» код існує, як пряма інвестиція в нормальний і рівний розвиток проекту. І, до того ж, такий код є напрочуд робочим та простим у підтримці. Мені цікаво звідки у вас такі думки. Справді.

Був такий гіркий досвід у мене. Прошу зауважити, що я не закликаю писати одразу обфускований код. У моєму досвіді були приклади коли треба зробити «отак і отак» за досить обмежений проміжок часу(дні чи години) і про можливий рефакторинг мови взагалі не йшло, тому що «все работает же». Все залежить від замовника.

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

Тут справа у розумінні замовника та його адекватності. Якщо він розуміє що заплативши зараз за рефакторинг збереже кошти на підтримку у майбутньому — це дуже добре. А якщо цю думку донесе менеджер, то він точно не зайвий на проекті.

Доведіть це будь-якому замовнику на фрилансі.

Так ми про сам факт існування «книжкового» коду чи про рівень очікування нетерплячого замовника, який очікує на готові пиріжки вже через дві години? Я наразі певен, що навіть «мінімальна + трошки більше» самоорганізація та самодисципліна дає потім суттєвий виграш навіть у межах стислих часових рамок. Чому «наразі» — займаюсь виключно довготерміновими продуктами. Зрештою, скупий платить двічі.

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

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

Вносили знаем, если случай не самый запущенный достаточно умения нажимать «Go to definition», но если пациент применял паттерны — быть беде.

Больше похоже на обфусцированный код. Может специально сделали для исходников md5.

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

Я бы также посоветовал всем (не только джунам) почитать книгу Clean Code.

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

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

Хорошая статья. Повидал много г-кода, но еще раз ткнуть носом для профилактики не помешает :)
Спасибо.

Вам спасибо:)

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

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

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

вы сильно плохого мнения о самоучках

Здесь ещё интересно вот что: разве есть другой путь, кроме как

Просто 1-1,5 роки почитав книжечки по відповідній мові і пішов працювати
?
Или надо 2-3 года читать книжечки? По-моему, вариантов особо нет.

" Как понимать чужой код? Читайте в сери книг «Никак, бл@ть!», где вы также найдете бестселлеры «Как лечь спать в 3 ночи и проснуться в 6 утра?», «Как за одну ночь подготовиться к сессии?» и «Как успеть до дедлайна?»"

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

Само собой. Ревьювить код нужно всем:)

Раньше заходил на StackOverflow, отвечал на что мог, разбирался в чужих проблемках (не очень сложных).
Правда, иногда тамошний код самое что ни на есть откровенное г@yно, но это даже и в «плюсик» к умению разбираться в чужом коде и адаптироваться, менять взгляд, а порой и мышление, в зависимости от качества кода :)

Подписаться на комментарии