Compatibile con Xcode 8

Principio di Singola Responsabilità applicato al linguaggio Swift

ENTRA NEL NOSTRO GRUPPO FACEBOOK

A fare più cose contemporaneamente c’è il rischio di confondersi. Se questa sembra una cosa assodata nella vita reale, nella programmazione molti tendono a dimenticarsene.

Il principio di Singola Responsabilità stabilisce che una classe deve essere responsabile di una singola e sola funzionalità dell’applicazione. Questa classe, inoltre, deve incapsularne tutto il comportamento.

Secondo l’autore di questo principio, lo zio Bob (Robert C. Martin), si definisce Responsabilità il motivo per cui una classe potrebbe cambiare. Di conseguenza, una classe o metodo, per rispettare il principio, dovrebbe avere un solo motivo per cambiare.principio di singola responsabilità

Cosa vuol dire cambiare? e come si applica il principio di Singola Responsabilità?
Vediamo il principio di Singola Responsabilità applicato al linguaggio Swift!

Prima di continuare, se non lo hai ancora fatto, potrebbe esserti d’aiuto e propedeutica la lettura del tutorial sulla legge di Demetra.

Esempio

Ipotizziamo che una società ti commissioni la realizzazione di un’applicazione che ha un e-commerce accessibile da più paesi.

I prodotti da visualizzare sono composti, per semplicità di spiegazione, da due campi: il nome ed il prezzo. Quest’ultimo, cioè il prezzo, è scorporato dalle tasse e, dato che l’app viene utilizzata da più parti del mondo, deve poter essere visualizzato con la VAT (cioè l’IVA) del paese dell’utente.

Uno sviluppatore alle prime armi con la OOP (Programmazione Orientata agli Oggetti), nel 99% dei casi, creerà qualcosa di simile a questo:

Peppe, ma sei sicuro che ci siano dei problemi? perché io non vedo niente di sbagliato in questa classe!

Esatto, l’impiccio sta proprio nel non vederne i problemi 😎

Prima applicazione del principio

Comincia a guardare le classi dal punto di vista della Singola Responsabilità e poniti la domanda: per quali motivi dovrei poter cambiare il comportamento (codice della classe)? 

Ci sono due motivi per cui potresti mettere mano alla classe:

  1. In primo luogo, il contenuto del Report può cambiare. Cioè capiterà, in futuro, di dover aggiungere nuove proprietà o di dover cambiare la struttura dei dati
  2. In secondo luogo, il metodo del calcolo del VAT può cambiare in contenuto e forma di calcolo

Una volta trovati due o più motivi non resta altro che domandarsi: come suddivido i motivi in classi a se stanti?

Il calcolo del VAT è qualcosa che ha a che fare con il prezzo. Di conseguenza ne conviene che il prezzo potrebbe vivere in una classe a se stante che, oltre ad avere il compito di gestire il valore al netto di tasse, può restituirne uno nuovo con l’aggiunta della tassa:

Decisamente una struttura più snella e facile da comprendere. Adesso, tutta la logica per la gestione del prezzo è relegata e rinchiusa all’interno della classe Price. 

La classe Product è diventata indipendente dai cambiamenti interni della classe Price.

Non noti ancora i benefici?

Immagina la classe Product all’interno di un vero progetto. Senza l’applicazione del principio di Singola Responsabilità ti ritroverai sicuramente ad avere decine di metodi e proprietà all’interno della classe Product.

Questo significa che, in un ipotetico caso di controllo e/o ricerca dell’errore, perderai del tempo solamente a cercare visivamente, ed all’interno della classe, il metodo/proprietà coinvolto. In più, il fatto di aver mischiato responsabilità diverse ti porterà a chiederti: É l’intera classe che ha problemi? i metodi vanno in conflitto tra loro?

Con l’utilizzo del principio di Singola Responsabilità anche i problemi e gli errori si responsabilizzano.

Per esempio, se si dovesse verificare un errore sul calcolo del prezzo sai che dovrai andarlo a ricerca all’interno della classe che lo controlla e non più all’interno di una classe più vasta e che contiene responsabilità differenti.

Seconda applicazione del principio

Ma, torniamo a noi!

Se sei stato attento, adesso è la classe Price che ha più responsabilità differenti. O meglio, il suo metodo withVAT ha più di un motivo per cambiare. Il primo riguarda un problema di contenuto, cioè il calcolo della VAT (un domani potrebbe cambiare la formula). Il secondo è relativo alla struttura utilizzata per generare il valore di IVA del paese in questione.

Lo switch sulla stringa porta con se diversi problemi. Il più importante è quello che bisogna inserire la stringa in modo che sia uguale ad uno dei case presenti. Cioè se io dovessi scrivere “IT” il codice non funzionerà perché si aspetta un “it”.

Potresti, quindi, rendere la generazione del VAT dipendente da un enum (dato che si tratterebbe solo di un elenco di valori):

Quello che viene fuori è una struttura di classi completamente indipendente l’una dall’altro e, cosa più importante, ognuna di questa ha una singola responsabilità cioè si occupa di una e solamente una parte dell’applicazione:

Ci sarebbe altre modifiche da fare (ma che non riguardano il principio) e per evitare di appesantire il tutorial eviterò di fare.

Perché usarlo?

Arrivati a questo punto generalmente in testa appare una sola e singola domanda: perché?

  1. Perché dovrei creare tre sovrastrutture quando con una potevo risolvere tutti i problemi?
  2. Perché devo utilizzarlo se tanto alla fine nel mio piccolo progetto le cose vanno bene così come sono?

Comincio col riprendere una frase detta nel tutorial sulla legge di Demetra (ti consiglio di leggerlo): Non perché puoi farlo significa che devi farlo. 

Però, in effetti hai ragione, io non ti biasimo. La scelta spetta solamente a te, alla fine della storia, l’applicazione funzionerà lo stesso.

Ma ha senso procedere senza regole?

Lasciamo stare per un momento la storia della bella scrittura del codice, della pulizia e della corretta applicazione.

Molti tirano in ballo la carte del tempo: “Perdo un sacco di tempo a seguire tutte queste regole“, “Devo sbrigarmi a rilasciare l’app, chissene**** dei pattern“.

Tra me e me sorrido quando mi rispondono così (e non far finta di non sapere di che sto parlando, probabilmente rientri anche tu nella categoria 😂 ).

É vero si perde del tempo ad acquisire una piena padronanza di queste regole. Ma questo tempo che perdi, non lo riacquisterai tutto più avanti?

Immagina di dover cucinare una frittata.

Se non sapessi che servono le uova, una padella e che devi versarle dentro, perderesti un sacco di tempo a cercare come si cuociono due uova. Invece, quel tempo non lo perdi perché sai esattamente come e cosa devi fare.

Molti continuano a pensare che le applicazioni sono sempre diverse l’una dall’altra. Ma invece no. Nella loro struttura di base sono tutte uguali, sono tutte delle frittate.

Se sai cosa sono sai anche come controllarle. Se so che ho delle strutture che rispecchiano una regola so sempre dove andare a cercare il problema. Se invece ho strutture casuali la mia ricerca sarà sempre casuale. Potrò avere la fortuna di trovare il problema al primo tentativo come potrei non trovare l’errore se non dopo ore ed ore di ricerca.

Va bene. mi hai convinto, al primo progetto importante seguirò questo consiglio.

Proprio qui casca l’asino.

Scrivi correttamente solo quando devi scrivere email importanti? Baci bene la tua lei o il tuo lui solo al primo appuntamento?

Se non ti eserciterai con i progetti piccoli, al primo progetto enorme, ti ritroverai sottoterra nel giro di poche ore. Queste regole non si apprendono leggendole, si apprendono con la pratica.

Considerazioni

Il principio di Singola Responsabilità o abbreviato in SRP fa parte di una famiglia di principi che viene chiamata SOLIDDove la S sta proprio ad indicare Responsibility.

Questi principi formano la base per la corretta interpretazione ed utilizzo di base della programmazione orientata agli oggetti. La comprensione di dei principi SOLID è anche il punto d’ingresso per lo step successivo che sono i pattern di programmazione.

Pian piano conto di poterli descrivere tutti!

A questo punto, se non lo hai ancora fatto, ti consiglio la lettura sulla legge di Demetra. Un’altra piccola chicca che ti aiuterà nella scrittura del codice.

Buona Programmazione!

Start typing and press Enter to search

Le differenze tra struct e class del linguaggio Swift