
Întâlnesc destul de des dezvoltatori care nu au auzit de principiile SOLID (noi . — Nota.) sau de programarea orientată pe obiect (OOP), sau au auzit, dar nu le folosesc în practică. În acest articol sunt descrise avantajele principiilor OOP, care ajută dezvoltatorul în munca sa zilnică. Unele dintre ele sunt bine cunoscute, altele — mai puțin, astfel că articolul va fi util atât pentru începători, cât și pentru programatori cu experiență.
Vă reamintim: pentru toți cititorii «»Habr» — o reducere de 10 000 de ruble la înscrierea la orice curs Skillbox cu codul promoțional «Habr».
Skillbox recomandă: Curs online educațional .
DRY (Don’t Repeat Yourself)
Un principiu destul de simplu, a cărui esență este clară din nume: «Nu te repeta». Pentru programator, aceasta înseamnă necesitatea de a evita codul duplicat, precum și posibilitatea de a folosi abstracția în muncă.
Dacă în cod există două părți repetate, ar trebui să le unifici într-o metodă. Dacă o valoare fixă este utilizată de mai multe ori, ar trebui să o transformi într-o constantă publică.
Acest lucru este necesar pentru a simplifica codul și a face întreținerea acestuia mai ușoară, ceea ce este principalul obiectiv al OOP. Nu trebuie să abuzi de unificare, deoarece același cod nu va trece testul atât cu OrderId, cât și cu SSN.
Încapsularea schimbărilor
Produsele software ale celor mai multe companii sunt în continuă dezvoltare. Asta înseamnă că trebuie făcute modificări în cod, acesta trebuie întreținut. Îți poți simplifica viața prin intermediul încapsulării. Aceasta va permite testarea și întreținerea mai eficientă a bazei de cod existente. .
Dacă scrii în Java, atunci .
Principiul deschiderii/închiderii
Acest principiu poate fi ușor reținut citind următoarea afirmație: «Entitățile software (clase, module, funcții etc.) trebuie să fie deschise pentru extensie, dar închise pentru modificare». În practică, aceasta înseamnă că ele pot permite schimbarea comportamentului lor fără a modifica codul sursă.
Principiul este important atunci când modificările în codul sursă necesită revizuirea acestuia, testarea modulară și alte proceduri. Codul care respectă principiul deschiderii/închiderii nu este modificat atunci când este extins, așadar întâmpină mult mai puține probleme.
Iată un exemplu de cod care încalcă acest principiu.

Dacă va fi necesar să modificăm ceva, va dura mult timp, deoarece va trebui să schimbăm toate părțile de cod care sunt legate de fragmentul dorit.
Apropo, principiul deschiderii și închiderii este unul dintre principiile SOLID.
Principiul responsabilității unice (SRP)
Un alt principiu din setul SOLID. Acesta afirmă că „există doar un motiv pentru a schimba o clasă”. O clasă rezolvă doar o singură problemă. Poate avea mai multe metode, dar fiecare dintre ele este utilizată doar pentru a rezolva sarcina generală. Toate metodele și proprietățile trebuie să servească doar acestui scop.

Valoarea acestui principiu constă în faptul că slăbește legătura dintre un anumit component de software și cod. Dacă se adaugă mai multă funcționalitate într-o clasă, aceasta introduce o legătură între două funcții. Astfel, dacă se schimbă una dintre ele, există o mare probabilitate să afecteze a doua, care este legată de prima. Și aceasta înseamnă creșterea ciclurilor de testare pentru a identifica toate problemele din timp.
Principiul inversării dependențelor (DIP)

Mai sus este un exemplu de cod, unde AppManager depinde de EventLogWriter, care, la rândul său, este strâns legat de AppManager. Dacă este nevoie de o altă metodă de a arăta notificarea, fie că este vorba de push, SMS sau email, va trebui să modificăm clasa AppManager.
Problema poate fi rezolvată cu ajutorul DIP. Astfel, în loc de AppManager, cerem EventLogWriter, care va fi introdus cu ajutorul framework-ului.
DIP permite înlocuirea fără probleme a modulelor individuale cu altele, prin modificarea modulului de dependență. Aceasta oferă posibilitatea de a modifica un modul fără a afecta restul.
Compoziție în loc de moștenire
Există două moduri principale de a reutiliza codul — moștenirea și compoziția, fiecare având propriile avantaje și dezavantaje. De obicei, se preferă a doua, deoarece este mai flexibilă.
Compoziția oferă posibilitatea de a schimba comportamentul unei clase în timpul execuției prin setarea proprietăților sale. La implementarea interfețelor se folosește polimorfismul, care oferă o implementare mai flexibilă.
Chiar și „Effective Java” de Joshua Bloch recomandă să se prefere compoziția în locul moștenirii.
Principiul substiției Barbara Liskov (LSP)
Încă un principiu din instrumentarul SOLID. Acesta afirmă că subtipurile trebuie să fie substituibile pentru supertip. Asta înseamnă că metodele și funcțiile care lucrează cu superclasa trebuie să poată funcționa fără probleme și cu subclasele acesteia.
LSP este legat atât de principiul responsabilității unice, cât și de principiul separării responsabilităților. Dacă o clasă oferă mai multe funcționalități decât subclasa, atunci aceasta din urmă nu va susține anumite funcții, încălcând acest principiu.
Iată un fragment de cod care contrazice LSP.

Metoda area(Rectangle r) calculează aria Rectangle. Programul va cădea după executarea lui Square, deoarece Square nu este un Rectangle aici. Conform principiului LSP, funcțiile care folosesc referințe la clasele de bază trebuie să fie capabile să utilizeze și obiectele claselor derivate fără instrucțiuni suplimentare.
Acest principiu, care este o definiție specifică a subtipului, a fost propus de Barbara Liskov în 1987 la o conferință în cadrul unei sesiuni plenare intitulate „Abstracția datelor și ierarhia” — de aici și denumirea sa.
Principiul separării interfeței (ISP)
Încă un principiu SOLID. Conform acestuia, o interfață care nu este folosită nu trebuie implementată. Urmarea acestui principiu ajută sistemul să rămână flexibil și ușor de refactorizat atunci când se fac modificări în logica de funcționare.
Cea mai frecventă situație apare atunci când interfața conține mai multe funcționalități, iar clientul are nevoie doar de una dintre ele.
Deoarece scrierea unei interfețe este o sarcină complicată, după finalizarea lucrării, modificarea acesteia fără a încălca nimic va fi o problemă.
Avantajul principiului ISP în Java este că mai întâi trebuie implementate toate metodele, iar abia apoi ele pot fi utilizate de către clase. Prin urmare, acest principiu permite reducerea numărului de metode.

Programare pentru interfață, nu pentru implementare
Aici totul este clar din denumire. Aplicarea acestui principiu duce la crearea unui cod flexibil, care poate funcționa cu orice nouă implementare a interfeței.
Trebuie să folosești tipul interfeței pentru variabile, tipuri returnate sau tipul argumentului metodei. Exemplu — utilizarea SuperClass, nu SubClass.
Adică:
List numbers = getNumbers();
Și nu:
ArrayList numbers = getNumbers();
Iată o implementare practică a celor spuse mai sus.

Principiul delegării
Un exemplu comun este metodele equals() și hashCode() în Java. Când este necesară compararea a două obiecte, această acțiune este delegată clasei corespunzătoare în loc de client.
Avantajul principiului este absența duplicării codului și schimbarea relativ simplă a comportamentului. De asemenea, este aplicabil pentru delegarea evenimentelor.

Toate aceste principii permit scrierea de cod mai flexibil, mai frumos și mai fiabil, cu o conectivitate ridicată și un cuplaj scăzut. Desigur, teoria este importantă, dar pentru ca un dezvoltator să folosească cu adevărat cunoștințele dobândite, este necesară practica. Următorul pas după stăpânirea principiilor OOP ar putea fi studiul modelor de proiectare pentru rezolvarea problemelor comune de dezvoltare a software-ului.
Skillbox recomandă:
- Curs practic .
- Curs online aplicat .
- Curs practic de doi ani .
Sursa: habr.com
