SRP: ce este, principiul responsabilității unice în dezvoltare

Autor: IT Sectr Publicat: 2026-05-11 Timp de citire: 9 min

SRP (Single Responsibility Principle) — primul principiu SOLID care definește: fiecare clasă sau modul trebuie să aibă exact un motiv pentru a se modifica. Acest principiu a fost formulat de Robert Martin în cartea Clean Architecture (2017) și a devenit fundamentul proiectării modulare. Conform acestei cărți, aplicarea SRP reduce direct cuplarea componentelor și elimină modificările în cascadă la îmbunătățirea funcționalității.

Principalele

  • SRP — primul principiu SOLID, care cere o singură responsabilitate per clasă
  • Motivul modificării — singurul criteriu pentru delimitarea responsabilității într-un modul
  • Încălcarea SRP duce la cod cuplat, greu de testat și extins
  • Aplicarea principiului simplifică refactorizarea și reduce riscul erorilor de regresie
  • SRP în dezvoltarea mobilă ajută la separarea logicii UI, a regulilor de afaceri și a lucrului cu datele

Ce este SRP (Single Responsibility Principle)?

SRP (Single Responsibility Principle) — principiul responsabilității unice care spune: fiecare clasă sau modul trebuie să aibă exact un motiv pentru a se modifica. Aceasta nu înseamnă că o clasă trebuie să execute exact o operație. Este vorba despre un grup de acțiuni conexe, unite printr-o singură responsabilitate față de un actor.

Robert Martin a reformulat SRP în termeni de actori: o clasă trebuie să se modifice doar la cererea unei persoane interesate sau a unui grup de persoane. Dacă doi actori diferiți solicită modificarea aceleiași clase — responsabilitatea este împărțită incorect.

De exemplu, clasa Employee, care simultan calculează salariul (cererea contabilității) și generează un raport (cererea conducerii), încalcă SRP. Modificarea regulilor de calcul poate afecta generarea raportului și invers.

Definiția formală a SRP

Modulul trebuie să aibă unul și numai un singur motiv pentru a se modifica. Motivul modificării este determinat de actor — persoana sau sistemul care inițiază cerința. Dacă cerințele de la actori diferiți duc la modificarea aceluiași modul — modulul încalcă SRP.

Conceptul de actor face din SRP un instrument practic de analiză arhitecturală, nu o recomandare abstractă. La proiectarea unui sistem este suficient să întrebăm: „Cine va cere modificarea acestui cod?” — dacă răspunsul conține mai multe persoane interesate, responsabilitatea trebuie împărțită.

Cum funcționează principiul responsabilității unice

Responsabilitatea unică se realizează prin gruparea metodelor care se modifică dintr-un singur motiv. Clasa devine un „punct de colectare” a logicii conexe, nu un „briceag elvețian” pentru orice situație. Acest lucru simplifică înțelegerea codului: dezvoltatorul vede clasa și înțelege imediat scopul său.

Mecanismul de funcționare al SRP se bazează pe regula unei singure axe de modificare. Dacă funcționalitatea se poate modifica din motive independente — trebuie extrasă în clase separate. Legăturile dintre aceste clase se construiesc prin compoziție sau delegare.

Încălcarea SRP se manifestă în „clasele-zeu” (God Objects), care conțin zeci de metode ce lucrează cu date diferite. O astfel de clasă este greu de testat — testarea unei metode necesită configurarea mediului pentru toate celelalte. Modificarea unei responsabilități poate strica alta, ceea ce face codul fragil.

În practică, SRP ajută dezvoltatorii să răspundă la întrebarea „unde se află acest cod?”. Dacă fiecare responsabilitate este separată în propria clasă, găsirea fișierului necesar durează secunde. Într-un proiect Android cu arhitectură MVVM, aceasta înseamnă că UserViewModel răspunde doar de starea ecranului utilizatorului, iar UserRepository — de obținerea datelor. Dezvoltatorul care caută logica de cache merge la UserCacheRepository, nu la ViewModel. O astfel de organizare a codului accelerează integrarea noilor membri ai echipei și reduce numărul de erori la refactorizare.

De ce SRP este important în dezvoltarea mobilă

Dezvoltarea mobilă impune cerințe speciale pentru modularitatea codului. Android Fragment sau iOS ViewController devin adesea „puncte de atracție” a logicii: procesarea clicurilor, apelarea API, parsarea răspunsului, actualizarea UI — totul într-o singură clasă. SRP cere separarea acestor responsabilități.

În arhitectura Android, SRP este încorporat în recomandările Google pentru Jetpack: ViewModel răspunde de starea ecranului, Repository — de date, UseCase — de logica de afaceri. Fiecare componentă are un singur motiv de modificare. În dezvoltarea iOS, modelul MVVM și Coordinator urmează aceeași logică.

Respectarea SRP în proiectele mobile oferă avantaje măsurabile: reducerea dimensiunii claselor cu 40-60%, scurtarea timpului de code-review și reducerea numărului de bug-uri de regresie la adăugarea de noi funcționalități. Modulele izolate sunt mai ușor de acoperit cu teste unitare și de reutilizat în alte ecrane.

Impactul SRP asupra testării

Testele unitare ale claselor care respectă SRP necesită mai puține obiecte mock și configurații. Dacă o clasă are o singură responsabilitate, dependențele sale sunt limitate. Testul verifică un singur comportament, nu o combinație de mai multe scenarii neconexe.

Conform raportului Google Testing Blog (2023), clasele cu responsabilitate unică arată o acoperire cu 35% mai mare cu teste comparativ cu clasele-agregatoare. Dezvoltatorii scriu mai ușor teste pentru module mici și ușor de înțeles.

Exemple SRP în Android și iOS

Examinați o clasă Android tipică care încalcă SRP — încarcă date, parsează răspunsul și actualizează UI. După refactorizare, fiecare responsabilitate este separată într-o componentă distinctă.

kotlin
// Încălcare SRP: o clasă face totul
class BadUserProfileActivity {
    fun loadUser(userId: Int) {
        // Cerere HTTP
        // Parsare JSON
        // Actualizare UI
        // Salvare în BD
    }
}

// După aplicarea SRP
class UserRepository {
    fun getUser(userId: Int): User
}

class UserViewModel {
    private val repo: UserRepository
    fun loadUser(userId: Int) { }
}

class UserProfileFragment {
    fun render(user: User) { }
}

Exemplu similar pe iOS Swift cu separarea stratului de rețea și al prezentării:

swift
// Încălcare SRP: ViewController gestionează date și UI
class BadProfileViewController: UIViewController {
    func viewDidLoad() {
        // Cerere URLSession
        // Decodare JSON
        // Actualizare label
    }
}

// După aplicarea SRP
protocol UserServiceProtocol {
    func fetchUser(id: Int) async throws -> User
}

class ProfileViewModel {
    private let service: UserServiceProtocol
    func loadProfile(id: Int) { }
}

class ProfileViewController: UIViewController {
    func display(user: User) { }
}

Refactorizarea SRP nu complică arhitectura — redistribuie responsabilitatea. Cantitatea de cod poate chiar să scadă prin eliminarea duplicării. Fiecare clasă nouă are un scop clar și poate fi dezvoltată independent.

Compoziția ca alternativă la moștenire

Compoziția ajută la respectarea SRP acolo unde moștenirea creează cuplări inutile. În loc de o superclasă cu zeci de metode, subclasa primește un set de obiecte specializate prin constructor. Fiecare obiect răspunde de propria funcționalitate.

În dezvoltarea Android, modelul Decorator permite adăugarea de responsabilități fără a modifica clasa originală. În iOS, lanțul Middleware în stratul de rețea separă logarea, cache-ul și autentificarea în module distincte.

Încălcări tipice SRP și consecințele lor

Cea mai frecventă încălcare — „God Class”: o clasă care gestionează baza de date, trimite notificări, generează rapoarte și procesează datele de intrare ale utilizatorului. O astfel de clasă devine un blocaj al proiectului: orice modificare necesită testare completă de regresie.

În dezvoltarea mobilă, încălcarea SRP este cauzată de amestecarea logicii de afaceri cu logica UI în Activity, Fragment sau ViewController. Când metoda onClickListener simultan validează datele, apelează API și actualizează vizibilitatea butoanelor — aceasta este o încălcare directă a principiului responsabilității unice.

Consecințele încălcării SRP includ: dificultatea dezvoltării paralele (conflicte într-un singur fișier), testarea unitară îngreunată, costul ridicat al modificărilor și scăderea lizibilității codului. Proiectele cu încălcare sistematică a SRP necesită de 2-3 ori mai mult timp pentru adăugarea de noi funcționalități.

Indicatori ai încălcării SRP în cod

Încălcarea SRP poate fi determinată prin semne indirecte: clasa conține peste 200 de linii, importă module din diferite straturi ale aplicației (UI + network + database), are mai mult de 5 metode publice cu tematică diferită. Metrica coeziunii (cohesion) — un indicator statistic: coeziunea scăzută a metodelor din interiorul clasei indică o încălcare a SRP.

Pentru depistarea încălcărilor SRP este util să folosiți instrumente de analiză statică: pentru Android — Detekt cu regula TooManyFunctions, pentru iOS — SwiftLint cu regula file_length. Aceste utilitare evidențiază clasele care depășesc pragurile de dimensiune și complexitate.

Refactorizarea claselor care încalcă SRP se realizează prin Extract Class sau Extract Delegate: un grup de metode conexe este extras într-o clasă separată, iar clasa originală le delegă apelurile. Aplicarea treptată a acestor refactorizări transformă „God Class” într-un set de module slab cuplate, fiecare cu o singură responsabilitate. O astfel de abordare permite îmbunătățirea arhitecturii fără a opri dezvoltarea — refactorizarea se execută iterativ, câte un modul pe rând.

Întrebări frecvente

Înseamnă SRP că o clasă trebuie să conțină o singură metodă?

Nu. SRP nu se referă la numărul de metode, ci la numărul de motive pentru modificare. O clasă poate avea zece metode dacă toate servesc o singură responsabilitate față de un singur actor. O singură metodă — este cealaltă extremă, care duce la o fragmentare excesivă a codului.

Cu ce diferă SRP de principiul obligației unice?

Este același principiu. Single Responsibility Principle se traduce atât ca „responsabilitate unică”, cât și ca „obligație unică”. Termenul „responsabilitate” reflectă mai exact esența: este vorba despre responsabilitatea față de un actor, nu despre o funcție tehnică.

Cum se leagă SRP de modelul Repository?

Repository — rezultatul direct al aplicării SRP la stratul de date. În loc să împrăștie logica de acces la date prin ViewModel sau UseCase, Repository își asumă o singură responsabilitate: furnizarea datelor cu abstractizarea sursei. Aceasta este o implementare clasică a SRP în arhitectura mobilă.

Poate o clasă cu SRP să aibă dependențe de alte clase?

Da, SRP nu interzice dependențele. O clasă cu o singură responsabilitate poate delega o parte din lucru altor clase prin compoziție. Este important ca aceste sarcini delegate să facă parte din aceeași responsabilitate, nu să fie un motiv independent de modificare.

Cum verific dacă o clasă respectă SRP?

Puneți întrebarea: „Ce actori ar putea solicita modificarea acestei clase?” Dacă răspunsul conține mai mult de un actor — SRP este încălcat. Suplimentar: încercați să descrieți scopul clasei într-o singură frază fără conjuncția „și”. Dacă nu reușiți — clasa face prea multe.

Rezumat

  • SRP (Single Responsibility Principle) — primul principiu SOLID, care cere un singur motiv pentru modificarea unei clase
  • Motivul modificării este determinat de actor — persoana sau sistemul care inițiază cerința față de modul
  • Încălcarea SRP duce la God Class, testabilitate scăzută și costuri ridicate de modificare
  • În dezvoltarea mobilă SRP separă logica UI, logica de afaceri și lucrul cu datele în componente distincte
  • Compoziția ajută la respectarea SRP mai eficient decât moștenirea, prin delegarea către obiecte specializate
  • Instrumentele de analiză statică (Detekt, SwiftLint) detectează automat potențialele încălcări SRP
  • Testele unitare ale claselor cu SRP necesită mai puține obiecte mock și arată o acoperire mai mare a codului

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și