Ne pristajte na razvoj onoga što ne razumijete

Ne pristajte na razvoj onoga što ne razumijete

Od početka 2018. godine obnašam dužnost vođe/šefa/vodećeg programera u timu — kako god želite to nazvati, bitno je da sam potpuno odgovoran za jedan od modula i za sve programere koji na njemu rade. Ova pozicija mi otvara novi pogled na proces razvoja jer sam uključен u veći broj projekata i aktivnije sudjelujem u donošenju odluka. Nedavno, zahvaljujući ova dva okolnosti, iznenada sam shvatio koliko znanje utječe na kod i na aplikaciju.

Misao koju želim izraziti svodi se na to da je kvaliteta koda (i konačnog proizvoda) usko povezana s tim koliko ljudi koji se bave dizajnom i pišu kod, svjesni su onoga što zapravo rade.

Možda sada mislite: „Hvala, kapetane. Naravno, bilo bi dobro razumjeti što uopće pišeš. U suprotnom, s istim uspjehom možemo unajmiti grupu majmuna da udaraju po nasumičnim tipkama i time se smiriti.“ I potpuno ste u pravu. Stoga prihvaćam kao činjenicu: svjesni ste da imati opće razumijevanje onoga što radite, jest neophodno. To možemo nazvati nultim nivoom razumijevanja, i njega nećemo detaljno razrađivati. Detaljno ćemo obraditi što točno treba razumjeti i kako to utječe na odluke koje donosite svaki dan. Da sam znao te stvari ranije, to bi me oslobodilo mnoštva izgubljenog vremena i sumnjivog koda.

Iako dolje nećete vidjeti ni jednu liniju koda, ipak smatram da sve što je ovdje rečeno ima velik značaj za pisanje kvalitetnog, izrazitog koda.

Prvi nivo razumijevanja: Zašto ne radi?

Na ovaj nivo programeri obično dolaze u najranijim fazama svoje karijere, ponekad čak i bez ičije pomoći — barem prema mojim zapažanjima. Zamislite da ste dobili bug report: neka funkcija u aplikaciji ne radi, treba je popraviti. Kako ćete postupiti?

Standardna shema izgleda ovako:

  1. Pronaći dio koda koji izaziva problem (kako to učiniti — posebna je tema koju razrađujem u svojoj knjizi o zastarjelom kodu)
  2. Unijeti promjene u taj dio koda
  3. Provjeriti je li bug ispravljen i da regresivne pogreške nisu nastale

Sada ćemo se usredotočiti na drugi dio — promjenu u kodu. Postoje dva pristupa ovom procesu. Prvi: razumjeti što se točno događa u trenutnom kodu, otkriti grešku i ispraviti je. Drugi: kretati se nasumice — dodati, recimo, +1 u uvjetni operator ili petlju, vidjeti hoće li to funkcionirati u potrebnom scenariju, a zatim isprobavati još nešto i tako unedogled.

Ispravan pristup je prvi. Kao što u svojoj knjizi Code Complete objašnjava Steve McConnell (inače, jako je preporučujem), svaki put kada nešto mijenjamo u kodu, trebali bismo biti sposobni s povjerenjem predvidjeti kako će to utjecati na aplikaciju. Citiram iz sjećanja, ali ako popravak greške ne funkcionira kako ste očekivali, to bi vas trebalo ozbiljno zabrinuti, trebali biste preispitati čitav svoj plan.

Sve u svemu, kako bi se izvršilo kvalitetno ispravljanje greške koje neće pogoršati kvalitetu koda, potrebno je razumjeti i cijelu strukturu koda i izvor konkretne problematike.

Druga razina razumijevanja: Zašto to radi?

Ova razina se shvaća mnogo manje intuitivno od prethodne. Kao mladi programer, usvojio sam je zahvaljujući svom šefu, a kasnije sam je više puta objašnjavao početnicima.

Ovaj put zamislite da ste primili dva izvještaja o grešci: prvi se odnosi na scenarij A, a drugi na scenarij B. U oba scenarija nešto nije u redu. Prema tome, prvo se bavite prvim problemom. Slijedeći principe koje smo odredili za prvu razinu razumijevanja, pažljivo proučavate kod povezan s problemom, otkrivate zašto aplikacija reagira na određeni način u scenariju A i unosite razumne ispravke koje daju točno onaj rezultat kojeg ste očekivali. Sve ide odlično.

Nakon toga prelazite na scenarij B. Ponovno provodite scenarij u pokušaju da izazovete grešku, ali — iznenađenje! — sada sve funkcionira kako treba. Da biste potvrdili svoju pretpostavku, poništavate promjene napravljene tijekom rada na grešci A, a greška B se ponovno pojavljuje. Vaše ispravljanje greške riješilo je oba problema. Imate sreće!

Niste se nadali da će to tako ispasti. Smislili ste način da ispravite grešku u scenariju A i nemate pojma zašto je to uspelo u scenariju B. U ovoj fazi postoji velika iskušenja da se zaključi da su oba zadatka uspešno završena. To ima smisla: konačno, svrha je bila ispraviti greške, zar ne? Ali rad još nije gotov: morate se još pozabaviti pitanjem zašto su vaše radnje ispravile grešku u scenariju B. Zašto? Zato što možda koristi pogrešne principe, i tada ćete morati da potražite drugo rešenje. Evo nekoliko primera takvih slučajeva:

  • pošto rešenje nije odabrano ciljano za grešku B uzimajući u obzir sve faktore, možda ste nesvesno pokvarili funkciju C.
  • Nije isključeno da se negde krije još jedna greška, povezana sa istom funkcijom, i vaša ispravka greške ruši pravilno funkcionisanje sistema u scenariju B na njoj. Trenutno sve izgleda dobro, ali jednog dana će ta treća greška biti primećena i ispravljena. Tada će se u scenariju B opet javiti greška, i dobro je ako samo tamo.

Sve to unosi haos u kod i jednog dana će vam se obiti o glavu — verovatno u najneprikladnijem trenutku. Moraćete da saberete misli i naterate se da odvojite vreme da shvatite zašto sve na prvi pogled funkcioniše, ali se isplati.

Treći nivo razumevanja: Zašto to radi?

Moje nedavno otkrovenje se odnosi upravo na ovaj nivo, i verovatno bi mi on davao najviše prednosti da sam do ove misli došao ranije.

Da bude jasnije, razmotrimo primer: vaš modul treba da bude kompatibilan sa funkcijom X. Niste posebno bliski sa funkcijom X, ali vam je rečeno da za kompatibilnost sa njom treba koristiti okvir F. Drugi moduli koji se integrišu sa X funkcionišu upravo s njim.

Vaš kod od prvog dana svog postojanja nije imao nikakve veze s frameworkom F, pa će njegovo implementiranje biti pravo iskušenje. To će donijeti ozbiljne posljedice za neke aspekte modula. Ipak, potpuno se posvećujete razvoju: tjednima pišete kod, testirate, izdavate pilot verzije, dobivate povratne informacije, ispravljate regresijske greške, otkrivate nepredviđene komplikacije, ne uspijevate se uklopiti u prvotno dogovorene rokove, pišete još koda, testirate, dobijate povratne informacije, ispravljate regresijske greške — sve to s ciljem da implementirate framework F.

I u jednom trenutku odjednom shvatite — ili možda čujete od nekoga — da vam framework F možda neće omogućiti kompatibilnost s funkcijom X. Možda su svi ti trud i vrijeme bili usmjereni pogrešno.

Nešto slično dogodilo se jednog dana tijekom rada na projektu za koji sam bio zadužen. Zašto se to dogodilo? Zato što nisam dobro razumio što je suština funkcije X i kako je povezana s frameworkom F. Što sam trebao učiniti? Zamoliti osobu koja postavlja zadatak za razvoj da mi jasno objasni kako planirani postupak vodi do željenog ishoda, umjesto da jednostavno ponavljam ono što je rađeno za druge module ili da vjerujem na riječ da je to potrebno za rad funkcije X.

Iskustvo ovog projekta naučilo me je da odbijem započeti proces razvoja dok nemamo jasno razumijevanje zašto nas traže da izvršimo određene radnje. Odbiti izravno. Kada dobijete zadatak, prvi instinkt je hitno se njime uhvatiti u koštac, kako ne biste gubili vrijeme. No, politika "smrzavanja projekta dok ne uđemo u sve detalje" može značajno smanjiti bespotrebno izgubljeno vrijeme.

Čak i kada vas pokušavaju natjerati da započnete rad, iako ne razumijete razloge — odupirite se. Prvo istražite s kojim ciljem vam postavljaju takav zadatak, i odlučite je li to pravi put do cilja. Sve sam ovo morao naučiti na gorkom iskustvu — nadam se da će moj primjer olakšati život onima koji ovo čitaju.

Četvrta razina razumijevanja: ???

U programiranju uvijek imaš čemu učiti, i vjerujem da sam se samo dotaknuo najosnovnijih slojeva razumijevanja. Koje ste još razine razumijevanja otkrili tijekom godina rada s kodom? Koje ste odluke donijeli koje su pozitivno utjecale na kvalitetu koda i aplikacija? Koje su odluke bile pogrešne i pružile vam dragocjenu lekciju? Podijelite svoje iskustvo u komentarima.

Izvor: habr.com

Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere 🔥 Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere | ProHoster