SRP: cos’è, il principio di responsabilità unica nello sviluppo

Autore: IT Sectr Pubblicato: 2026-05-11 Tempo di lettura: 9 min

SRP (Single Responsibility Principle) — il primo principio di SOLID, che stabilisce: ogni classe o modulo deve avere esattamente una ragione per cambiare. Questo principio è stato formulato da Robert Martin nel libro Clean Architecture (2017) ed è diventato il fondamento del design modulare. Secondo questo libro, l’applicazione di SRP riduce direttamente l’accoppiamento dei componenti ed elimina le modifiche a cascata durante la modifica delle funzionalità.

Punti chiave

  • SRP — il primo principio SOLID, che richiede una responsabilità per classe
  • Ragione di cambiamento — l’unico criterio per assegnare la responsabilità a un modulo
  • Violare SRP porta a codice accoppiato, difficile da testare ed estendere
  • Applicare il principio semplifica il refactoring e riduce il rischio di errori di regressione
  • SRP nello sviluppo mobile aiuta a separare la logica UI, le regole di business e la gestione dei dati

Cos’è SRP (Single Responsibility Principle)?

SRP (Single Responsibility Principle) è il principio di responsabilità unica, che afferma: ogni classe o modulo deve avere esattamente una ragione per cambiare. Ciò non significa che una classe debba eseguire esattamente un’operazione. Si riferisce a un gruppo di azioni correlate unite da un’unica responsabilità verso un attore.

Robert Martin ha riformulato SRP in termini di attori: una classe dovrebbe cambiare solo su richiesta di un singolo stakeholder o di un gruppo di persone. Se due attori diversi richiedono modifiche alla stessa classe, la responsabilità è divisa in modo errato.

Ad esempio, una classe Employee che calcola lo stipendio (richiesta dell’ufficio contabile) e genera report (richiesta della direzione) viola SRP. Modificare le regole di calcolo potrebbe influenzare la generazione dei report e viceversa.

Definizione formale di SRP

Un modulo deve avere una e una sola ragione per cambiare. La ragione del cambiamento è determinata da un attore — persona o sistema che avvia il requisito. Se requisiti provenienti da attori diversi portano a modifiche in un singolo modulo, quel modulo viola SRP.

Il concetto di attore rende SRP uno strumento pratico di analisi architetturale, non una raccomandazione astratta. Quando si progetta un sistema, basta chiedersi: “Chi chiederà di modificare questo codice?” — se la risposta include più di uno stakeholder, la responsabilità dovrebbe essere divisa.

Come funziona il principio di responsabilità unica

La responsabilità unica viene implementata raggruppando i metodi che cambiano per una stessa ragione. La classe diventa un “punto di raccolta” di logica correlata, non un “coltellino svizzero” per tutte le occasioni. Ciò semplifica la comprensione del codice: lo sviluppatore vede la classe e ne comprende immediatamente lo scopo.

Il meccanismo di SRP si basa sulla regola dell’unico asse di cambiamento. Se una funzionalità può cambiare per ragioni indipendenti, dovrebbe essere estratta in classi separate. Le connessioni tra queste classi sono costruite tramite composizione o delega.

La violazione di SRP si manifesta nei “God Objects” — classi con decine di metodi che lavorano con dati diversi. Una classe del genere è difficile da testare — testare un metodo richiede di configurare l’ambiente per tutti gli altri. Cambiare una responsabilità può romperne un’altra, rendendo il codice fragile.

In pratica, SRP aiuta gli sviluppatori a rispondere alla domanda “dov’è questo codice?” Se ogni responsabilità è separata nella propria classe, trovare il file giusto richiede secondi. In un progetto Android con architettura MVVM, UserViewModel è responsabile solo dello stato dello schermo utente, e UserRepository del recupero dati. Uno sviluppatore che cerca la logica di caching va in UserCacheRepository, non in ViewModel. Tale organizzazione del codice accelera l’inserimento di nuovi membri del team e riduce il numero di errori durante il refactoring.

Perché SRP è importante nello sviluppo mobile

Lo sviluppo mobile pone esigenze particolari di modularità del codice. Un Fragment Android o un ViewController iOS diventa spesso una “calamita” di logica: gestione dei tocchi, chiamate API, analisi delle risposte, aggiornamento UI — tutto in una classe. SRP richiede di separare queste responsabilità.

Nell’architettura Android, SRP è integrato nelle raccomandazioni di Google su Jetpack: ViewModel è responsabile dello stato dello schermo, Repository dei dati, UseCase della logica di business. Ogni componente ha una ragione per cambiare. Nello sviluppo iOS, i pattern MVVM e Coordinator seguono la stessa logica.

Seguire SRP nei progetti mobile porta vantaggi misurabili: riduzione del 40-60% della dimensione delle classi, meno tempo nelle revisioni del codice e meno bug di regressione quando si aggiungono nuove funzionalità. I moduli isolati sono più facili da coprire con test unitari e riutilizzare in altri schermi.

Impatto di SRP sui test

I test unitari delle classi che seguono SRP richiedono meno oggetti mock e meno configurazione. Se una classe ha un’unica responsabilità, le sue dipendenze sono limitate. Il test verifica un comportamento, non una combinazione di più scenari non correlati.

Secondo il report del Google Testing Blog (2023), le classi con responsabilità unica mostrano il 35% in più di copertura dei test rispetto alle classi aggregatrici. Gli sviluppatori sono più propensi a scrivere test per moduli piccoli e comprensibili.

Esempi di SRP in Android e iOS

Consideriamo una classe Android tipica che viola SRP — carica dati, analizza la risposta e aggiorna l’UI. Dopo il refactoring, ogni responsabilità è separata nel proprio componente.

kotlin
// Violazione SRP: una classe fa tutto
class BadUserProfileActivity {
    fun loadUser(userId: Int) {
        // Richiesta HTTP
        // Parsing JSON
        // Aggiornamento UI
        // Salvataggio DB
    }
}

// Dopo l'applicazione di SRP
class UserRepository {
    fun getUser(userId: Int): User
}

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

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

Un esempio simile in iOS Swift con separazione del livello di rete e visualizzazione:

swift
// Violazione SRP: ViewController gestisce dati e UI
class BadProfileViewController: UIViewController {
    func viewDidLoad() {
        // Richiesta URLSession
        // Decodifica JSON
        // Aggiornamento label
    }
}

// Dopo l'applicazione di 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) { }
}

Il refactoring SRP non complica l’architettura — ridistribuisce la responsabilità. La quantità di codice può persino diminuire eliminando le duplicazioni. Ogni nuova classe ha uno scopo chiaro e può essere sviluppata indipendentemente.

La composizione come alternativa all’ereditarietà

La composizione aiuta a mantenere SRP là dove l’ereditarietà crea accoppiamenti inutili. Invece di una superclasse con decine di metodi, la sottoclasse riceve un insieme di oggetti specializzati tramite il costruttore. Ogni oggetto è responsabile della propria funzionalità.

Nello sviluppo Android, il pattern Decorator permette di aggiungere responsabilità senza modificare la classe originale. In iOS, una catena di Middleware nel livello di rete separa logging, caching e autenticazione in moduli indipendenti.

Violazioni tipiche di SRP e loro conseguenze

La violazione più comune è una “God Class”: una classe che gestisce il database, invia notifiche, genera report e processa l’input dell’utente. Una classe del genere diventa un collo di bottiglia del progetto: qualsiasi modifica richiede test di regressione completi.

Nello sviluppo mobile, la violazione di SRP deriva dalla mescolanza di logica di business e logica UI in Activity, Fragment o ViewController. Quando un onClickListener contemporaneamente valida dati, chiama un’API e aggiorna la visibilità dei pulsanti — è una violazione diretta del principio di responsabilità unica.

Le conseguenze della violazione di SRP includono: difficoltà nello sviluppo parallelo (conflitti in un singolo file), test unitari difficoltosi, alto costo delle modifiche e minore leggibilità del codice. I progetti con violazioni sistematiche di SRP richiedono 2-3 volte più tempo per aggiungere nuove funzionalità.

Indicatori di violazione di SRP nel codice

Le violazioni di SRP possono essere identificate da segni indiretti: la classe supera le 200 righe, importa moduli da diversi livelli applicativi (UI + network + database), ha più di 5 metodi pubblici su temi diversi. La metrica di coesione è un indicatore statistico: una bassa coesione dei metodi all’interno di una classe indica una violazione di SRP.

Per individuare violazioni di SRP, utilizzare strumenti di analisi statica: per Android — Detekt con la regola TooManyFunctions, per iOS — SwiftLint con la regola file_length. Questi strumenti evidenziano le classi che superano le soglie di dimensione e complessità.

Il refactoring delle classi che violano SRP viene eseguito tramite Extract Class o Extract Delegate: un gruppo di metodi correlati viene estratto in una classe separata, e la classe originale delega le chiamate ad essi. L’applicazione graduale di questi refactoring trasforma una “God Class” in un insieme di modoli debolmente accoppiati, ciascuno con un’unica responsabilità. Questo approccio permette di migliorare l’architettura senza fermare lo sviluppo — il refactoring viene eseguito in modo iterativo, un modulo alla volta.

Domande frequenti

SRP significa che una classe deve contenere un solo metodo?

No. SRP non riguarda il numero di metodi, ma il numero di ragioni per cambiare. Una classe può avere decine di metodi se servono tutti un’unica responsabilità verso un singolo attore. Un solo metodo è l’estremo opposto, che porta a un’eccessiva frammentazione del codice.

In cosa SRP differisce dal principio di obbligo unico?

È lo stesso principio. Single Responsibility Principle si traduce sia come “responsabilità unica” che come “obbligo unico”. Il termine “responsabilità” riflette meglio l’essenza: si tratta della responsabilità verso un attore, non di una funzione tecnica.

Come si relaziona SRP con il pattern Repository?

Repository è un risultato diretto dell’applicazione di SRP al livello dati. Invece di spargere la logica di accesso ai dati in ViewModel o UseCase, Repository assume un’unica responsabilità: fornire dati con astrazione della fonte. È un’implementazione classica di SRP nell’architettura mobile.

Una classe SRP può avere dipendenze da altre classi?

Sì, SRP non vieta le dipendenze. Una classe con un’unica responsabilità può delegare parte del lavoro ad altre classi tramite composizione. L’importante è che questi compiti delegati facciano parte della stessa responsabilità, non una ragione indipendente per cambiare.

Come verificare se una classe rispetta SRP?

Fate la domanda: “Quali attori potrebbero richiedere modifiche a questa classe?” Se la risposta contiene più di un attore, SRP è violato. Inoltre: provate a descrivere lo scopo della classe in una frase senza la congiunzione “e”. Se non ci riuscite, la classe fa troppo.

Riepilogo

  • SRP (Single Responsibility Principle) — il primo principio SOLID, che richiede una sola ragione per cambiare una classe
  • La ragione del cambiamento è determinata da un attore — persona o sistema che avvia un requisito per il modulo
  • Violare SRP porta a God Class, bassa testabilità e alti costi di modifica
  • Nello sviluppo mobile SRP separa la logica UI, la logica di business e la gestione dei dati in componenti indipendenti
  • La composizione aiuta a mantenere SRP meglio dell’ereditarietà, delegando a oggetti specializzati
  • Gli strumenti di analisi statica (Detekt, SwiftLint) rilevano automaticamente potenziali violazioni di SRP
  • I test unitari delle classi SRP richiedono meno oggetti mock e mostrano una maggiore copertura del codice

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche