Коли я починав кар’єру програміста, доживав свого віку браузер Internet Explorer 4-ї версії. У ньому була підтримка так званої поведінки ‘hover’ (наведення мишкою на елемент на сторінці) лише для посилань (лінків). Усі решта елементів не підтримували даного стилю. Щоб обійти дане обмеження старенького браузера розробники придумали Javascript бібліотеку, яка штучно навішувала подібну поведінку на усі елементи на сторінці. В одному з проектів ми використовували дану бібліотеку, але, оскільки, елементів із даною поведінкою на сторінці було дуже багато – бібліотека буквально заморожувала сторінку на 5-10 секунд при першому завантаженні.
Моє завдання полягало у пришвидшенні та оптимізації даної бібліотеки. Код був низькорівневий (ніяких Prototype чи jQuery на той час не існувало) і доволі непростий. Щоб розібратись, що роблять цих 200 рядочків коду, я витратив більше, ніж 2 тижня. В кінцевому результаті ми знайшли слабкі сторони даного коду, покращили і адаптували під наші потреби, пришвидшивши його у сотні разів.
Це був мій перший досвід розбору чужого коду. Дався він мені дуже важко. Але з цього моменту я добре зрозумів, на скільки важливо вміти читати і розуміти чужий код: код вашого колеги, код додаткових плагінів, а чи навіть платформи, на якій ви розробляєте.
Тепер, навчаючи інших, з певного моменту, коли бачу, що людина вже непогано справляється із роботою по інструкції та документації, агітую переходити на новий рівень – розбирати проблеми і помилки через занурення у чужий код. Для чого це потрібно, та як краще навчитись читати чужий код – про це все розповім у даній статті.
Для чого потрібно читати чужий код?
Перед тим як переходити до підказок щодо читання чужого коду, варто розібратись для чого нам взагалі потрібно це робити.
Під чужим кодом я розумію:
- код вашого колеги по проекту;
- код додаткових бібліотек та плагінів, які ви використовуєте у своєму проекті;
- ну і звичайно, код платформи, на якій ви розробляєте своє рішення (звичайно якщо платформа йде із відкритим кодом (OpenSource)).
Професійні програмісти працюють над складними завданнями. Досить часто документації бракує, або вона є не зовсім коректною. І навіть дядько Гугл не завжди допоможе, особливо, якщо ви натрапили на не надто популярну проблему. Саме для таких випадків і призначений такий потужний інструмент, як читання чужого коду.
Це одна з причин, чому я надаю перевагу опенсорс технологіям. Дуже класно, коли є доступ до усього коду проекту (включно із кодом платформи, на якій розробляєте) і ви можете розібратись з багами самостійно. Швидко, тимчасово виправивши їх, аніж тижнями чекати відповіді від тих, хто підтримує дану платформу.
Таким чином, якщо програміст не вміє розбиратись із чужим кодом, швидше за все він не буде автономним гравцем у команді, завжди потребуючи допомоги від колег. Доволі часто професіоналу швидше і простіше глянути в код, ніж вичитувати документацію. Код ніколи не бреше.
Якщо ви працюєте у команді, тоді вам приходиться читати код ваших колег. Важливо переглядати код колег. Навіть якщо ви працюєте над різними завданнями, які не перетинаються. Це може бути і у вигляді регулярного рев’ю, як частина ваших обов’язків. Старші по званню роблять рев’ю коду молодших. А також це може бути і власна ініціатива, щоб бути в курсі проекту загалом.
Тільки читаючи код ваших колег, ви зможете переконатись, що притримуєтесь спільних стилів коду, практик і технік. Один проект, бібліотека чи плагін повинні притримуватись спільного стилю та технік. Також зможете переймати підходи і шаблони ваших колег, які ви вважаєте, є кращими, ніж ваші поточні. Подібним чином, пишучи якісний код, з тестами, ваші колеги можуть переймати ваші підходи до виконання завдань. В команді програмісти діляться досвідом через код. Це працює найкраще.
Також потрібно розбиратись із чужим кодом, якщо ви починаєте працювати над існуючим проектом. Доволі часто приходиться допилювати або підтримувати існуючі проекти, початково створені іншими. В такому випадку перебрати на себе обов’язки програміста означає розібратись із існуючим кодом. Навіть, якщо попередні програмісти писали тести і документацію (нажаль це є рідкістю, адже писати документацію значно нудніше, ніж писати код ;-), все одно приходиться зариватись у їхній код, щоб розуміти, куди вставити свої оновлення.
Писати проект з нуля простіше. Тут не потрібно розбирати чужий код, не потрібно підтримувати стиль коду та форматування попередників. Усі правила і тон проекту задаєте ви самі. Це класно, якщо ви профі і знаєте, як це робити правильно. Початківцям я рекомендую вливатись у команду і працювати вже над існуючим проектом. В такому випадку, людина має доступ до коду, написаного досвідченішими членами команди. І лише перейнявши правильні базові принципи, переходити до проекту з нуля.
Читання чужого коду також є дуже потужним інструментом у процесі навчання програмуванню. Далеко не кожен початківець має доступ до команди програмістів, яка працює над реальним проектом. Саме тому, усім початківцям, які вже вміють реалізувати задачі згідно документації, я рекомендую переходити до більш складних завдань, які вимагають занурення у чужий код. Код, з яким вони мають справу, але ще поки цього не усвідомлюють. Саме тому, я рекомендую починати із OpenSource технологій, де людина має доступ до усього коду, включно із самою мовою програмування (до речі Python дає вам доступ до усього коду).
Програмування – це ідеальне ремесло, щоб навчатись із досвіду інших. Вам не потрібно знати Гвідо ван Росума, щоб переймати досвід автора мови Python і застосовувати його у своїй щоденній практиці. Достатньо регулярно читати код його ОпенСорс проектів і досить швидко матимете результат.
Думаю, більшість класних письменників не лише багато пишуть, але й дуже багато читають інших письменників. Кожен початківець вбирає у себе сотні стилів інших авторів і, в кінцевому результаті, комбінує для створення свого власного неповторного стилю. Так само і програміст, щоб перейти від навчального коду згідно туторіалів і документації, повинен регулярно проводити час за читанням чужого якісного коду.
Початківець, як тільки починає читати код інших, отримує автономність. З цього моменту, практичну будь-яку проблему, може вирішувати сам. Навіть якщо документація і Гугл не допомогли. В протилежному випадку, він завжди шукатиме поради у більш досвідченого спеціаліста.
***
Я розумію, що усі ми, програмісти, не любимо занурюватись у чужий код. Особливо якщо він не дуже гарний і дуже відрізняється від того стилю, до якого ми звикли. Це як і у будь-якій іншій професії. Кожного разу, коли приїжджаю з поломкою на своєму авто на іншу станцію технічного обслуговування, мені чемно вказують на те, що тут була зроблена халтура. Що попередній майстер полінувався, або не мав достатньої компетенції (все це мені пояснюють у більше приземленішій формі ;-)).
Так само і ми, зазвичай думаємо, що код попередників є гіршим, ніж наш. Навіть свій власний код ми перестаємо любити після того, як мине 2 тижні з його написання. І це нормально. Це означає, що ми прогресуємо і навчаємось нового. Тим не менше, варто переосмислювати своє ставлення до чужого коду. Він завжди дає нам можливість навчатись як варто робити та як робити не варто. В кінці кінців, якщо ми не прочитали масу чужого суперового коду, звідки у нас візьметься розуміння того, що таке якісний код і як його писати?
Якщо тепер ви погоджуєтесь, що варто подумати над тим, щоб частіше заглядати у чужий коду, пропоную переходити до практичних порад. Вони допоможуть швидше розбиратись із чужим кодом.
Як практикуватись у читанні чужого коду?
Починати читати чужий код є завжди непросто. Особливо, якщо починаєте розбирати код платформи, на якій програмуєте. Простіше, якщо код колег або додаткових аплікацій. Знову ж таки, важче, якщо код вашої мови програмування та її додаткових бібліотек.
Незалежно від того, який код вам прийдеться читати першим, ось кілька технік і порад, які я сам постійно використовую. Вони допомагають не здаватись передчасно, швидше розбиратись із чужим кодом і таки доводити діло до кінця:
Збудуйте і запустіть код, який потрібно зрозуміти. Якщо є така можливість, запустіть проект, частину коду, яку вам потрібно прочитати і зрозуміти. Спробувавши попрацювати із кодом як кінцевий користувач, ви зможете легше розуміти сам код. Нажаль, не завжди є можливість збудувати і запустити код, тому наступні кроки допоможуть у такому випадку.
Не фокусуйтесь на деталях на початку. Перше, що вам потрібно зробити, особливо якщо коду багато, це швидко пройтись по ньому не звертаючи увагу на деталі. Вашим завданням є відчути стиль коду, структуру проекту, спробувати зрозуміти за який функціонал відповідає та чи інша частина коду.
Не витрачайте занадто багато часу на даний етап. Ви ще не раз до нього повертатиметесь пізніше.
Переконайтесь, що розумієте усі конструкції та функції використані в коді. Другий раз пройдіться по коду, але тепер зверніть увагу на усі місця, які вам не зрозумілі з точки зору конструкції мови, невідомі для вас функції, зовнішні бібліотеки. Якщо ви не супер-експерт вашої мови, то швидше за все знайдете не одну нову для себе річ.
Розберіться із новими для вас конструкціями і функціями використовуючи документацію та Гугл. Без цього шансів зрозуміти код, практично не буде. Цей процес дасть вам багато нових знань про вашу мову програмування. І ті кілька годин вартують нових знань.
Тепер можна зануритись у кілька кусків код більше детальніше. На цьому етапі знову пройдіть поверхнево по коду, але тепер виберіть випадковим чином кілька місць і детально розберіть їх. Це може бути кілька класів або функцій. Якщо застрягли в одному із таких кусків – залишайте, ще буде можливість повернутись.
На даному етапі ви зрозумієте весь ритм і підходити людини, що писала код. Ви ще не раз повертатиметесь до даного етапу, щоб досліджувати інші куски код, але кожного разу маючи все більше і більше розуміння про код і проект загалом.
Почитайте тести, якщо є. До цього моменту у вас мабуть залишиться ще багато незрозумілого коду. Якщо код є покритий тестами, тоді вам пощастило. Тести дуже гарно показуть застосування коду.
Якщо ж тестів немає, і ви намагаєтесь розібратись із кодом, який прийдеться оновляти в майбутньому, тоді це хороша для вас можливість написати тести і, в процесі, розібратись із самим кодом.
Спробуйте виділити складний код у окремі функції. Ще один непоганий підхід для розбору особливо важких для розуміння кусків коду – виділити його в окремі функції. В процесі рефакторизації ви точно зможете краще зрозуміти даний код.
Особливо добре працює даний підхід, якщо дані функції не залежать від інших компонентів, і їх можна окремо запустити і проаналізувати результат.
Важливо розуміти не лише логіку і код, але пробувати вгадувати чому програміст зробив саме такий код, а не інакший. Саме через розуміння основних причин для того чи іншого рішення, приходить розуміння коду.
Доволі часто важко розібратись із складним кодом не знаючи його мети. Таким прикладом служать складні алгоритми кодування даних, обробка та підтримка певних форматів даних. Без розуміння протоколу даних та алгоритмів, зрозуміти такий код буде доволі непростим завданням. В таких випадках, потрібно добряче дослідити документацію та пошукати, що про нього розказують люди в інтернеті, ваші колеги. В кінці-кінців, спробувати сконтактувати людей, які причетні до даного коду.
Часто легше зрозуміти середину, якщо переглянути початок і кінець. Коли я маю розібрати величезну функцію, я починаю із її визначення і одразу переходжу у сам кінець – що функція повертає. Це дає мені розуміння протоколу даної функції, а тому і полегшує читання тіла функції.
Рекомендую вам також пробувати даний підхід. Швидкі стрибки по коду взад і вперед допомагають отримати загальну картину поки без вникнення у деталі.
Не пробуйте зрозуміти весь код від початку до кінця за один присіст. Основна проблема чому початківці здаються при спробі розбору чужого коду – вони думають, що кожен рядок коду повинен бути одразу зрозумілим по ходу їхнього прочитання.
Це не так. Окремий рядок коду практично неможливо зрозуміти без контексту. Усі вищеперечислені етапи служать для того, щоб спробувати отримати загальну картину у кілька окремих підходів. Без детального розбору коду за один присіст.
Великий код практично неможливо порядково зрозуміти за один раз. Потрібно розбивати роботу на частини і в кілька окремих підходів спробувати відкусити все більший кусок.
Читайте чужий код в парах. Дуже класна практика. Навіть якщо ви сидітимете із людиною, яка програмує не краще, ніж ви, думки в голос допоможуть наштовхнути один одного на правильний хід. Вже не кажу, що дві голови це завжди краще, ніж одна.
Шукайте напарника для розбору чужого коду. Швидкість розбору збільшується в рази!
Якщо немає потреби читати чужий код, все одно виділяйте 15-30-60 хвилин щодня на читання чужого якісного коду. Як визначити чи якісний? Більшість популярних опенсорсних бібліотек, фреймворків, платформ написані на хорошому рівні.
За перший тиждень, якщо ви початківець, ви можете не зрозуміти жодної концепції в коді складного фреймворку. Але з кожним днем чужий код виглядатиме трохи простішим і зрозумілішим. Якщо не виходить зрозуміти, треба завчити. А коли завчили, тоді приходить і розуміння. Так і тут. Потрібно лише терпіння і розуміння того, що за один присіст ніхто не зрозуміє весь код фреймворка Django. А щоденні 30хв роботи допоможуть з часом розібратись в усіх деталях.
***
Головне, потрібно розуміти, що читання коду – це навик, який постійно потрібно вдосконалювати. Вам завжди траплятимуться проекти і код, які буде важко розібрати з першого присісту. Але в той же час, з кожною новою спробою ви ставатимете кращим у даній справі, швидкість читання збільшуватиметься і ви зможете легко відрізняти якісний код від поганого. Регулярне читання коду однозначно зробить вас кращим програмістом, незалежно від вашого поточного рівня.
А які техніки і фішки є у вас, що полегшують розбір чужого коду?
Будьмо дружніми!