in

dotNet Umbria [DNU]

Il primo User Group in Umbria sul mondo .Net

Lorenzo Maiorfi

Da Oggetti a Componenti a Servizi

I pochi che non dormivano giovedì 6 novembre all'hotel Giò, nonostante la nostra sessione fosse (non a caso) subito dopo la pausa caffè, si ricorderanno forse che si è accennato, molto velocemente in verità, allo sviluppo di applicazioni SOA (Service Oriented Applications) con WCF (Windows Communication Foundation).

Prima di addentrarci, con il prossimo post, in una demo che soddisferà almeno le prime curiosità in merito alla creazione di un servizio WCF, concedetemi un breve excursus storico che, sebbene potrà avere effetti irreversibili sulle vostre gonadi, cercherà di spiegare come e perché si è arrivati  a definire il modello di applicazione SOA dopo aver assistito ad almeno due "transizioni" analoghe negli anni 80 e 90.

Negli anni 80, quando i più vecchi di noi erano al massimo al massimo programmatori "in erba" (e si trattava di gramigna, come poi i fatti hanno dimostrato per molti di noi), il mitologico Turbo Pascal (su PC) o l'altrettanto leggendario "Compilatore C" di turno (Lattice e Aztec su Amiga, tanto per citarne due utilizzati dal sottoscritto) cominciavano ad essere affiancati da versioni "Object Oriented" degli stessi strumenti, ossia da compilatori in grado di gestire una nuova famiglia di linguaggi, nati in ambiente accademico (come Eiffel o SmallTalk) o direttamente nei laboratori delle grandi industrie (come il C++, nato dall'evoluzione del Simula di Stroustrup presso la AT&T). Il paradigma che caratterizzava tali linguaggi può essere sinteticamente esposto in termini di "adozione" di tre linee guida che suonano oggi tanto familiari quanto "vintage": ereditarietà, polimorfismo ed incapsulamento. In altri termini: possibilità di specializzare il comportamento di una classe a partire da un'altra classe "base", possibilità di lavorare indifferentemente con oggetti "base" o "derivati" lasciando agli oggetti stessi la responsabilità di un differente comportamento, possibilità di "nascondere" ai fruitori delle funzionalità di un oggetto i dettagli implementativi di quest'ultimo, implementando il cosiddetto modello "black box".

Negli anni 90 ci si rese però rapidamente conto che le possibilità di modularizzare (e quindi di riutilizzare) "elementi" software seppur progettati ed implementati secondo quanto previsto dall'OOP (Object Oriented Programming) erano di molto inferiori alle necessità di un mercato che stava ormai crescendo molto più velocemente degli strumenti che servivano per alimentarlo. Io mi ricordo ad esempio di un mastodontico (parliamo di decine di milioni di righe di codice) software per il pilotaggio di un dispositivo hardware industriale per il controllo di qualità di schede e componenti elettronici, interamente realizzato in C++/MFC (per piattaforma Win16, ossia Windows 3.1"), che a dispetto della assoluta aderenza ai più rigidi dettami dell'OOP, divenne assolutamente "blindato" ed "inestricabile" non appena il suo programmatore smise di lavorare per la ditta per cui l'aveva sviluppato. In sintesi, si intuì che una classe (o analogamente un insieme di classi che interagiscono) non era affatto un elemento isolato ed autonomo ai fini dell'integrazione delle funzionalità che questa offriva in un altro contesto rispetto a quello che la ospitava inizialmente. E poi i personal computer cominciavano a trovarsi sempre più spesso collegati tra loro in rete, letteralmente "scimmiottando" quello che per anni era stato il modello server/terminale tipico dei mainframe, senza però la possibilità di avere a disposizione, a differenza di questi ultimi, software in grado di sfruttare questa configurazione, se non per le funzionalità, ancora oggi molto sfruttate, di condivisione di documenti (funzionalità che per molti nostri clienti è ad oggi ancora l'unica comprensibile, anche dopo lunghe spiegazioni sulle possibili alternative.mah).

Quello che serviva nel corso degli anni 90 era uno standard in grado di realizzare questo isolamento indipendentemente dal contesto originale, ossia che permettesse in altri termini di riutilizzare ed integrare le funzionalità di quello che poi sarebbe stato chiamato un "componente" software: indipendenza dal linguaggio con cui era stato sviluppato (ossia integrabilità "binaria" e non a livello di sorgente), capacità di "descriversi" in maniera formale (in termini di metadati che esponessero, nel caso ad esempio di COM e CORBA, interfacce, classi, tipi enumerati e altra robbaccia del genere) e, preferibilmente, capacità (al limite accettando delle restrizioni di natura tecnologica) di avvalersi della presenza di più computer sulla stessa rete, magari mettendo a disposizione di più client una determinata funzionalità server, a volte per bilanciare e distribuire un carico computazionale, altre volte semplicemente per distribuire fisicamente una determinata "catena di responsabilità" (e con il mondo fisico l'uomo si è sempre confrontato più volentieri che con quello concettuale; prova ne è che molti indicano il monitor chiamandolo "il computer").

Arriviamo nei primi anni 2000, quando il proliferare di tecnologie e di sistemi operativi delle più disparate provenienze cominciano a far sentire il bisogno di un'integrazione tra applicazioni che sia più interoperabile (ossia indipendente appunto dai legami tecnologici) e più distribuita o, in altri termini, più adatta ad essere utilizzata "attraverso" Internet, oltre che su rete locale. SOA, attraverso la definizione del concetto di "servizio", ha dato una risposta a queste necessità, focalizzandosi sul rispetto di quattro "leggi" fondamentali (chiamati "tenet" nella letteratura, termine traducibile come "opinione", "principio", "dottrina" o "dogma"), liberamente interpretate da me come segue:

  1. Solo i confini di un servizio sono noti - Meno un client sa del servizio che invoca meglio è per entrambi, perché questo significherà minore accoppiamento tra le componenti che dialogano.
  2. I servizi sono autonomi - La dipendenza di un servizio da altri servizi o componenti devono essere "taciuti" ai client che lo consumano (che a loro volta devono rifiutarsi di utilizzare tali informazioni di dipendenza, se rese note). Analogamente, gli aspetti relativi al deployment o al versioning del servizio devono riguardare isolatamente solo il servizio interessato.
  3. I servizi devono esporre la propria "superficie pubblica" in termini di schemi e contratti, non di classi e interfacce - Questo li rende effettivamente interoperabili ed intrinsecamente cross-platform (questo è il tenet che preferisco, perché descrive secondo me in maniera più efficace la differenza tra applicazioni SOA e il resto del mondo).
  4. Le modalità di interazione con un servizio devono essere espressi mediante l'uso di policy - L'informazione che descrive la semantica del comportamento e dei requisiti di un servizio deve essere espressa in una forma più adatta a poter essere processata da un software che da un uomo. In questo modo, le possibilità di composizione di più servizi per ottenere funzionalità complesse potranno essere individuate e validate per mezzo di strumenti automatici.

Detto questo, possiamo dedurre che tutte le componenti logiche dei nostri software devono tendere fin da ora ad una implementazione necessariamente "a servizi"? Ovviamente no, e infatti nel lavoro di tutti i giorni vi accorgerete che, per ogni servizio che sviluppate, realizzerete almeno 10 componenti (sotto forma di assembly/class-library per noi .NET-tiani) e almeno 100 classi. Ma è anche vero che valutare regolarmente questa opportunità (come la tendenza ad esempio a "remotizzare" un data-layer, tanto per introdurre qualcosa che vedremo nei prossimi post) non potrà che migliorare  la predisposizione dei nostri progetti software ad una produzione fatta con criteri di qualità "industriali".

L'unica nota stonata riguarda secondo me l'accezione comune della parola "servizi", come nella frase: "scusi, dove sono i servizi?". C'è chi dice che l'ambiguità sia ulteriormente rafforzata dalla sigla WCF. Mah.

Only published comments... Nov 12 2008, 10:59 PM by maiorfi
Filed under: ,

Comments

 

pomarc said:

tutto molto bello e, al contrario di quanto si direbbe, anche robusto, alla prova dei fatti.

lìunica perplessità che mi rimane è sempre quella delle prestazioni: quando metti un sacco di layers (serializzatori, deserializzatori,ecc) e di metadati fra l'applicazione e i dati stessi, non è che per dirla con la saggezza popolare di un tempo, te costa più 'l brodo che la carne?

November 19, 2008 8:42 PM

About maiorfi

Sopravvivo dal 1971. Pigio per la prima volta i tasti di gomma del Sinclair Spectrum nel 1982, grazie all'acquisto presso la famosa G.B.C. di Temperini in Via Pellas da parte di mio padre. Entro in possesso di un Commodore Amiga 1000 in una anno che ricordo a fatica tra il 1986 e il 1987. Inizia il quegli anni la sperimentazione della frustrazione per la difficoltà di utilizzo delle API C per lo sviluppo di applicazioni integrate nel sistema operativo "Workbench" (ispirato al sistema Macintosh), un po' dovuta anche agli unici 2 compilatori presenti sul mercato: Aztec e Lattice, amichevoli come il software per la perforazione delle schede. La frustrazione veniva lenita parzialmente solo dalle ore trascorse giocando a KickOff di Dino Dini. Finalmente nei primi anni 90 approdo al mondo dei PC, con un 386sx assemblato della Olidata. In quegli anni il Turbo Pascal prima e il Turbo C dopo riescono a far sembrare lo sviluppo un esperienza tutto sommato divertente. Nel 1993 installo per la prima volta una copia (ovviamente abusiva) di Windows 3.1, con la quale inizio a sperimentare, grazie anche alla strepitosa libreria OWL di Borland integrata in "Borland C++" (primo ambiente object-oriented degno di questo nome), lo sviluppo di applicazioni desktop (anche se a quei tempi l'espressione "desktop" era sconosciuta e superflua, visto che tutte le applicazioni windows avevano di fatto un'interfaccia utente). Negli anni a seguire il mio interesse si focalizza su Visual C++, MFC, COM, ATL e su tutto quanto oramai inizia ad orbitare intorno alla piattaforma di sviluppo Microsoft "unmanaged", tanto che nel 1996 impronto la mia tesi di laurea, svolta con e per la società Eles di Todi, interamente su COM/OLE/ActiveX, ed in particolare sulle architetture per l'integrazione binaria dei componenti software. Credo che la tesi abbia effettivamente totalizzato 2 lettori, me e il mio revisore compresi. Dopo la laurea ed un anno di militare speso smanettando in Clipper presso il Nucleo Elaborazione Dati del Distretto Militare di Perugia (allora gestito dal famoso Colonnello Ansalone e dal famigerato Maresciallo Venditto), vengo assunto dalla (oramai defunta) Sinfor s.r.l. come lead (and only) developer. Ricordo tanti piccoli progetti Visual C++/MFC e VB6, qualcuno fatto male e qualcuno fatto peggio, ma complessivamente utili al loro scopo: far sì che io riuscissi a millantare un'esperienza ed una capacità che non avevo, contribuendo a farmi guadagnare uno stipendio che non meritavo. Nel 1999 lascio la Sinfor (anticipando il termine dei 2 anni del contratto di formazione!) per fondare la Innovactive Engineering s.r.l. insieme ai miei 3 soci (a dire il vero uno dei 3 soci è cambiato qualche tempo dopo, ma a chi importa?). Stentiamo un po' ad affrontare il seppur ricchissimo ed apertissimo mercato umbro ma riusciamo alla fine a consegnare il nostro primo prodotto: un gestionale per l'amministrazione di una società che opera nel campo assicurativo/assistenziale. Non è un successo né in termini economici né in termini di soddisfazione professionale (ad eccezione di quanto concerne la realizzazione del più lento e inaffidabile ORMapper della storia) ma da qualcosa bisognava pure cominciare. Negli anni intorno al 2001-2002 ci spostiamo all'interno della sede di Carsoli del Sole24Ore, coinvolti in qualità di consulenti per lo sviluppo con ASP/COM+/VB6/VC++. E' il periodo delle "vacche grasse" (dovuto alla famosa bolla speculativa della new economy), purtroppo mai più ripresentatosi negli anni successivi. Rientrati stabilmente a Perugia, dal 2003 in poi iniziamo un'attività più propriamente "aziendale" e cresciamo fino a raggiungere quota 7, grazie alla acquisizione delle nostre tre colonne portanti: Fabrizio, Valerio e Gianluca.

dotNet Umbria 2007-2008
Powered by Community Server (Commercial Edition), by Telligent Systems