Există două lucruri - Programare și Programare bună. Programarea este ceea ce am făcut cu toții. Acum este momentul să faci o programare bună. Știm cu toții că chiar și codul rău funcționează. Dar este nevoie de timp și resurse pentru a face un program bun. Mai mult, alți dezvoltatori vă batjocoresc când încearcă să afle ce se întâmplă în codul dvs. Dar niciodată nu este prea târziu să ai grijă de programele tale.

codul

Această carte mi-a oferit multe cunoștințe despre care sunt cele mai bune practici și despre cum să scriu codul. Acum îmi este rușine de abilitățile mele de codare. Deși mă străduiesc întotdeauna să-mi îmbunătățesc codul, această carte a învățat mult mai multe.

Acum, citiți acest blog din două motive. În primul rând, ești programator. În al doilea rând, vrei să fii un programator mai bun. Bun. Avem nevoie de programatori mai buni.

Caracteristicile unui cod Clean:

  1. Ar trebui să fie elegant - Codul curat ar trebui să fie plăcut de citit. Citind-o ar trebui să te facă să zâmbești așa cum ar face o cutie de muzică bine artizanată sau o mașină bine proiectată.
  2. Codul curat este focalizat - Fiecare funcție, fiecare clasă, fiecare modul expune o atitudine unică, care rămâne în întregime nedistricționată și nepoluată de detaliile din jur.
  3. Codul curat este îngrijit. Cineva și-a luat timp să-l păstreze simplu și ordonat. Au acordat o atenție adecvată detaliilor. Le-a pasat.

4. Rulează toate testele

5. Nu conține duplicări

6. Minimizați numărul de entități, cum ar fi clase, metode, funcții și altele asemenea.

Folosiți nume care dezvăluie intenția. Alegerea unor nume bune necesită timp, dar economisește mai mult decât este necesar. Numele unei variabile, funcții sau clase, ar trebui să răspundă la toate întrebările mari. Ar trebui să vă spună de ce există, ce face și cum este utilizat. Dacă un nume necesită un comentariu, atunci numele nu își dezvăluie intenția.

Ex- int d; // timpul scurs în zile.

Ar trebui să alegem un nume care să specifice ce se măsoară și unitatea măsurii respective.

Un nume mai bun ar fi: - int elapsedTime. (Chiar dacă cartea spune elapsedTimeInDays, aș prefera totuși cea dintâi. Să presupunem că timpul scurs se schimbă în milisecunde. Apoi ar trebui să schimbăm mult în int și elapsedTimeInMillis în loc de elapsedTimeInDays. Și pentru cât timp vom continua să schimbăm ambele tipul de date și numele.)

Numele clasei - Clasele și obiectele ar trebui să aibă nume de nume substantivale sau de sintagme nominale precum Client, WikiPage, Cont și AddressParser. Evitați cuvintele precum Manager, procesor, date sau informații în numele unei clase. Un nume de clasă nu trebuie să fie un verb.

Numele metodelor -Metodele ar trebui să aibă nume de verbe sau de fraze verbale precum postPayment, deletePage sau save. Accesorii, mutatorii și predicatele trebuie denumite după valoarea lor și prefixate cu get, set.

Când constructorii sunt supraîncărcați, utilizați metode statice din fabrică cu nume care descriu argumentele. De exemplu,

Punct fulcrum complex = Complex.FromRealNumber (23.0); este, în general, mai bun decât Complex fulcrumPoint = new Complex (23.0);

Alegeți un cuvânt pe concept -Alegeți un cuvânt pentru un concept abstract și rămâneți cu el. De exemplu, este confuz să obțineți, să preluați și să obțineți ca metode echivalente din diferite clase. Cum vă amintiți ce nume de metodă se asociază cu ce clasă? La fel, este confuz să ai un controler, un manager și un driver în aceeași bază de cod. Care este diferența esențială între un DeviceManager și un Protocol-Controller?

Prima regulă a funcțiilor este că acestea ar trebui să fie mici. A doua regulă a funcțiilor este că acestea ar trebui să fie mai mici decât aceasta. Acest lucru implică faptul că blocurile din instrucțiunile if, else, în timp ce instrucțiunile și așa mai departe, ar trebui să aibă o linie lungă. Probabil că acea linie ar trebui să fie un apel funcțional. Acest lucru nu numai că menține funcția de închidere mică, dar adaugă și valoare documentară, deoarece funcția numită în cadrul blocului poate avea un nume frumos descriptiv.

Argumente funcționale

O funcție nu trebuie să aibă mai mult de 3 argumente. Păstrați-l cât mai jos posibil. Când o funcție pare să aibă nevoie de mai mult de două sau trei argumente, este probabil ca unele dintre aceste argumente să fie încorporate într-o clasă proprie. Reducerea numărului de argumente prin crearea de obiecte din ele poate părea a fi înșelător, dar nu este.

Acum, când spun să reduceți dimensiunea unei funcții, cu siguranță v-ați gândi cum să reduceți try-catch, deoarece vă face deja codul mult mai mare. Răspunsul meu este să creez o funcție care conține doar declarațiile try-catch-finalmente. Și separați corpurile de blocare try/catch/finalmente într-o funcție separată. De exemplu-

Acest lucru face ca logica să fie clară. Numele funcțiilor descriu cu ușurință ceea ce încercăm să realizăm. Tratarea erorilor poate fi ignorată. Aceasta oferă o separare plăcută care face codul mai ușor de înțeles și de modificat.

Tratarea erorilor este un lucru - Funcția ar trebui să facă un lucru. Tratarea erorilor este un alt lucru. Dacă o funcție are un cuvânt cheie try, atunci acesta ar trebui să fie primul cuvânt cheie și nu ar trebui să existe nimic după blocurile de captură/în cele din urmă.

Comentarii

Dacă scrieți comentarii pentru a vă dovedi punctul de vedere, faceți o gafă. În mod ideal, comentariile nu sunt deloc obligatorii. Dacă codul dvs. are nevoie de comentarii, faceți ceva greșit. Codul nostru ar trebui să explice totul. Limbajele de programare moderne sunt englezești, prin care ne putem explica cu ușurință ideea. Denumirea corectă poate împiedica comentariile.

Comentariile legale nu sunt luate în considerare aici. Sunt necesare pentru a scrie. Comentarii legale înseamnă drepturi de autor și declarații de licențe.

Obiecte și structuri de date

Acesta este un subiect complex, așa că acordați o atenție deosebită acestuia. Mai întâi trebuie să clarificăm diferența dintre obiect și structurile de date.

Obiectele își ascund datele în spatele abstractizărilor și expun funcții care operează pe aceste date. Structura datelor își expune datele și nu au funcții semnificative.

Aceste 2 lucruri sunt complet diferite. Una este doar despre stocarea datelor, iar cealaltă este modul de manipulare a acestor date. Luați în considerare, de exemplu, exemplul de formă procedurală de mai jos. Clasa Geometrie funcționează pe cele trei clase de forme. Clasele de formă sunt structuri de date simple, fără niciun comportament. Tot comportamentul este în clasa Geometrie.

Luați în considerare ce s-ar întâmpla dacă o funcție perimeter () ar fi adăugată la Geometrie. Clasele de formă nu ar fi afectate! Orice alte clase care depindeau de forme nu ar fi, de asemenea, neafectate! Pe de altă parte, dacă adaug o nouă formă, trebuie să schimb toate funcțiile din Geometrie pentru a face față acesteia. Citește din nou asta. Observați că cele două condiții sunt diametral opuse.

Acum luați în considerare o altă abordare pentru scenariul de mai sus.

Acum putem adăuga cu ușurință noi forme, adică structuri de date comparativ cu cazul anterior. Și dacă trebuie să adăugăm funcția perimeter () într-o singură formă, suntem forțați să implementăm acea funcție în toate formele, deoarece clasa Shape este o interfață care conține funcția area () și perimeter (). Asta înseamnă:

Structurile D ata facilitează adăugarea de funcții noi fără a modifica structurile de date existente. Codul OO (folosind obiecte), facilitează adăugarea de noi clase fără a schimba funcțiile existente.

Complementul este, de asemenea, adevărat:

Codul procedural (folosind structuri de date) face dificilă adăugarea de noi structuri de date, deoarece toate funcțiile trebuie schimbate. Codul OO face dificilă adăugarea de funcții noi, deoarece toate clasele trebuie să se schimbe.

Deci, lucrurile care sunt dificile pentru OO sunt ușoare pentru proceduri, iar lucrurile care sunt dificile pentru proceduri sunt ușoare pentru OO!

În orice sistem complex, vor exista momente în care dorim să adăugăm noi tipuri de date, mai degrabă decât funcții noi. Pentru aceste cazuri, obiectele și OO sunt cele mai potrivite. Pe de altă parte, vor exista și momente în care vom dori să adăugăm funcții noi spre deosebire de tipurile de date. În acest caz, codul procedural și structurile de date vor fi mai adecvate.

Programatorii maturi știu că ideea că totul este un obiect este un mit. Uneori chiar vrei structuri de date simple cu proceduri care operează pe ele. Deci, trebuie să vă gândiți cu atenție la ce să implementați, gândindu-vă și la perspectiva viitoare, ceea ce va fi ușor de actualizat. În ceea ce privește acest exemplu, deoarece orice formă nouă poate fi adăugată în viitor, voi alege abordarea OO pentru aceasta.

Înțeleg că este greu să scrii programe bune, având în vedere cronologia în care trebuie să-ți faci sarcinile. Dar până când vei întârzia? Începeți încet și fiți consecvenți. Codul dvs. poate face minuni pentru dvs. și mai ales pentru alții. Am început și am găsit atâtea greșeli pe care le făceam tot timpul. Deși a durat câteva ore în plus din limita mea zilnică de timp, mă va plăti în viitor.

Acesta nu este un sfârșit al acestui blog. Voi continua să scriu despre noi modalități de a vă curăța codul. Mai mult, voi scrie și despre câteva modele de proiectare de bază, care trebuie să fie cunoscute pentru fiecare dezvoltator din orice tehnologie.

Între timp, dacă îți place blogul meu și ai învățat din el, te rog să aplaude. Îmi dă motivație să creez un nou blog mai repede:) Comentariile/sugestiile sunt binevenite ca întotdeauna. Continuă să înveți și să împărtășești.