Как понимать чужой код
Прежде чем перейти к куче текста, посмотрите на код и поймите, что он делает:
Такое пишут разработчики. Кто-то не понял вообще, кто-то только догадывается, что делает этот код. Но есть способ понять его. О нем будет ниже.
Когда мы вынуждены читать чужой код?
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
Читать джуниорам перед сном:
— Стандарт оформления кода
— Комментарии
— Рефакторинг
Все про українське ІТ в телеграмі — підписуйтеся на канал DOU
Найкращі коментарі пропустити