Chiunque abbia un po’ di esperienza nella programmazione software, giudica codice software scritto da altri, utilizzando parametri di giudizio basati sul proprio percorso di crescita professionale.
Nel corso della mia carriera professionale, ho conosciuto molti sviluppatori, e ho visto migliaia di righe di codice e quando ho bisogno di valutare l’abilità di uno sviluppatore guardo principalmente due fattori:
Fortunatamente, ci sono alcuni fondamenti o principi che rendono facile essere migliori nella codifica.
l’acronimo S.O.L.I.D. sta per:
S: principio di responsabilità unica
O: principio aperto-chiuso
L: Principio di sostituzione di Liskov
I: Principio di segregazione dell’interfaccia
D: Principio di inversione delle dipendenze
Iniziamo con approfondire il primo principio SOLID, cioè il
Una classe (o modulo) dovrebbe avere un solo motivo per cambiare, per evolversi.
Il concetto di per se è molto semplice, però per raggiungere questa semplicità il percorso di attuazione può essere molto complicato. Una classe dovrebbe avere un solo motivo per cambiare.
Ma perché?
Perché è così importante avere una sola ragione per cambiare?
Ad esempio se ci sono due diversi motivi per cambiare, è concepibile che due diversi team possano lavorare sullo stesso codice per due diversi motivi. Ciascuno dovrà implementare la propria soluzione, che nel caso di un linguaggio compilato (come C ++, C # o Java), potrebbe portare a moduli incompatibili con altri team o altre parti dell’applicazione.
Altro esempio, se si usa un linguaggio interpretato, si potrebbe dover ripetere il test della stessa classe o modulo per motivi diversi. Questo implica più lavoro, tempo e impegno per il controllo qualità.
Andare a identificare l’unica feature che una classe o un modulo dovrebbe avere è molto più complesso che guardare semplicemente una checklist per eseguire i test.
Ma proviamo a ragionare da un punto di vista meno tecnico, e cioè proviamo ad analizzare l’utenza della nostra classe o modulo, cioè chi andrà ad utilizzarla. Un aspetto fondamentale che dobbiamo sempre tenere in considerazione, è il fatto che gli utenti dell’applicazione o del sistema che sviluppiamo che sono serviti da un particolare modulo saranno quelli che richiedono modifiche allo stesso. Quelli serviti chiederanno il cambiare la classe o il modulo.
Alcuni esempi di moduli e relativa utenza:
Quindi se il primo passo consiste nel ricercare gli attori o l’attore che ha il ruolo di interlocutore con il modulo, associare persone fisiche a tutti i ruoli può essere difficile. In una piccola azienda una sola persona può svolgere più ruoli mentre in una grande azienda possono esserci più persone che hanno un unico ruolo.
Sembra più ragionevole identificare i ruoli, invece che le persone o gli utenti.
Quindi:
Vediamo degli esempi
Supponiamo di avere una classe Libro che incapsula il concetto di un libro e le sue funzionalità.
class Libro {
function getTitolo() {
return “Un Grande Libro”;
}
function getAutore() {
return “Alessandro Baricco”;
}
function prossimaPagina() {
// pagina successiva
}
function printPaginaCorrente() {
echo “contenuto della pagina corrente”;
}
}
Questa è una normalissima classe. Abbiamo un libro, e la classe ci può fornire il titolo, ci può fornire l’autore e può voltare pagina. Infine, è anche in grado di stampare la pagina corrente sullo schermo.
C’è però un piccolo problema.
Ragionando sugli attori coinvolti nella gestione dell’oggetto Libro, chi potrebbero essere?
Possiamo facilmente pensare a due attori diversi qui: Gestione del libro (come il bibliotecario) e Meccanismo di presentazione dei dati (come il modo in cui vogliamo fornire il contenuto all’utente: su schermo, interfaccia utente grafica, interfaccia utente di solo testo, forse stampa) .
Abbiamo quindi due attori molto diversi che interagiscono con la classe.
In poche parole questa classe fa un mix tra:
questo può essere un problema perché viola il principio di responsabilità unica (SRP).
Come possiamo modificare, come possiamo migliorare questo codice per rispettare il principio di responsabilità unica ?
Dai un’occhiata al codice seguente:
class Libro {
function getTitolo() {
return “Oceano Mare”;
}
function getAutore() {
return “Alessandro Baricco”;
}
function turnPagina() {
// pagina successiva
}
function getPaginaCorrente() {
echo “contenuto della pagina corrente”;
}
}
interface Printer {
function printPage($page);
}
class StampaLibro implements Printer {
function stampaPagine($page) {
echo $page;
}
}
class HtmlPrinter implements Printer {
function stampaPagine($page) {
echo ‘<div style=”single-page”>’ . $page . ‘</div>’;
}
}
Questo esempio molto semplice mostra come separare la presentazione dalla logica aziendale, e nel rispetto dell’SRP offre grandi vantaggi nella flessibilità del nostro progetto.
Vediamo un altro esempio:
Un esempio simile a quello sopra è quando un oggetto può salvare e recuperare se stesso dalla presentazione.
class Libro {
function getTitolo() {
return “Oceano Mare”;
}
function getAutore() {
return “Alessandro Baricco”;
}
function turnPagina() {
// pagina successiva
}
function getPaginaCorrente() {
return “contenuto della pagina corrente”;
}
function salva() {
$nomefile = ‘/documenti/’. $this->getTitolo(). ‘ – ‘ . $this->getAutore();
file_put_contents($nomefile, serialize($this));
}
}
Come prima, anche qui possiamo identificare diversi attori come Gestione del libro (come il bibliotecario) e la Persistenza. Ogni volta che vogliamo cambiare il modo in cui passiamo da una pagina all’altra, dobbiamo modificare questa classe. Possiamo avere diversi motivi di cambiamento.
class Libro {
function getTitolo() {
return “Oceano Mare”;
}
function getAutore() {
return “Alessandro Baricco”;
}
function turnPagina() {
// pagina successiva
}
function getPaginaCorrente() {
return “contenuto della pagina corrente”;
}
}
class SimpleFilePersistence {
function salva(Libro $libro) {
$nomefile = ‘/documenti/’ . $libro->getTitolo() . ‘ – ‘ . $book->getAutore();
file_put_contents($nomefile, serialize($book));
}
}
Spostare l’operazione di persistenza in un’altra classe separerà chiaramente le responsabilità e saremo liberi di scambiare metodi di persistenza senza influire sulla nostra classe Libro. Ad esempio, l’implementazione di una classe DatabasePersistence sarebbe banale e la nostra logica aziendale costruita attorno alle operazioni con i libri non cambierà.
Continua leggendo il secondo principio Open/Closed —>
Alberta Innovates annuncia nuovi finanziamenti attraverso il programma Digital Innovation in Clean Energy (DICE). Sono disponibili 2,5 milioni di dollari in finanziamenti da…
Il wireless ottico potrebbe non avere più ostacoli. Studio del Politecnico di Milano con Scuola Superiore Sant’Anna di Pisa, e…
In un’epoca di grandi trasformazioni economiche e sociali emerge l’urgenza di ridisegnare nuovi modelli organizzativi delle aziende per guidare il…
EarlyBirds , la piattaforma australiana di Open Innovation e Industry Intelligence, si distingue come innovatore leader tra le startup australiane di…
Quale contributo effettivo può dare e sta già dando l’Intelligenza artificiale all’ambito delle cure e della sanità italiana? Questa è…
Lightspeed Commerce Inc. ha recentemente ospitato l'edizione 2023 del Lightspeed Summit, "Oxygen". Il vertice di tre giorni a Montreal ha riunito…
L'iniziativa "AI Ready" di Amazon, offre lezioni online per sviluppatori e altri professionisti tecnici, nonché per studenti delle scuole superiori…
L’intelligenza artificiale generativa è l’argomento di discussione tecnologico più caldo del 2023. Cos’è l’intelligenza artificiale generativa, come funziona e di…
Alcatel-Lucent Enterprise è orgogliosa di annunciare che la sua piattaforma di collaborazione, Rainbow™ by Alcatel-Lucent Enterprise ha ottenuto la Certificazione…
BYD ha centrato un risultato storico: sei milioni di veicoli a nuova energia usciti dalla catena di montaggio dello stabilimento…