Șase sfaturi pentru scrierea codului software mai inteligibil - produse software

Jeff Vogel, președinte, Software-ul Spiderweb

Am trecut printr-o cale dificilă înainte de a învăța să scriu un cod de program clar care să permită întreținerea ulterioară. În ultimii doisprezece ani, îmi câștig existența prin crearea de jocuri pe calculator și vânzarea lor online printr-un model de marketing numit shareware. Aceasta înseamnă că mă așez în fața unui ecran gol și încep să scriu cod - și numai după ce scriu câteva zeci de mii de linii de cod, obțin ceva ce poate fi vândut.







Cu alte cuvinte, dacă creez o mizerie, atunci o fac exclusiv în cuibul meu. Când ora trei dimineața mă uit pentru o greșeală confuz ca un program de vis urat „macaroane“, și-mi spun: „Oh, Doamne, ce retardat care cauzează endogamie a scris acest coșmar“, răspunsul la această întrebare nu poate fi decât: „Eu sunt eu“ .

Dezvoltarea tehnicilor de programare bune, ordonate a devenit o adevărată binecuvântare pentru mine. Unele dintre aceste tehnici sunt descrise în acest articol. Mulți programatori calificați, experimentați și interni disciplinați cunosc multe din aceste tehnici de la bază. Tot ceea ce oamenii pot obține de la acest articol - este abilitatea de a se bucura de stilul meu literar încântător și amintiți-vă cât de teribil a fost viața lor înainte de a dobândit acces la conceptul de „cod curat“.

Ca o ilustrare în acest articol, voi lua în considerare un program care este un joc de calculator ipotetic numit Kill Bad Aliens (Kill a Aliens Bad). Participantul acestui joc trebuie să controleze nava spațială. Această navă se mișcă orizontal în partea de jos a ecranului și împușcă proiectile verticale. Controlul acestei nave spațiale va fi, de exemplu, folosind tastatura.

Fig. 1. Jocul nostru ipotetic

Șase sfaturi pentru scrierea codului software mai inteligibil - produse software

Jocul este împărțit în intervale de timp - așa-numitele "valuri". De-a lungul fiecărui val în partea de sus a ecranului, unul după altul, există străini. Ei zboară în jurul ecranului și aruncă bombe. Străinii apar pe ecran pentru o perioadă fixă ​​de timp. Valul se termină după ce jucătorul a distrus un anumit număr de străini.

Pentru fiecare străin ucis, jucătorul este creditat cu un anumit număr de puncte. După terminarea fiecărui val, jucătorul primește un anumit număr de puncte bonus - în funcție de cât de repede a reușit să finalizeze acest val.

Când o navă spațială este lovită de o bombă, explodează și apoi apare o altă navă pe ecran. Dacă nava spațială explodează de trei ori, jocul se termină. Un jucător cu un scor mare este adăugat la evaluarea finală. Cu un număr mic de puncte câștigate, acest lucru nu se întâmplă.

Deci, vă așezați la birou și începeți să scrieți codul pentru Kill Bad Aliens în C ++. Mai întâi determinați obiectele pe care va reprezenta nava spațială, cochilii jucătorului, extratereștrii și bombele lor. Apoi scrieți codul pentru reprezentarea grafică pe ecran a tuturor obiectelor specificate. După aceea, scrieți codul pentru a muta obiecte în jurul ecranului în funcție de timp. Și, în sfârșit, scrieți logica jocurilor, inteligența artificială a străinilor, codul de program pentru a intra de la comenzile tastaturii jucătorului etc.

Se pune întrebarea inevitabilă - cum să facă toate cele de mai sus, astfel încât codul de final al jocului a fost evident, nu a creat dificultăți în susținerea ulterioară și nu reprezintă o mizerie ilizibile?

Și dacă am ajuns la asta, o altă recomandare - nu faceți niciodată acest lucru:

Deci, tot ce avem nevoie este o descriere la început și mai multe "indicii" din interior, explicând calea aleasă. Toate acestea se fac foarte repede și pe termen lung economisesc mult timp.

Mai jos este un exemplu din jocul nostru ipotetic Kill Bad Aliens. Luați în considerare un obiect care reprezintă proiectilele pe care le împușcă jucătorul. Va trebui adesea să apelați o funcție care va muta acest obiect în sus și va determina unde a mers. Aș scrie această procedură după cum urmează:

Șase sfaturi pentru scrierea codului software mai inteligibil - produse software

Să presupunem că, în jocul nostru ipotetic, dorim ca fiecare jucător să obțină zece puncte de fiecare dată când lovește un străin. Această problemă poate fi rezolvată în două moduri. Mod rău:

O modalitate bună: într-un fișier global, scrieți următorul rând:

Acum, dacă doriți să atribuiți jucătorului câteva puncte de premiere, este suficient să scrieți următoarele:

Majoritatea programatorilor știu cumva că este necesar să facă acest lucru. Cu toate acestea, pentru implementarea consecventă a acestui concept este necesară disciplina internă. Aproape de fiecare dată când introduceți o constantă numerică, trebuie să vă gândiți cu atenție - nu o întrebați într-un "punct central". Să presupunem, de exemplu, că doriți să aveți o zonă de joc cu dimensiunile de 800 x 600 pixeli. Vă recomandăm să setați dimensiunea acestei zone după cum urmează:

Atunci când se lucrează pe joc Kill Bad Străinii am nevoie pentru a decide cât de mulți străini trebuie să-l omoare pentru a finaliza val ca străini pot fi pe ecran, la o dată și modul în care străinii rapid apar pe ecran. De exemplu, dacă vreau ca fiecare val să aibă același număr de străini care apar la aceeași frecvență, cel mai probabil voi scrie ceva de genul:

Codul este destul de ușor de înțeles. Apoi, când am ajuns la concluzia că valurile sunt prea scurte sau că intervalele dintre aparițiile străinilor sunt prea mici, pot schimba aceste valori și resetați instantaneu întregul joc.

Unul dintre avantajele semnificative ale unui astfel de mecanism pentru stabilirea parametrilor jocului este că această abilitate de a face schimbări rapide este o adevărată plăcere și vă permite să vă simțiți atotputernic. De exemplu, ați modificat textul de mai sus după cum urmează:

Acum, o recompilare este suficientă - și jocul dvs. va fi mult mai distractiv și chiar mai nebunesc.

Fig. 2. Kill Bad Aliens joc înainte de a schimba constantele

Șase sfaturi pentru scrierea codului software mai inteligibil - produse software






Fig. 3. Jucați Kill Bad Aliens după ce ați crescut toate constantele (jucați, poate, este dificil, dar este interesant de văzut)

Șase sfaturi pentru scrierea codului software mai inteligibil - produse software

Scopul final este simplu: scrie codul de program astfel încât un outsider care nu are nicio idee despre ce face acest cod poate înțelege cât de repede posibil.

În acest caz, este necesar să se respecte mediul de aur. Dați-le obiectelor numele care sunt suficient de lungi pentru a înțelege semnificația lor, dar nu atât de lungă și greoaie pentru a face dificilă citirea codului.

De exemplu, în condiții reale, probabil că nu voi da constantele astfel de nume lungi, pe care le-am aplicat în secțiunea anterioară. Am făcut acest lucru numai pentru ca cititorul să înțeleagă pe deplin semnificația lor fără niciun context. În contextul programului în sine, în loc de text:

Probabil că aș fi scris următoarele:

Orice neînțelegere datorată numelui mai scurt va fi eliminată foarte rapid, iar "lizibilitatea" codului se va îmbunătăți.

Acum, luați în considerare un fragment de cod care va fi folosit foarte des pentru a muta toți străinii în jurul ecranului. Aproape că aș scrie așa:

Rețineți că matricea pentru toți străinii se numește extratereștri. Și acest lucru este foarte bun. Acest nume convează exact ceea ce am vrut să spun, dar este suficient de scurt încât să pot intra de la tastatură de o mie de ori și să nu mă descurc. Probabil că veți folosi această matrice FOARTE FREQUENT. Dacă chemați acest matrice all_aliens_currently_on_screen. Codul dvs. de program va fi de zece mile mai lung și la fel de incomprehensibil.

Fără îndoială, numele variabilelor poate fi tratat mult mai serios. De exemplu, există un așa-zis. Notația maghiară. Acest concept are mai multe opțiuni, însă ideea sa principală este că fiecare nume de variabilă trebuie să înceapă cu un prefix care indică tipul acestei variabile. (De exemplu, toate variabilele de tip variabile lungi nesemnate trebuie să înceapă cu prefixul ul, etc.). În opinia mea, aceasta este deja o bustă, dar trebuie să știți despre existența și această opțiune. Puteți petrece mult timp pentru a face lucrurile mai clare, dar rezolvarea acestei sarcini necesită și un efort.

Dacă programul dvs. este suficient de mare, acesta va avea cu siguranță o mulțime de funcții și proceduri. Cu toate acestea, ar putea părea că este greu, fiecare funcție / procedură trebuie verificată pentru erori.

Atunci când creați orice procedură / funcție, trebuie să întrebați întotdeauna întrebarea: "Să presupunem că un anumit personaj nebun va trece pe cele mai neadecvate valori. Deoarece această bucată pufos de cod va fi în măsură să vă proteja și pentru a menține întregul program de a fi deteriorate? „Apoi scrie cod, astfel încât acesta verifică procedura / funcția în prezența unor astfel de date ostile și să le protejeze.

Luați în considerare următorul exemplu. Scopul principal al jocului nostru spațiale minunat este de a ucide extratereștrii și de a câștiga puncte, deci avem nevoie de o procedură pentru a schimba punctele marcate de jucător. Mai mult, atunci când adăugăm puncte jucătorului, dorim să apelăm la o procedură care să coloreze scorul final cu paiete frumoase. Prima opțiune este după cum urmează:

În timp ce totul merge bine. Acum întrebați-vă întrebarea: "Ce poate fi greșit în acest cod?"

În primul rând, un punct evident. Ce se întâmplă dacă variabila num_points are o valoare negativă? Putem permite contului jucătorului să coboare? Poate. Cu toate acestea, în descrierea jocului, nu am menționat niciodată aici mai devreme despre posibilitatea ca un jucător să piardă puncte. În plus, jocul ar trebui să fie distractiv, iar pierderea de puncte este contrară acestui fapt. Astfel, ajungem la concluzia că un număr negativ de puncte este o greșeală care trebuie capturată.

Acest exemplu a fost destul de simplu. Există, de asemenea, o problemă mai puțin evidentă (pe care o întâmpin constant în jocurile mele). Ce se întâmplă dacă variabila num_points este zero?

Aceasta este o situație foarte plauzibilă. Nu uitați că, la sfârșitul fiecărui val, oferim jucătorilor puncte bonus în funcție de viteza de trecere. Ce se întâmplă dacă jucătorul joacă prea încet și ne hotărâm să-i dăm 0 puncte? Este posibil ca lucrul la codul dvs. la 3 dimineața să decideți să apelați procedura change_score și să treceți valoarea 0 la ea.

În acest caz, problema este că vom cel mai probabil, nu doresc să decoreze scorul final de culoare festive, în cazul în care numărul de puncte nu este schimbat. Astfel, trebuie să fie identificată și această situație. Să încercăm acest cod:

Ei bine, aici. E mult mai bine.

Rețineți că aceasta a fost o funcție foarte simplă. Îi lipsesc complet indicatorii noi, pe care tinerii programatori le folosesc atât de mult. Dacă parcurgeți tablouri sau indicatori, trebuie să anticipați detectarea erorilor sau a datelor nepotrivite.

Avantajele acestei abordări nu se limitează la protejarea programului de eșecuri. Mecanismele bune de verificare a erorilor accelerează de asemenea depanarea. Să presupunem că știi că undeva există o serie de date scrie în afară de unele matrice, și să vizualizați codul în căutarea unui loc în care acest lucru se poate întâmpla. Dacă în orice procedură sunt disponibile toate mecanismele de verificare, nu trebuie să treceți pas cu pas în căutarea unei erori.

Această abordare economisește mult timp și merită o aplicare regulată. Timpul este resursa noastră cea mai valoroasă.

Această frază nu a fost inventată de mine. Cu toate acestea, este în Wikipedia și, prin urmare, aparent, nu este lipsită de sens.

Dacă scopul dvs. final nu este acela de a chinui oamenii, atunci când scrieți codul, trebuie să vă străduiți să obțineți o claritate maximă. Un cod simplu durează mai puțin timp pentru a scrie, pentru a înțelege mai târziu accesarea acestuia și depanarea.

Optimizarea este inamicul clarității. Cu toate acestea, trebuie remarcat faptul că, în unele cazuri, este necesară optimizarea. Acest lucru este valabil mai ales pentru jocuri. Cu toate acestea - și acest lucru este foarte important - aproape niciodată nu știu dinainte ce are nevoie de îmbunătățiri, atâta timp cât nu testați codul real de funcționare cu ajutorul unui instrument numit un profiler. (Profiler - este un program care monitorizează programul și estimează timpul necesar pentru a efectua anumite provocări Există un program minunat de acest tip găsi și de a folosi ...)

De fiecare dată când mă angajez să optimizez unele dintre jocurile mele, am întotdeauna uimire. Codul pe care eram îngrijorat de cele mai multe ori funcționează întotdeauna bine - dar am încetinit codul pe care nu l-am gândit niciodată. Din moment ce am avut nici o idee de cod ce va fi mai rapid, și ceea ce - este lent, timpul petrecut pe optimizarea pentru a obține date reale este irosit. În realitate, situația este chiar mai rău - în plus față de deșeuri inutile de timp această optimizare duce la un cod incurcate.

Respectarea acestei reguli nu este ușoară. Pe de altă parte, altfel nu ar fi regula. "Bine" programatori stângaci codul este enervant, chiar dacă acesta funcționează mai repede.

Dar bucura-te! După predicile mele lungi pe care ar trebui să petreacă mai mult timp și mai mult timp pe ea, a venit o rară, de neprețuit atunci când vă spun că un pic de lene este destul de acceptabil!

Scrieți un program clar și de lucru. După aceea, veți avea timp suficient pentru a vă răsturna prin optimizare. Cu toate acestea, nu faceți acest lucru până când nu sunteți sigur că faceți ceea ce trebuie.

Și, în sfârșit, din moment ce vorbim despre dureros, iată sfatul meu final:

Este posibil să fi auzit despre existența evenimentului sub numele ascuns pentru cod C Concursul Internațional - un concurs internațional pentru cele mai complicate codul software în C. Faptul este că limbile C și C ++, cu toate avantajele sale, se poate crea un cod de coșmar încurcat. Acest concurs demonstrează avantajele codului clar "din opusul" - prin recompensarea celor mai nebuni programatori. Idee minunată.

Cu rezultatele acestui concurs este în valoare de lectură, dacă numai pentru a înțelege ce pagube mari pot fi aplicate prin intermediul unor cunoștințe enciclopedice a limbajului de programare, completată de lipsa rușinii de bază. Dacă aveți suficiente cunoștințe, puteți stoarce zece linii de cod normal într-o singură linie. Prețul pentru acest lucru va fi scăzut - doar o imposibilitate completă de a repara rapid eroarea în acest cod.

Lecția principală este următoarea. În cazul în care codul generat necesită cunoștințe detaliate a regulilor complicate de prioritate sau te face sa te uiti la ultimul capitol al unei cărți, pentru a înțelege exact ceea ce faci - înseamnă că ați început să filozofeze.

Fiecare programator are propriul nivel acceptabil de complexitate a codului generat. Personal, îmi scriu programele așa cum conduce o bunică tipică. În opinia mea, dacă codul dvs. C necesită înțelegerea diferențelor subtile dintre expresiile i ++ și ++ i, atunci este prea complex.

Dacă vrei, poți să mă consideri plictisită. Ai dreptate. Cu toate acestea, îmi petrec mult mai puțin timp înțelegând codul decât puteam.

Cu toate acestea, nu trebuie să credem că tot ceea ce este declarat este evident pentru toată lumea. De fapt, nu este așa. Codul greșit scrise apare din nou și din nou - deși ați fi putut să o faceți fără ea.

Dacă vă ocupați de cantități uriașe de cod și nu doriți să muriți sub greutatea sa, sper cu sinceritate că sfatul meu vă va ajuta. Străduiți-vă pentru simplitate și claritate - acest lucru vă economisește mult timp și ușurează suferințele inutile.







Trimiteți-le prietenilor: