Da un modello procedurale ad un modello ad oggetti – Seconda Parte

Leggi la prima parte dell’articolo…

Nel 1991 la Microsoft propose sul mercato quello che da li a poco divenne uno degli strumenti di sviluppo RAD più famosi al mondo: Visual Basic 1.0 per Windows (dato l’enorme successo nel 1992 fu sviluppata dalla casa di Redmond anche l’alterego per DOS dove l’interfaccia utilizzava i caratteri ASCII estesi per simulare l’apparenza di una interfaccia grafica).

Indubbiamente Visual Basic spopolò per tutta una serie di caratteristiche che pur avendo poco da offrire in termini di OOD al tempo risultavano estremamente interessanti:

  1. Programmazione event driven;
  2. Semplicità d’uso (non utilizza formalità di punteggiatura tipica di quasi tutti gli altri linguaggi);
  3. Ambiente di lavoro RAD per la realizzazione interfacce GUI anche complesse (complessità che risultava trasparente al programmatore);
  4. Pratico accesso alle basi dati tramite oggetti e widzard visuali.
  5. Creazione di controlli ActiveX con il linguaggio stesso.

Non a caso ho utilizzato l’espressione “al tempo risultavano estremamente interessanti”, e mi spiego:
Il mondo dell’informatica, e tutto ciò che ruota intorno ad essa, è passata di moda in moda.. di necessità in necessità.. infatti mentre un tempo il GURU di turno era il programmatore capace di spremere fino all’ultimo bit di un calcolatore sviluppando algoritmi estremamente performanti agli inizi degli anni novanta era la Rapidità di Sviluppo a catturare l’attenzione delle aziende, rapidità di sviluppo dove il RAD la faceva da padrone.

I linguaggi e gli ambienti e le metodologie di programmazione RAD, Visual Basic in primis ed a seguire tutti i suoi simili, per un lungo periodo hanno avuto il predominio su quelli che oggi definiamo più evoluti ma che al tempo erano comunque già presenti sul mercato e che sembravano non esserlo affatto, perché? Il saggio Design Patterns: Elements of Reusable Object-Oriented Software, della Gang of Four, vede la sua prima edizione nel 1995 eppure proprio nell’agosto di quell’anno Visual Basic 4.0 era uno dei linguaggi di programmazione più usati per lo sviluppo di applicativi gestionali di considerevole complessità. Come si spiega tutto ciò?

Perché il mercato non era pronto!
Le software house non avevano richieste abbastanza esigenti da giustificare l’investimento su tecnologie più costose in termini di risorse e di tempo. Oggi dove le applicazioni crescono in dimensioni e complessità in maniera esponenziale dall’oggi al domani, dovendo comunque garantire continuità di servizio, la richiesta di manutenibilità e di scalabilità sostituisce nella maggior parte dei casi quella di “rapidità di sviluppo”.
Potremmo dire a questo punto che il RAD ha concluso ormai il suo ciclo di vita (almeno in parte in quanto tutt’oggi la maggior parte degli ambienti di sviluppo offrono un’ottima integrazione di strumenti RAD e Controllo totale), che ha svolto a dovere e per parecchio tempo il suo compito.

Volendo analizzare le motivazioni per le quali tali tecnologie hanno raggiunto un limite abbastanza forte potremmo utilizzare tre concetti chiave per descrivere le principali problematiche dei software basati su ambienti RAD: fragilità, immobilità e viscosità.

Fragilità del software
Gli applicativi scritti con linguaggi come Visual Basic, almeno fino alla versione 6.0, generalente sono scritti secondo l’approccio conosciuto come “Spaghetti Code” .

E’ chiaro che in un codice sorgente scritto secondo lo stile dello spaghetti code, anche se di sole poche migliaia di righe di codice, sia estremamente complesso, pur avendo individuato con chiarezze le cause di eventuali malfunzionamenti, agire senza poter essere sicuri al 100% di non apportare danno in un altro punto dell’applicazione stessa.

Immobilità del software
Un importante fattore da considerare è che senza un’ottimizzazione puntuale delle responsabilità funzionali, cosa che risulta difficilmente ottenibile con la programmazione RAD, la riusabilità del codice e l’estendibilità dello stesso risulta più complessa e talvolta estremamente limitata.

Viscosità
Per via della fragilità del codice lo sviluppatore è costretto, nella maggior parte dei casi relativi ad azioni di manutenzione o adeguamento, a dover patchare il proprio codice e spesso in più punti per porre rimedio alle inaspettate conseguenze che le stesse patche portano in altri punti dell’applicazione e tutto ciò rende sempre più difficoltoso modificare parti di codice nel sorgente al passare del tempo.

Le motivazioni di ciò sono da ricondurre alla dipendenza che gli attori di un sistema (sia esso un macro o un micro sistema) hanno tra di loro. E’ indubbio che non esiste un sistema software nel quale non esistano dipendenze tra gli oggetti collaboratori ma con le tecniche di OOP si può tentare di disaccoppiare quanto più possibile i ruoli e le responsabilità di tali elementi mantenendo il giusto compromesso tra coesione ed accoppiamento senza finire però nel paradosso (come nel paradosso di Zenone “Achille e la Tartaruga” si potrebbe finire, nel tentativo estremo di disaccoppiamento, a non raggiungere mai il giusto compromesso tra Coesione ed Accoppiamento).

OOP ma allora è realmente “tutta salute”?
Indubbiamente la Object Oriented Programming (si presuppone che il lettore conosca i principi base della OOP) offre tutta una serie di vantaggi rispetto alla programmazione procedurale e quella RAD per risolvere per quanto possibile le problematiche precedentemente esposte, ma anche quest’ultima non è esente da insidie che possono passare inosservate.

Talvolta alcune feature offerte dalla OOP possano rivelarsi essere delle armi a doppio taglio. L’ereditarietà per esempio, uno dei tre pilastri cardine della programmazione ad oggetti, se mal controllata può portare anch’essa a situazioni scomode ed inaspettate (una qualunque classe specializzata per esempio può essere vista come una “classe fragile” in quanto dipendente dalle modifiche che trasparentemente un altro programmatore potrebbe apportare, magari a valle di una successiva e frettolosa refactory, semplicemente intervenendo sulla classe base compromettendo il funzionamento della classe specializzata). A tal proposito esistono una serie di solidi principi (S.O.L.I.D. principles) da seguire durante la progettazione per la produzione di “buon codice” orientato alla manutenibilità, estendibilità, scalabilità e stabilità.

Annunci

Da un modello procedurale ad un modello ad oggetti – Prima parte

La crescita esponenziale delle aziende e la conseguente necessità di automatizzare processi sempre più critici e complessi ha nel tempo portato gli sviluppatori ad abbandonare il modello di programmazione procedurale in favore di quello orientato agli oggetti che, seppur già presente fin dagli anni novanta, non aveva ottenuto al tempo un seguito cospicuo.

In quegli anni potremmo dire con simpatica che lo sviluppatore era portato a snobbare la Object Oriented Programming (OOP) poiché la complessità relativamente contenuta delle applicazioni prodotte in quel periodo non giustificava l’investimento, in termini di tempo e di risorse, che avrebbe richiesto l’utilizzo di tale modello di sviluppo. Tutto ciò sarà sicuramente opinabile da chi può permettersi di affrontare lo sviluppo software con un fare principalmente filosofico (Architetti, Ingegneri, ecc..) ma la questione è più spinosa di quanto potrebbe sembrare in quanto le aziende informatiche (purtroppo) non vivono di sola filosofia, ed ogni investimento in termini di tempo e risorse va giustificato con un rientro economico che a fine progetto faccia quadrare i bilanci aziendali.

Tutt’oggi molti professionisti ancora non riconoscono i benefici portati dall’utilizzo della OOP, spesso si sente dire o si legge su forums e blogs di carattere informatico:

  • OOP = Meno codice da scrivere
  • OOP = Meno manutenzione
  • OOP = Meno…

e poi nella pratica i conti non tornano.. ci si ritrova a fine progetto con un quantitativo maggiore di codice rispetto ad uno stesso progetto scritto con un approccio procedurale e con la stessa necessità di dover intervenire per manutenere ed, eventualmente su richiesta estendere il prodotto.

Ma allora dov’è il guadagno?
Innanzitutto sarebbe da chiarire una volta per tutte che, per quanto se ne dica, scrivere software secondo il modello della OOP “non vuol dire assolutamente scrivere meno codice, tutt’altro!” ma il sensibile aumento del numero di righe di codice di un progetto viene giustificato dalla necessità di disaccoppiare gli attori e le rispettive responsabilità che gli stessi assolvono in un processo indipendentemente da quanto complesso esso sia. Più codice quindi, ma necessario per separare e successivamente assegnare ruoli e funzionalità in un realtà dove gli stessi attori possono essere utilizzati per assolvere ad uno o più compiti ben definiti anche in sistemi e/o sottosistemi differenti (stiamo parlando di separazione delle responsabilità e successivo riutilizzo di codice esistente).

Per quanto riguarda la manutenzione: non esiste ad oggi alcuna applicazione che non necessiti di manutenzione. Secondo alcune statistiche, presenti in rete, si stima che la maggior parte degli sviluppatori siano impegnati per il 65-70%≈ della loro carriera professionale su interventi di manutenzione e sviluppi evolutivi piuttosto che di progettazione di software ex-novo e questo comporta la necessità di avere del codice facilmente mantenibile ed estendibile.

La naturale organizzazione del codice scritto secondo l’approccio Object Oriented Design (OOD) dovrebbe poter dare al programmatore la possibilità di modificare una determinata e molto più ristretta porzione di codice con la conseguenza di propagare tale modifica in tutti i punti del sistema in cui quella funzionalità viene utilizzata (Manutenibilità) .

Un uso intelligente dei concetti della OOP, soprattutto se accoppiato allo sviluppo basato su diversi layer applicativi, porta ad un altro vantaggio che diviene sempre più una necessità su applicativi di grandi dimensioni la: testabilità. La divisione delle competenze, infatti, semplifica il test puntuale delle funzionalità di un componente (anche in questo caso il termine semplifica non è da confondere con il termine velocizza, vedi il tempo che portano via gli unit test). In generale infatti (lo vedremo più avanti) le classi di un Object Model dovrebbero essere, passatemi il termine, quanto più striminzite (specifiche) possibile sia per una questione di precisa definizione del ruolo degli oggetti nel sistema sia per aumentare la riusabilità e la testabilità degli stessi.

Leggi la seconda parte dell’articolo…