TIL - Principio di Singola Responsabilità


Oggi ho letto un articolo facile da comprendere sul principio di singola responsabilità, chiamato anche SRP1. L’articolo in questione è di Fenis Despoudis.

L’SRP fa parte di una serie di principi che insieme formano il S.O.L.I.D.:

  • S -> SRP (Single Responsability Principle)
  • O -> OCP (Open Closed Principle)
  • L -> LSP (Liskov substitution Principle)
  • I -> ISP (Interface Segregation Principle)
  • D -> DIP (Dependency Inversion Principle)

Ogni modulo o classe dovrebbe avere la responsabilità su una singola parte della funzionalità fornita dal software e quella funzionalità dovrebbe essere interamente incapsulata nella classe.

Per capire bene di cosa stiamo parlando focalizziamoci su ogni singola parte del principio in questione:

Singola

Questa parte si riferisce al fatto che un metodo o una determinata componente di una classe dovrebbe limitarsi a svolgere una singola cosa.

Prendiamo in esempio un metodo incaricato di prendere dei dati e renderizzarli, la via migliore per applicare l’SRP è quello di spezzare il metodo in questione dividendo i due compiti.

Responsabilità

Per responsabilità parliamo di lavoro o azione che assegnamo ad ogni parte del nostro sistema, troppa responsabilità induce all’accoppiamento.

Quando un client ha bisogno di conoscere la classe B per usare la classe A, allora A e B sono accoppiate

Bisognerebbe raggiungere all’interno del sistema una giusta quantità di accoppiamento per mantenere un buon livello di coesione; infatti, componenti con un basso livello di coesione svolgono tasks che non sono correlati alle loro responsabilità, per esempio:

class User {
  public age, name, email;

  checkAge();
  validateEmail();
}

Perché i metodi checkAge e validateEmail son lì? Questo rende la classe meno coesiva aggiungendo metodi che non avrebbe senso avere nella classe User, avrebbe infatti più senso metterli in una classe apposita che possiamo liberamente chiamare per esempio UserFieldValidation

Cambiamento

Alterazione o modifica del codice esistere

Quando si programma è praticamente una prassi dover cambiare il codice esistente, non si scappa; pensate ad un modulo molto grande che usa altre classi scritte magari meno bene della vostra, sarete puntualmente costretti a ristrutturare il codice per accomodare a futuri cambiamenti aumentando inesorabilmente la complessità. WRONG!

Come faccio a far seguire questo principio al mio codice?

Un piccolo consiglio ma di grande impatto è quello di essere KISS2.

Cerca di unire le cose che cambiano per la stessa ragione e tieni separate le cose che cambiano per motivi diversi.

In poche parole:

Isola il cambiamento

  • Prestare attenzione a metodi o classi troppo grandi
  • tenere traccia delle dipendenze controllando per esempio se il costruttore ha come parametri troppe dipendenze, infatti tenere traccia dei parametri dei metodi aiuta a capire se un determinato metodo richiede troppe cose per funzionare.
  • Usare nomi semplici, spesso nomi troppo lunghi sono sinonimo di un qualcosa che fa più cose
  • Rifattorizza spesso e presto se noti che qualcosa può essere semplificata

Questo principio infatti va di pari passo con l’ISP permettendo di scrivere del codice facile da refattorizzare e da cambiare.