Археалогія програмнага забезпечэння: практычны метод для анаізу коду з минулых версыйяў
Выучыце пасляпасовы падход для абяранлівага дакладнага аналізу кодавых баз, якія не маюць дакладнай документацыі: ад аналізу історыі змян да рефакторавання без парадоксальных наследкіў для працуючага програмнага продукту.
Існуея спецыяльны тип страху, які кожны разработчык рано чыта пасвячае.
Вы ачынаеце файл. У яму паўз 4 000 ліній. Не адна жадная прыметка, палова зменных называюцца такімі іменамі, як x2 або tempFinal_REAL, а дзе-небудзь усередзіне знаходзится функцыя пад назвай doStuff(), якая, за вашым мненням, таямна адпаведальная за вырахунакі ў всій кампаніи.
Вы запускаеце git blame, і следы вядуць да чалавека, які пакінуў кампанію шасць гадоў тыму. Пошук у Slack не дае нічога пра тое, чаму все гэта існуе. Яедыны чалавек, які можа ўсё ж такі памятаць, зараз не на рабочым месцы, і, часом, ён таксама можа не памяцать деталей.
Гэта – археолагія програмнага забезпечэння.
Гэта не паказваецца ні на якій схеме адміністрацыі ні ў абавесцях пра вакансіі, але якщо вы вже паўгодзіны чы то два гады працавалі над напісаннем програмнага забезпечэння, вы вже практыкувалі гэта. Вы аналізавалі стары код так, як польскі археолаг пераглядае месца раскопак — паступова, уважна, намагаючыся з’ясаваць, пра што насправды думалі тыя, хто яго створыў, нават якіх уже няма і якія не можаць нічога раз’ясніць.
Наступнае — гід па тым, як эфектываўна выканаць гэю роботу, не втрачаючы розуму і не парушуючы працэс вырабоцтва.
Што насправды ёсць археалогія програмнаг забезпечэння?
Археалогія програмнаг забезпечэння — это дакладжанне, адказванне та разумеўце старог чы недокументаванаг коду, зазвычай каб можна было безпечна яго падтрымваць, расшырываць чы зрэшты заменіць.
Это іншая задача, чым звычная дэбаггінг. Дэбаггінг выконваецца на падставе прыязнення, што вы розумееце систему і ў яй чыгнула якаясь проблема. Археалогія програмнага забезпечэння выконваецца на протылежной падставе — вы ўсё яшчэ зовсім не розумееце систему, і першая справа — аднакоўсі це розумэнне, перш чым смелаць чаго-небудзь зменіць.
Это розныя справы: механік, які рэмонтуе автомабіль, з яким працаваў гады, і той, хто відновляе Peugeot 1962 года, якога ніколі раней не ачынаў. Той самы набор інструмента, але зусім разны стан розуму.
Большасць інжынераў не выбіраюць такую работу — яна прыходзіць да іх. Вы пачынайце новую работу, а за шасьць тыдзяней хтось даў вам заявку, якая стосуецца „старога абслужвання запасоў“. Раптам вы вяршыце не новы код, а раскопкі.
Чаму гэтыя навыкі маюць большое значэнне, чым прызнаюць людзі
Это некальманавальны факт: большая частка програмнага апарату, які фактычна керуюць светам, не ўжо новыя. Яны старыя, склееныя працой гадоў, часткова зрозумелыя, і сталі прычыной трывогі для тых, хто формальна за ўсім стоіць.
Банкі яшчэ выкарыстоўваюць COBOL, напісаны ў 1970-х гадах. Авіакомпаніі плануюць руты за дапамою систем, якія існуюць ўжо да часаў пілотаў, якія летаюць на гэтых самолётах. Нават стартапы, якія рухаюцца з максимальной швалёй, за год-два накапліваюць код з минулых версый — код, створаны пад тым праблемам працай адной особы, якая згодзе перайшла ў іншую команду, і які рашаў проблему, якая нігде не была задокументавана.
Якщо прабаваць новы код — гэта ўсё, чаму вы ведаеце, то вы обмежаны новымі проектамі. Але якщо вы справдзебна можете чытаць стары код — так сама, як дэтектив аналізуе месца злочыну — тады вы стаўце тымі, да каго звертаюцца інжынерскія команды, калі трэба паспрабаваць выправіць ўскладненыя проблемы. Гэта професійная перадача, пра якую рэдка калі ведуць адкрытая размова.
Мысленне археалага
Перш чым перейść да конкрэтных тэхнік, неабходна змяніць падход, якае значна спрыяе ўсем наступным крокаў.
Працаваць з гадкай, што код колісь мяў сэнс для каго-то.
Гэты прыем пера мае большое значэнне, чым будзь-яка іншая тэхніка з гэтага списку. Калі бачыш заплутаны, незрозумелы код, лёгка ўважаць, што той, хто яго напісаў, не ведаў, што робіць. Але гэта практычна ніколі не ёсць правдой. Частае прычына — гэтасябржы термін, обмежэння, якое вам больш не видна, системныя трэбаванні, якія згодзе зниклі, або прыказка, якая ў 2016 годзе здавалася абсолютна разумной, але пасля таго больш ніколи не рассматрывалася.
Уявіце сабе, калі заходзите ў стары дом і бачыце нешта на кшталт опорнага балка ў дзівным, здаецца, абэктываўшымся месцы. Здаецца, што ён не служыць ніякой мэты — пакуль вы не дазнаецеся, што там раней стаяла стэна, якую зніслі, і тады гэты балак стаў ёдынай раштою, якая не дазволіла даху зваліцца. Кодавыя базы спадчыны заполнены такімі балкамі. Перш чым ўсё чаго-небудзь трагнуць, ваша задача — з’ясавіць, што кожны з іх таямніча падтрымае.
Застосаванне такага падходу дае вам два прынцыпавых выгоды: ён спакойвае вас ў стосунку да савых прыпускаў, а таксама заменяе разчароўванне цікавасцю. Цікавасць, як выявляецца, ў дзiesięć разоў эфектывнейшы інструмент для адлучэння бягаў, чым будзе калі-небудзь раздражэнне.
Тактыкі для аналізу кода з минулых версый
1. Чытайце історыю змян як дзённік
Історыя Git — гэта тое, чым можна парадна заменіць справжню машыну часу. Не проста адзірвайце тэкучы стан файлу — выявіце, як ён там з’явіўся.
Выкананне команды git log --follow для конкрэтнага файлу часта адкрывае правdziвую історыю: функцыя, якая была дадана ў спешцы прыпынку перед важлівай дэманстрацыяй для кліента, поспешны выправленні, апублікованы пазно ў пятак увечары, або каментар з напісам "тэмпарарны рашэння, адмаўіць пасля запуску ў трэцьму квартале", які зараз вже чатыры годзі стары.
З’явілася картынка з незвычным оператаром if, який стосуўся толькі однаго ID кліента, без жадных пояснень. Перагляд записаў git blame паказаў прыметку ад таго, хто яго напісаў, у якой пояснювалася, што у виробных данных адпаведнага кліента была памылка, і што гэты контроль мяў на мете толькі тымчасова утримаць ситуацыю, пакуль кліент не выправіць свою частку. Гэты тымчасовы раўянак таямна застаўся у сіле прыблізна пяць гадоў. Розуменне прычын змяніла спосаб, яким команда ў канцэ нарэшце яго адключыла — вони стаўіліся да гэтага адпаведальна, выкарыстоўваючы правільную міграцыю дадзеных, у замест на простае выдаленне контролю і надзію, што нічога не зламаецца.
2. Следзіце за дадзенымі, а не толькі за кодам
Код паказвае, што могла выйсці. Дадзеныя паказвают, што фактычна выйшло.
Якірцуйцеся безпасэчна да базы дадзеных. Паглядзіце на рэальныя рядкі. Якшто табелю ёсць столбец status з значэннямі на кшталт 1, 2, 7 і 99, не намагайцеся выявіць ўсё значэнне гэтых значэнняў толькі па чытанні коду — запрашайце рэальныя записы для кожнага значэння і студзіруйце, што з імі адбылася на практыцы.
Рассмотріце поле type у старай табелі замовленняў, дзе кодавая база урахоўвала толькі значэнняя з 1 па 5, але рэальныя даныя паказвалі тысячы рядкав з type = 0. Аказалася, што 0 означае „створана ўчора, калі поле type яшчэ не існавала“ — частка історыі системы, якая зникла з нынешняга коду, але ўсё ж засталася там, чытабельна, у даных.
3. Размова з „праэктамі“ (таксама вядомымі як людзі, якія ўсё ўсё тут)
Нават калі тыя, хто стварыў частку системы, давно зниклі, як правіло, хтось у близкасці володзіе фрагментам контексту — тыя, хто спачатку прыjęлі гэтага чалавека, інжынер падтрымкі, який рашыў багато запитаў на гэю тэму, або менеджер продукту, які ўсё ж памятае „гэты інцыдент“.
Задавайце конкрэтныя, менее напружаныя запитанні замест шырокіх. „Што робіць гэты код?“ прабуджае здагадкі, бо ён занадта нечыясны. „Чы гэтыя памятайце што-небудзь не звычнае па часткі обробкі вярнення грошаў у 2021 году?“ ёсць настаткі конкрэтным, каб прыгадаць реальную інформацію.
4. Створыце карту прычым да таго, каб чамусь не трогаць
Археалагі ніколі не прыначаюць раскопакі аднойчынна — спачатку яны ствараюць карту месца. Той жа прынцып трэба застосавіць да кодавой базы.
Нарисуйце, хоць і прыблізна, на паперы або ў докумэнце, справжнія даныя траекторыі, якія вона праходзіць праз систему: калькі запускаюць калькі іншыя, якія часткі зберагаюць інфармацыю у запам’ятовальніку, і на якія компоненты павязаны іншыя. Вам не трэба выкалічанага дыяграмы — проста патрэбна достатня колькасць інфармацыі, каб больш не было неспадкоў.
Адны корыстны трюк: выберыце адну рэальную дзейнасць, напрыклад „пользователь анулюе сваю падпіску“, і праследавайце яе з самага пачатку да канца, фіксуючы кожны файл і функцыю, через якія вона праходзіць. Следаванне за гэтым адным шляхам часта паказвае большую частку таго, што вам трэба знать пра систему ў цялы.
5. Напісці тэсты перад рефактораваннем
Якщо у базе коду зовсім немае тэстаў, што ўзніклае часта ў старых системах, стрымайцеся ад бажання выправіць усё за одну спробу. У замен напішыце так званыя тэсты характарызаціі — тэсты, якія проста фіксуюць, што код зараз робіць, незалежна ад таго, чы ўсе яго дзеяння правільныя.
Это дае вам два рэзультата адразу: захіст на будучыя змены і прымусовую яснасць, адколі вы не зможаце точна описаць потычную працэзуатыванню, якщо толькі не разумеце яе. Большая частка цянічнасці крыўцяцца з самага процесу напісання тэстаў, а не толькі з ўжывання іх.
6. Зменяйце адна рэч за раз
Калі вы нарэшце зразумеце складную систему, выклікаеся спакуса перапісаць усё за одну, масштабную прыемку змян. Не робіце гэтага.
Сістэмы-спадчыны частаюць быць болей шкодзяблымі, чым здаецца, і гэта таму, што жадна адзін чалавек не володзіеюць пачатковым абразамом усіх залежнасцей. Выкананне маленькіх, вярнагаецца змян — по адной, кожная з яых пераканальвалася пры пераходзе да наступной — гэта спосаб прыменшыць рызык таго, што ваша праця стане наступным незрозумелым элементам, які будзе трэба расшукаць будучым археалагам.
7. Документавайце тое, што знайдзілі — для наступнага чалавека
Усё, што вам удаецца аднайсці і зрозумець, вартаяць зберагчэння. Запісуйце гэта будзь-дзе. Нават короткі, неформальны, непূরны дакумент пад заглавлём на кшталт "Як на самай працуеяць Служба выкалення рахункоў-спадчыны" ёсць подарункам для таго, хто будзе спадчыннікам гэтага коду пасля вас — і тым чалавекам можаць стаць вы самі за шасць месцаў, калі забудзеце все.
Короткая історыя: Функцыя, якую ніхто не разумеў
У адзінай кампаніі адзіна функцыя здобыла прозвішча «звяр» — 900 ліній коду, спакаваных глыбока ў процесе адправкі пакупкаў, з якімі ніхто не хацеў працаваць. Новых спецыястаў паведамлялі пра гэта пад час адбору, напалові як у жарт, напалові як сэрьёзную історыю, падобную да местнай фалклоры.
У канцэ нарэшце хтось вырашыў як след з’ясавіць структуру гэтай функцыі замест таго, каб яе айшоў ухіляцца. У замяну спробам перапісаць код яны стасканавалі рэальныя транзакцыі, якія праходзілі через гэтую функцыю, практычна апісалі кожную ветку логіки і напісалі тэсты, каб пераканацца, што кожны магчымы пат старанна пераканаўся. Усі гэтыя працы зайнялі апошней часаву.
Тое, што яны адкрылі, не было хаосам — выявілася досыта цэлесапраўдная система для керування пяцьма разнымі прадавцамі адплатаў, кожны з якіх меў сваю сэрыю особлівасцей і спецыяльных кейсаў. Яе створыў чалавек, які рашаў рэальныя, конкретныя проблемы пад рэальнымі абмежэннямі, без можлівасці пазней прыбраць усё да ладу. Калі ёе цэлыя структура была з’ясавана, гэта явішча перестало будзьць страшным. Ён застаўся складным, але тепер цэ была складнасць, якую хтось насправды розумеў.
У сутнасці, гэта і є вся галузь: ператвараць страх у карту.
Заключныя думкі
У археалогіі програмнага забезпечэння няма ніч гламурнага. Ніхто не пісае „вмелы ў расшифраванні заплутанага коду іншых людзей“ як ключовую навыку у сваёй рэзюме. Аднак гэта застаўся адным з найболей корыстных, але ў той жа час найбольш занедбаных навыкаў у інжынерыі програмнаг забезпечэння.
Стары код не трэба відмахваліць як непатрэбны — ён є архівам рашынакоў, прынятых пад тым пячом і абмежэннямі, пра якія вы можаце нават не ведаць. Падходзіце да яго з цікавасцю, а не з суджэнням, і вы зробіце болей безпечныя змены, а таксама, верагатэльна, павідоміце, што цей процес ў дзiesяць разоў мае большую цэннасць, чым вы спакульвалі.
Таму наступны раз, калі якісь файл змусіць вас захацець закрыць крышку ноутбука і выйсці на вуліцу, зупніцеся і аддышыце на секунду. Тое, што вы бачыце, — гэта не руіны. Гэта месца археалагічных раскопак, якое чакае на розумэнне.
Взяце пензель, а не бульдазер.
Спадневаная літэратура
- Дзевяць прыкмет, якія на рэвэле коду спакойваюць работу вышэйшых інжынераў і падвышаюць довяроўнасць ў іх работе — Расглядае дзевяць конкрэтных практык напісання коду — ад клазаў захавання да строгага модэлювання дадзеных — якія робяць код болей стойкім, чытабельным і простым у дыбагаванні пад тэншам.
- Дзесяць часта павтараючыхся прыкмет JavaScript, якія таямніча падрываюць ваш кодбэйс — Пасвячана дзесяць распашчытных проблем у JavaScript і TypeScript, ад слабкай роўнасці да мутацыі стану, і паказвае безпечнейшыя патэрны для замены кожной з іх.