„Orice prost poate scrie cod pe care un computer îl poate înțelege. Programatorii buni scriu cod pe care oamenii îl pot înțelege. “- Martin Fowler

Scrierea unui cod curat, ușor de înțeles și de întreținut este o abilitate crucială pentru fiecare dezvoltator pe care să o stăpânească.

În această postare, vom analiza cele mai importante principii pentru îmbunătățirea calității codului și vă voi oferi exemple de cod pentru fiecare dintre ele.

Cele mai multe exemple sunt preluate din ale lui Robert J. Martin Cod curat. Este un clasic de programare și vă sugerez să citiți întregul text când aveți timp.

Cum să denumiți variabile (și alte lucruri)

„Există doar două lucruri dificile în informatică: invalidarea cache-ului și denumirea lucrurilor”. – Phil Karlton

Există un motiv pentru care nu folosim adrese de memorie și nu avem nume în schimb: numele sunt mult mai ușor de reamintit. Și, mai important, vă pot oferi mai multe informații despre variabilă, astfel încât altcineva să poată înțelege semnificația acesteia.

Poate dura ceva timp pentru a găsi un nume bun, dar vă va salva și dvs. și echipa dvs. și mai mult timp în viitor. Și sunt sigur că majoritatea cititorilor s-au confruntat cu situația în care vizitați codul dvs. doar câteva luni mai târziu și le este greu să înțelegeți ce ați făcut înainte.

Cum să creați nume semnificative

Nu utilizați comentarii pentru a explica de ce este utilizată o variabilă. Dacă un nume necesită un comentariu, atunci ar trebui să vă alocați timp pentru a redenumi variabila respectivă în loc să scrieți un comentariu.

“Un nume ar trebui să vă spună de ce există, ce face și cum este folosit. Dacă un nume necesită un comentariu, atunci numele nu își dezvăluie intenția.” – Cod curat

Rău:

var d; // elapsed time in days

Am văzut acest tip de cod de atâtea ori. Este o concepție greșită obișnuită că ar trebui să-ți ascunzi mizeria cu comentarii. Nu utilizați litere precum x, y, a sau b ca nume de variabile, cu excepția cazului în care există un motiv întemeiat (variabilele de buclă sunt o excepție de la aceasta).

Bun:

var elapsedTimeInDays;
var daysSinceCreation;
var daysSinceModification;

Aceste nume sunt mult mai bune. Acestea vă spun ce se măsoară și unitatea măsurării respective.

ad-banner

Evitați dezinformarea

Aveți grijă la cuvintele care înseamnă ceva anume. Nu vă referiți la un grup de conturi ca accountList cu excepția cazului în care tipul său este de fapt o Listă. Cuvântul are un sens specific și poate duce la concluzii false.

Chiar dacă tipul este o listă, conturi este un nume mai simplu și mai bun.

Rău:

var accountList = [];

Bun:

var accounts = []

Evitați cuvintele de zgomot

Cuvintele de zgomot sunt cuvintele care nu oferă informații suplimentare despre variabilă. Sunt redundante și ar trebui eliminate.

Unele cuvinte populare de zgomot sunt:

  • (Prefixul)
  • Informații
  • Date
  • Variabil
  • Obiect
  • Administrator

Dacă clasa dvs. este numită UserInfo, puteți elimina informațiile și o puteți face utilizator. Folosirea BookData în loc de Book ca nume de clasă este doar o nebunie, întrucât o clasă stochează date oricum.

Puteți citi, de asemenea, postarea de blog a lui Jeff Atwood despre numirea SomethingManager Aici.

Utilizați nume pronunțabile

Dacă nu poți pronunța un nume, nu îl poți discuta fără să pară o prostie.

Rău:

const yyyymmdstr = moment().format("YYYY/MM/DD");

Bun:

const currentDate = moment().format("YYYY/MM/DD");

Folosiți nume care pot fi căutate

Evitați să folosiți numere magice în cod. Optează pentru constante care pot fi căutate, numite. Nu utilizați nume dintr-o singură literă pentru constante, deoarece acestea pot apărea în multe locuri și, prin urmare, nu sunt ușor de căutat.

Rău:

if (student.classes.length < 7) {
   // Do something
}

Bun:

if (student.classes.length < MAX_CLASSES_PER_STUDENT) {
    // Do something
}

Acest lucru este mult mai bun pentru că MAX_CLASSES_PER_STUDENT poate fi folosit în multe locuri în cod. Dacă trebuie să-l schimbăm la 6 în viitor, putem schimba constantă.

Exemplul rău creează semne de întrebare în mintea cititorului, cum ar fi care este importanța 7?

De asemenea, ar trebui să utilizați convențiile de denumire și declarație constante ale limbii dvs., cum ar fi privat static final în Java sau const în JavaScript.

Fii consistent

Urmează un cuvânt pentru fiecare concept regulă. Nu folosi aduc, recupera, și obține pentru aceeași operație în clase diferite. Alegeți una dintre ele și utilizați-o în tot proiectul, astfel încât persoanele care întrețin baza de cod sau clienții API-ului dvs. să poată găsi cu ușurință metodele pe care le caută.

Cum se scrie funcții

Păstrați-le mici

Funcțiile ar trebui să fie mici, foarte mici. Ar trebui să aibă rareori 20 de rânduri. Cu cât o funcție devine mai lungă, este mai probabil să faci mai multe lucruri și să ai efecte secundare.

Asigurați-vă că fac doar un lucru

Funcțiile ar trebui să facă un lucru. Ar trebui să o facă bine. Ar trebui să o facă numai. – Cod curat

Funcțiile dvs. ar trebui să facă un singur lucru. Dacă urmați această regulă, este garantat că vor fi mici. Singurul lucru pe care îl face funcția ar trebui să fie menționat în numele său.

Uneori este greu să te uiți la funcție și să vezi dacă face sau nu mai multe lucruri. O modalitate bună de a verifica este să încercați să extrageți o altă funcție cu un nume diferit. Dacă îl puteți găsi, asta înseamnă că ar trebui să fie o funcție diferită.

Acesta este probabil cel mai important concept din acest articol și va dura ceva timp să vă obișnuiți. Dar, odată ce îl veți obține, codul dvs. va arăta mult mai matur și va fi mai ușor refactorizabil, ușor de înțeles și testat cu siguranță.

Incapsulați condiționali în funcții

Refactorizarea condiției și introducerea acesteia într-o funcție numită este o modalitate bună de a face condiționările dvs. mai lizibile.

Iată o bucată de cod dintr-un proiect școlar al meu. Acest cod este responsabil pentru introducerea unui cip pe tabloul jocului Connect4.

isValidInsertion metoda se ocupă de verificarea validității numărului de coloană și ne permite să ne concentrăm pe logica pentru inserarea cipului.

public void insertChipAt(int column) throws Exception {
        if (isValidInsertion(column)) {
            insertChip(column);
            boardConfiguration += column;
            currentPlayer = currentPlayer == Chip.RED ? Chip.YELLOW : Chip.RED;
        } else {
            if (!columnExistsAt(column))
                throw new IllegalArgumentException();
            else if (isColumnFull(column - 1) || getWinner() != Chip.NONE)
                throw new RuntimeException();
        }
    }

Iată codul pentru isValidInsertion, dacă sunteți interesat.

    private boolean isValidInsertion(int column) {
        boolean columnIsAvailable = column <= NUM_COLUMNS && column >= 1 && numberOfItemsInColumn[column - 1] < NUM_ROWS;
        boolean gameIsOver = getWinner() != Chip.NONE;
        return columnIsAvailable && !gameIsOver;
    }

Fără metodă, dacă condiția ar arăta astfel:

if (column <= NUM_COLUMNS
 && column >= 1
 && numberOfItemsInColumn[column - 1] < NUM_ROWS 
 && getWinner() != Chip.NONE)

Brut, nu? Sunt de acord.

Mai puține argumente

Funcțiile ar trebui să aibă două sau mai puține argumente, cu cât sunt mai puține, cu atât mai bine. Evitați trei sau mai multe argumente acolo unde este posibil.

Argumentele îngreunează citirea și înțelegerea funcției. Acestea sunt și mai dificile din punct de vedere al testării, deoarece creează nevoia de a scrie cazuri de testare pentru fiecare combinație de argumente.

Nu utilizați Argumente de semnalizare

Un argument de semnalizare este un argument boolean care este transmis unei funcții. Două acțiuni diferite sunt întreprinse în funcție de valoarea acestui argument.

De exemplu, să spunem că există o funcție care este responsabilă pentru rezervarea biletelor la un concert și că există 2 tipuri de utilizatori: Premium și Regular. Puteți avea un cod ca acesta:

    public Booking book (Customer aCustomer, boolean isPremium) {
      if(isPremium) 
       // logic for premium book
      else
       // logic for regular booking
    }

Argumentele semnale contrazic în mod firesc principiul responsabilității unice. Când le vedeți, ar trebui să luați în considerare împărțirea funcției în două.

Nu aveți efecte secundare

Efectele secundare sunt consecințe neintenționate ale codului dvs. Este posibil să schimbe parametrii trecuți, în caz de trecere prin referință sau poate schimba o variabilă globală.

Punctul cheie este că au promis să facă un alt lucru și trebuie să citiți codul cu atenție pentru a observa efectul secundar. Acestea pot duce la unele bug-uri urâte.

Iată un exemplu din carte:

public class UserValidator {
      private Cryptographer cryptographer;
      public boolean checkPassword(String userName, String password) { 
        User user = UserGateway.findByName(userName);
        if (user != User.NULL) {
          String codedPhrase = user.getPhraseEncodedByPassword();
          String phrase = cryptographer.decrypt(codedPhrase, password);
          if ("Valid Password".equals(phrase)) {
            Session.initialize();
            return true; 
          }
        }
        return false; 
      }
}

Puteți vedea efectul secundar al acestei funcții?

Se verifică parola, dar atunci când parola este validă, inițializează și sesiunea, care este un efect secundar.

Puteți schimba numele funcției în ceva de genul checkPasswordAndInitializeSession pentru a face acest efect explicit. Dar când faceți acest lucru, ar trebui să observați că funcția dvs. face de fapt două lucruri și nu ar trebui să inițializați sesiunea aici.

Nu te repeta

Repetarea codului poate fi rădăcina tuturor răurilor din software. Codul duplicat înseamnă că trebuie să schimbați lucrurile în mai multe locuri atunci când există o modificare a logicii și este foarte predispus la erori.

Utilizați caracteristicile de refactorizare a IDE-ului dvs. și extrageți o metodă ori de câte ori întâlniți un segment de cod repetat.

Cod curat explicat O introducere practica pentru codificarea curata
Metoda de extragere IntelliJ

Primă

Nu lăsați codul în comentarii

Te rog nu. Acesta este serios, deoarece alții care văd codul se vor teme să-l șteargă, deoarece nu știu dacă există acolo dintr-un motiv. Codul comentat va rămâne acolo mult timp. Apoi, atunci când numele variabilelor sau numele metodelor se schimbă, devine irelevant, dar totuși nimeni nu o șterge.

Doar ștergeți-l. Chiar dacă a fost important, există control de versiune pentru asta. O poți găsi oricând.

Cunoașteți convențiile limbii dvs.

Ar trebui să cunoașteți convențiile limbii dvs. în ceea ce privește spațiul, comentariile și denumirea lucrurilor. Există ghiduri de stil disponibile pentru multe limbi.

De exemplu, ar trebui să utilizați camelCase în Java, dar snake_case în Python. Puneți paranteze de deschidere pe o nouă linie în C #, dar le puneți pe aceeași linie în Java și JavaScript.

Aceste lucruri se schimbă de la limbă la limbă și nu există un standard universal.

Iată câteva linkuri utile pentru dvs.:

Concluzie

Codificarea curată nu este o abilitate care poate fi dobândită peste noapte. Este un obicei care trebuie dezvoltat ținând cont de aceste principii și aplicându-le ori de câte ori scrieți cod.

Vă mulțumesc că v-ați luat timp să citiți și sper că a fost de ajutor.

Dacă sunteți interesat să citiți mai multe articole de acest gen, vă puteți abona la blog.