Se hai bisogno urgente del nostro intervento puoi contattarci al numero 370 148 9430
RENOR & Partners è una società di consulenza d'impresa con alti standard qualitativi e con i prezzi più bassi del mercato.
RENOR & Partners S.r.l.
Via Cicerone, 15 - Ariccia (RM)
info@renor.it
Ci sono molte persone a cui piacerebbe imparare a programmare per il Web ma non sanno da dove partire. Alcuni si affidano ai libri, altri a corsi online ma quello che mi capita di sentire è sempre la stessa frase: “ho iniziato a studiare un linguaggio di Backend su un corso online ma la programmazione a oggetti è troppo difficile”.
Effettivamente, quasi tutti i libri di testo che ho letto nella vita sul paradigma OOP complicano un concetto che io definirei come la naturale evoluzione della programmazione procedurale e funzionale.
Perché a mio avviso, tutti i libri e tutti i corsi vogliono per forza portare degli esempi paragonando la programmazione a oggetti alla vita reale. In realtà, chi ha imparato a programmare in modo procedurale, fino a quel momento ha visto unicamente esempi nel mondo dello sviluppo: cos’è una variabile, cos’è un array, come si cicla un array, come scrivere una condizione, come fare un diagramma di flusso, come scrivere una funzione; pertanto non ritengo siano abituati a cogliere degli esempi nel mondo reale in questa fase, ma dopo aver compreso cosa implica il paradigma a oggetti in ambito informatico. È un metodo di pensare al codice che diviene quasi necessario quando si passa dal piccolo progetto ad un progetto più grande o che dovrà essere manutenuto ed esteso nel futuro. Solo quando si avranno chiare queste basi, sarà possibile portare degli esempi nella vita reale.
Complicando in questo modo le cose i nuovi “adepti” del mondo della programmazione si scoraggiano. Il risultato è che alcuni di loro abbandonano l’interesse per la programmazione, altri restano fermi alla programmazione procedurale o funzionale senza sapere che da quella funzionale all’OOP il passo è veramente cortissimo.
Il paradigma a oggetti non è solo un “diverso modo di organizzare il codice” ma fornisce delle regole e un modus operandi tale per cui chi dovrà mettere mano su codice sviluppato da qualcun altro lo potrà fare senza spaccarsi per troppo tempo la testa alla ricerca di “cosa fa cosa”.
Inoltre nella programmazione a oggetti non bisognerebbe mai sottovalutare la potenza dell’UML.
In sostanza la programmazione a oggetti fornisce tutte le best practice che un buon sviluppatore dovrebbe mettere in atto per rendere il codice facilmente leggibile, strutturato come si deve, facilmente manutenibile e scalabile.
Non solo il paradigma ad oggetti incanala lo sviluppatore in un’ottica di sviluppo virtuosa, ma permette anche di usufruire di tutta una serie di strumenti già pronti e facilmente integrabili. Git Hub pullula di Classi già implementate e facilmente integrabili, per lo più tramite Composer, che danno modo di risparmiare tantissimo tempo in fase di sviluppo. Esistono classi praticamente per qualsiasi cosa: la generazione di un PDF, l’invio delle eMail, l’integrazione con le API di eBay e Amazon per l’automazione di progetti eCommerce, la generazione di QR Code e Bar Code, il confronto tra immagini, il ridimensionamento di immagini, la compressione, ecc. ecc.
Questi strumenti sono sempre scritti con paradigma orientato agli oggetti e per sfruttarli e, in taluni casi, riadattarli alle nostre necessità, è necessario conoscere questa filosofia di scrittura del codice.
Svariate volte mi è capitato di rimettere mano su progetti scritti in ottica procedurale… Ho dovuto perdere letteralmente giorni solo per capire in che modo fosse organizzato il codice, dovendo leggermi file di decine di migliaia di righe di codice. Diviene molto difficile modificare anche una banalissima funzione perché è necessario andare alla ricerca, nelle migliaia di righe, di quella porzione di codice che si occupa di mettere in atto quell’azione, stare lì ore a debuggare… Un inferno.
In progetti orientati agli oggetti la cosa sarebbe stata di una banalità disarmante!
Sono minuti che giriamo intorno all’argomento ma ancora non ne abbiamo dato una definizione che sia facilmente comprensibile.
Per imparare a programmare a oggetti non c’è altra strada che imparare prima la programmazione procedurale, poi quella funzionale ed in fine quella ad oggetti, perché una è la naturale evoluzione dell’altra.
Programmare significa saper analizzare un grosso problema, scomporlo in problemi più piccoli e trovare delle soluzioni a ciascuno di questi piccoli problemi per poi ricomporne i pezzi e risolvere il problema principale. Per fare questo ci si avvale di funzioni.
Il passaggio dalla programmazione procedurale alla funzionale è abbastanza semplice: le funzioni sono dei raccoglitori di codice procedurale specializzate nella risoluzione di un piccolo problema. Es. scrivere un programma che si occupi di cercare una stringa all’interno di un’altra stringa; se la trova restituire esito positivo altrimenti negativo. Questo programma posso scriverlo all’interno di una funzione. Le funzioni nella programmazione sono esattamente come le funzioni matematiche: si passano una o più variabili in ingresso dopodiché la funzione le elabora e restituisce un risultato, o se vogliamo dirlo in un modo più correttamente matematico. Data una funzione per ogni elemento del dominio della funzione ne corrisponde uno nel codominio. Nella programmazione le funzioni hanno dei parametri di ingresso che vengono elaborati e viene restituito un valore di uscita.
In questo modo si risolve un piccolo problema derivato dal problema principale e posso continuare a risolvere piccoli problemi con altre funzioni per poi metterle assieme e risolvere il problema principale.
All’atto in cui ho finito di preparare tutte queste funzioni, posso valutare quali siano risolutive di una classe di problemi. Poniamo ad esempio di dover calcolare il totale di n fatture ancora non pagate di un’azienda e di dover successivamente inviare questo totale tramite mail al cliente che ce le deve pagare.
Primo problema: prendere tutti i dati da un database
Secondo problema: esaminare le fatture
Terzo problema: sommare le fatture non pagate
Quarto problema: inviare il totale tramite email al cliente per il pagamento
Primo problema:
Secondo problema:
Terzo problema:
Quarto problema:
Come è possibile vedere abbiamo risolto il problema principale “Calcolare il totale di n fatture ancora non pagate di un’azienda e inviare il totale tramite mail al cliente per il pagamento” utilizzando delle funzioni che risolvono delle sottocategorie del problema principale semplicemente mettendole assieme in modo ordinato.
Si devono scindere gli attori in gioco per comprendere a quali Classi di problemi questi appartengano… Ad esempio la Connessione al database è una Classe di problemi che differisce da quella delle fatture, pertanto fatture potrebbe essere un’altra classe di problemi, così come l’invio della Mail è ulteriormente un’altra Classe di problema rispetto alla connessione al database e all’invio delle Mail.
Abbiamo quindi identificato delle Classi che altro non sono che raccoglitori di funzioni, le quali, al loro interno, assumono il nome di “Metodi”.
Per questo problema avremo la Classe Connection per la connessione al database, la Classe Fatture per tutte le funzioni che soddisfano il requisito di risolvere i sottoproblemi relativi alle fatture e la Classe Mail che contiene i metodi relativi all’invio della posta elettronica. Ogni classe raccoglie i metodi (o se vogliamo ancora utilizzare il termine “funzioni”) relativi alla loro classe risolutiva di problemi.
L’oggetto che viene istanziato (creato) dalla Classe, altro non è che un contenitore dei metodi che implementa la Classe (e di proprietà che altro non sono che le variabili in gioco all’interno della Classe) che possono essere utilizzati per risolvere il problema principale.
Naturalmente questo è uno degli approcci, ma ognuno potrebbe trarre le sue conclusioni sugli attori come meglio crede che sia giusto e non ci sarebbe una versione corretta e una errata. Ad esempio uno sviluppatore avrebbe potuto integrare i metodi per l’invio delle Mail all’interno della Classe delle fatture visto che si riferiscono all’invio di posta elettronica contenente dati di fatturazione. Sarebbe stato un ragionamento che io non condivido ma non scorretto.
Semplice! Perché se domani mi chiedessero di integrare anche la media del totale delle fatture, tutto quello che dovrò fare sarà aggiungere un metodo alla Classe Fatture che si occupi di calcolare il valore medio delle fatture di quel Cliente, senza dover stare a ricercare in un file unico la parte di codice che si occupa della fattura.
La cosa importante da fare quando si programma a oggetti è dunque quella di capire quali sono i problemi in gioco, strutturare un diagramma che si chiama UML e raccogliere dentro ogni classe tutti i metodi risolutivi dei microproblemi adibiti a quella Classe di problemi. Una volta che il discorso filerà liscio su carta si potrà iniziare a scrivere i commenti (una best practice che puoi leggere in questo articolo) e per ultimo stendere il codice. L’operazione diventerà veramente banale perché il grosso del lavoro è stato fatto prima con carta e penna.
Naturalmente questo non è un corso di programmazione OOP, le regole della programmazione a oggetti sono molte e vanno comprese integralmente: ereditarietà di una classe figlia, classi astratte, interfacce, traits, ecc., ma una volta entrati nell’ottica di “Cosa è una Classe” e “Perché passare alla programmazione a oggetti” si tratterà solo di studiare queste regole ed applicarle programmando e continuando a programmare sempre di più. Ti accorgerai, una volta compresa, della facilità concettuale e di come torni veramente utile per organizzare il codice secondo regole facilmente interpretabili anche da un’altra persona che dovrà rimettere mano al tuo codice.
Come hai visto la programmazione a oggetti è molto più semplice di quello che si dice, non è assolutamente un concetto astratto e terribile che crea blocchi a chi vuole imparare a programmare… Tutto sta a prenderla nel modo giusto senza stare lì a parlare di Case, Automobili e Moto (questo è l’esempio più citato), Palazzi, Ricette e chi più ne ha più ne metta.