Principiul responsabilității unice ( SRP ) este un principiu POO care înseamnă că fiecare obiect trebuie să aibă o singură responsabilitate și această responsabilitate trebuie să fie complet încapsulată într- o clasă . Toată conduita lui trebuie să fie îndreptată exclusiv spre asigurarea acestei responsabilități.
O clasă ar trebui să aibă un singur motiv să se schimbe.Robert C. Martin
Termenul SRP a fost inventat de Robert S. Martin într-un articol cu același nume ca parte din SOLID , popularizat prin cartea sa Rapid Software Development. Principii, exemple, practică.” [1] . Martin a descris SRP pe baza unui model descris de Tom DeMarco [2] și Mailer Page-Jones [3] numit conectivitate .
În SOLID , litera „S” este o abreviere pentru Principiul responsabilității unice.
Martin definește responsabilitatea drept motivul schimbării și concluzionează că clasele ar trebui să aibă unul și un singur motiv pentru schimbare. De exemplu, imaginați-vă o clasă care scrie și imprimă un raport. O astfel de clasă se poate schimba din două motive:
În mod logic, ambele aspecte ale acestor cauze sunt de fapt două responsabilități diferite. SRP spune că, în acest caz, trebuie să împărțiți clasa în două clase noi, care vor fi caracterizate de o singură responsabilitate. Motivul pentru care este important să păstrezi cursurile concentrate pe un singur scop este pentru că face cursurile mai sănătoase. În ceea ce privește clasa de mai sus, dacă a existat o schimbare în procesul de compilare a raportului, există o mare probabilitate ca codul responsabil pentru imprimare să devină inutilizabil.
Când se proiectează comportamente diferite pentru aceeași clasă, apare adesea un „ Obiect Dumnezeu ”, care este considerat un anti -model în OOP . Respectarea principiului responsabilității unice evită acest anti-model.
Apare întrebarea când merită să folosiți acest principiu? Totuși, un principiu nu este o lege și SRP ar trebui aplicat în funcție de modul în care se modifică aplicația:
Urmărirea orbește a principiului responsabilității unice duce la o complexitate excesivă a aplicației, susținerea și testarea acesteia. SRP trebuie utilizat numai atunci când este garantat. Principiul SRP poate fi aplicat numai atunci când:
Consolidarea responsabilităților este o practică obișnuită și nu este nimic în neregulă cu ea, atâta timp cât este ușor de întreținut. Urmărirea principiului responsabilității unice depinde de funcțiile produsului software și este cea mai dificilă la proiectarea aplicațiilor.
ActiveRecord este adesea citat ca exemplu de încălcări SRP , un model care vă permite să legați cu ușurință datele obiectului și datele dintr-o bază de date. În ActiveRecord, multe responsabilități sunt concentrate într-un singur loc și, prin urmare, se poate argumenta că ActiveRecord încalcă SRP și devine astfel un anti-pattern. [4] În unele cazuri, această afirmație este discutabilă, deoarece obiectul în sine, care implementează ActiveRecord, nu conține nicio logică de afaceri, dar oferă un tabel din baza de date, are un singur motiv pentru schimbare (schimbarea tabelului), care nu nu contrazice definiția principiului SRP [5] [6] .
Următoarele tehnici vă permit să respectați principiul responsabilității unice:
Un exemplu clasic [7] al unei încălcări SRP este atunci când un sistem de reguli de afaceri ( BRMS ) trebuie să se ocupe de stocarea persistentă ( Persistence ). În primele etape ale proiectării unor astfel de sisteme, este creată o clasă care procesează regulile de afaceri și conține logica pentru lucrul cu baza de date. Odată cu încălcarea SRP, apar semne ale unui proiect prost , cum ar fi:
Dacă sistemul a fost dezvoltat inițial prin testare ( TDD ), atunci este posibil ca această problemă să nu fi apărut. Pe baza testelor, dezvoltatorii își pot imagina rapid de ce funcționalitate are nevoie utilizatorul. Astfel, detaliile clasei apar cu mult înainte de implementarea finală a soluției, influențând astfel proiectarea sistemului dezvoltat. Dar se întâmplă, de asemenea, ca dezvoltarea bazată pe teste să nu conducă la aplicarea modelului Class Extraction , apoi sistemul este refactorizat folosind modelele Facade , DAO sau Proxy .
SRP sugerează separarea claselor generice în clase concrete, ceea ce le va face simple și ușor de întreținut. O idee similară este prezentată și de principiul KISS [8] .