giovedì 19 luglio 2007

Narciso Yepes e la chiave del quindici



Narciso Yepes, diventato noto al grande pubblico per aver suonato con la sua chitarra classica il pezzo centrale della colonna sonora di Giochi Proibiti, soleva ricordare di aver imparato le basi da un grande maestro che, però, non era un chitarrista, ma un pianista, Vincente Asencio.
Asencio gli faceva sentire al pianoforte cosa doveva suonare. Quando lui gli diceva che non era possibile ripeterlo con la chitarra, Asencio gli rispondeva che, se non poteva fare nulla con quello strumento, avrebbe fatto meglio a cambiarlo. Così Yepes studiò nuove tecniche, riuscì a ripetere gli esercizi proposti, diventò uno dei massimi virtuosi del mondo, arrivando a tenere concerti con la chitarra estesa da 6 a 10 corde dal liutaio Ramirez secondo i suoi suggerimenti.

Questo aneddoto deve essere molto noto perchè è facile incontrare persone che si immedesimano in Yepes.
Qualche virtuoso esiste anche, ma non è raro vedere usare strumenti sbagliati nei modi e momenti sbagliati, con tentativi di estensione ed estremizzazione, ma senza prima averne approfondito i limiti.

Come chi cerca di usare la chiave del quindici su un bullone da 12 o un martello per svitare un dado, talvolta i risultati possono non essere quelli sperati (ben vengano le eccezioni, ovviamente!).

In questo senso, uno degli esempi più comuni nell'informatica è quello di considerare l'XML come ingrediente fondamentale e irrinunciabile. Non importa per cosa, l'importante è usarlo.



Qualcuno di voi sarà anche saltato sulla sedia, ma l'XML, che mi conosce, sa che non deve prendersela, dal momento che gli è ben noto che lo uso con quotidiana assiduità.

Ci frequentiamo almeno dal 1996 1998 e non se la prende se continuo a sottolineare l'ovvio, ovvero che continuare ad evidenziare che è uno standard è utile quanto confondere Java con la sua sintassi di base.

Perchè di standard, nell'XML c'è solo quello: la sintassi.
La semantica bisogna sempre implementarla, come credo sia ben noto.

Dtd o Xml Schema servono per rafforzare la sintassi, anche se a diversi livelli, ma per usare quei dati incastrati tra un tag e l'altro, serve sempre un programmatore.

Spero, infatti, sia a tutti palese che, anche usando l'xsl(t), anche se dichiarativamente, anche se tra mille limiti e salti tripli per fare cose banali in altri ambienti, stiamo sempre scrivendo regole, filtri, semplici trasformazioni, qualche controllo, ovvero: programmando.
A questo proposito, giusto per fare un esempio che mi piace sempre sottolineare, progettare una architettura multilivello, separando bene la presentation dalle business rules e poi decidere coscientemente di buttare la possibilità di usare competenze e strumenti specifici del front-end (esperti di html e javascript, grafici che costano tipicamente meno di programmatori e strumenti WYSIWYG che permettono un disegno rapido) usando xml ed xslt per generare il layout e manutenerlo è veramente un peccato.

Senza considerare che il carico (sia in termini di heap che di cpu) per il parsing ed applicazione delle regole rischia spesso di essere significativo rispetto all'utilizzo di altre tecniche (magari compilate, come una buona vecchia JSP).

Comunque, se il fatto che si debba fornire la semantica programmandola e che sia ragionevolmente sconsigliato sfruttare l'XML come base di un template engine/layout manager fossero gli unici problemi non avrei scritto questo articolo. Si tratterebbe di peccati veniali.

Ciò che mi preme sottolineare è la tendenza all'esagerazione nell'utilizzo di questo seppur utile e versatile strumento.

Per esempio, come strumento per memorizzare dati, in ambiti complessi.
Per fare un esempio pratico: non mi direte che non avete mai visto un CMS xml-based, vero?
Io ho anche visto citare questa feature come elemento distintivo di certi sistemi, laddove il pubblico (e talvolta l'oratore) non era in grado di cogliere che:
  • la stessa flessibilità descrittiva si può ottenere anche con un bel database, con la stessa facilità (i casi cui mi riferisco riguardano progetti di una certa dimensione, dove non è neppure messo in dubbio che esistano altre funzionalità per cui è necessario ed irrinunciabile un bel RDBMS)
  • ricercare valori di tag in XML salvati sul filesystem non è operazione propriamente performante: per risolvere questo tipo di problema è solitamente necessario ricorrere ad altre strutture architetturali (es: estrazione preventiva dei metadati e loro indicizzazione - non di rado appoggiandosi ad un RDBMS, o, talvolta, addirittura riscrivendo da capo funzionalità che sono oramai consolidate e super-performanti da anni in quei sistemi -, cache multilivello, etc. etc.)
  • come sopra citato, per la famosa estensibilità garantita dall'XML bisogna programmare: lo so bene che non è sempre necessario farlo all'aggiunta di un nuovo campo in un CMS, - a patto di rimanere entro certi limiti, beninteso -, ma per quello che mi è capitato di verificare nella pratica o si rientra in situazioni quasi banali e gestibili anche più facilmente su DB, o si devono comunque battere quelle costose 10 benedette dita sui tasti.
Un altro caso tipico è la generalizzazione "hand made", tipicamente in fase di configurazione di un sistema: il costo dell'interprete vale il vantaggio della generalizzazione? ci lamentiamo della reflection e aggiungiamo un intero interprete? anzi, a volte aggiungiamo pure la reflection come modalità di costruzione di oggetti generalizzati nell'xml, da far richiamare in una Factory e/o in un Singleton allo startup?

Non so se vi siete resi conto delle risorse richieste per l'elaborazione, soprattutto usando DOM - a proposito, su .NET c'è il parser SAX, o si va solo di DOM? io non sono riuscito a trovarlo...:
  • tempi per il parsing (SAX e DOM)
  • tempi per costruirsi gli oggetti (automaticamente nel DOM, spesso 'a mano', più leggeri, con parser SAX based)
  • heap che si riempie facilmente (che so: mai provato un out of memory in Java per import dati massivo via XML, passando da un parser DOM?)
Vediamo di esaminare anche i vantaggi, per capire dove ha senso usarlo, almeno IMHO (in italiano verrebbe IMMP, fa schifo, spero lo capiate, senza considerare che la 'M' di 'Modesto' poco mi si addice):
  • la standardizzazione di questa sintassi aiuta nell'avere dei parser e ci sono molti casi in cui un parser bell'e pronto è proprio ciò che ha ordinato il dottore (per esempio, per estendere un linguaggio con tag libraries/web controls)
  • esistono casi - rari e semplici, purtroppo - in cui una bella trasformazione xslt è comunque decisamente più semplice da scrivere di un programma (es.: per creare dei pdf - xsl-fo - magari a partire da un html: bisogna lavorare un po' sull'xsl, ma fare uno spider che si naviga il sito in un certo ordine e ne produce un libercolo in pdf è alla portata - mi dicono che il Mac lo faccia di default, è vero? per PC, tra gli open source, di decente ho trovato solo HTMLDOC, anche se non si naviga da solo gli url delle pagine - ; ancora: nel passaggio di dati da un sistema ad un altro, spesso è utile trasformare un XML proveniente dall'esterno in un XML in formato già gestito dal nostro sistema, per rielaborarlo senza ulteriori sviluppi e un filtro di questo tipo scritto in xsl è la morte sua).
  • laddove le descrizioni dei dati (dai tracciati record alle immagini SVG) sono complesse e questi dati devono essere scambiati tra sistemi o essere alla base di programmi per cui ha poco senso aggiungere un database, l'XML è decisamente più adatto di altri formalismi (es, il vecchio EDI), essendo potenzialmente molto più ricco, espressivo e permettendo di condividere e validare la sintassi in modo più mirato.
Proviamo un piccolo riassunto di casi pratici, relativo ai punti su cui solitamente mi sento o non mi sento di usarlo:

NO
  • in generale, per evitare di gestire documenti su DB (es. del CMS) o come modalità di estensione dei campi nel database: non posso fare ricerche e join in modo performante, devo parsare ed intepretare il mio file ogni volta (a meno di pre-parsing ed indicizzazioni di cui si è già parlato - ma come gestite l'indicizzazione? la delegate al DB o la gestite a mano? vi siete ricordati di indicizzare tutti gli elementi e lasciare il testo ad un motore di ricerca full-text? i valori dei tag sono codificati o si tratta di stringhe, pure inserite manualmente?). Indizi del fatto che non va così bene: a parte i tempi di sviluppo di eventuali indicizzazioni e recupero dei dati, dovete usare uno o più livelli di cache e, in caso di miss, la relativa interpretazione porta via 2 ordini di grandezza o più del tempo necessario per recuperare il dato pre-interpretato dalla cache (2 ordini di grandezza è troppo: sarebbe bene che le cache correggano 1 ordine di grandezza, altrimenti è indice di seri problemi nell'operazione fuori cache: se non ci sono alternative, fate bene ad usarle, ma se le alternative ve le siete precluse da soli...).
  • XML per memorizzare oggetti:
    • non vi piaceva la serializzazione nativa di Java e davvero pensate che questa sia più veloce? provate a fare un profiling e non dimenticate la gestione del versioning delle classi).
    • la versione in xml potete passarla come risultato di un Web Service? in linea di principio va bene, ma usare qualcosa di già pronto - es: SOAP - e passare direttamente l'oggetto era troppo standard?
    • vi serve per estendere il DB? v. sopra.
    • Volete farvi da soli il vostro OODBMS? Forse è il caso di considerare qualcosa di già pronto (ma non prima di aver considerato che, comunque, si tratta di tecnologie ancora molto discusse e, come minimo, un po' immature)
  • XML alla base dello strato di presentation: in questo caso si ha la perdita di performance per interpretazione vs. compilazione di cui ho già parlato; vi sentite più flessibili nel definire le zone del sito e le pagine? avete contato bene il costo di manutenzione, la flessibilità e quanto vi è costato realizzare un Template Manager di quel tipo, fuori da ogni standard?.
NI [situazioni da pesare, caso per caso: personalmente non ho ancora trovato una regola]
  • XML come file di configurazione [rischio: overdesign (in molti casi basta un file di properties) - possibile vantaggio: flessibilità ed espressività (soprattutto quando servono diversi livelli di approfondimento)]
  • XML come metadato (es.: base per Xlink o, più in generale, per il Web semantico ed RDF) [rischio: performance povere per mancanza indicizzazione o indicizzazione manuale, difficoltà nell'eseguire query, difficoltà di documentazione - possibile vantaggio: distribuibilità, laddove le performance non sono importanti, maggiore disponibilità di ambienti per eseguire parsing xml rispetto ad installare un RDBMS
SI
  • XML per trasferire dati ed aumentare l'interoperabilità tra applicazioni (in tanti sostengono che sia nato per questo ;) ):

    • Web Services
    • base per Web 2.0, a partire da RSS/ATOM
    • come sorgente dati remota (in particolare come RE in REST)
    • in generale, per disaccoppiare i sistemi

  • XML come base per il formato di memorizzazione di una applicazione standalone laddove usare un DB sarebbe un po' eccessivo (es: state scrivendo Open Office e decidete di salvare in dati in locale, in formato portabile, aperto e facilmente trasformabile; i vostri dati, in questo caso, tipicamente non richiedono ricerche cross tra i diversi xml, al più solo all'interno di uno stesso documento
  • come base per definire nuovi linguaggi che richiedano interpretazione ed esecuzione: Apache Ant docet e certamente ha senso, dal momento che, in questi casi, comunque bisogna scrivere un parser ed un interprete e trovarsi con metà del lavoro fatto (e anche bene) non può che far piacere; altri esempi sono linguaggi che descrivono regole inferenziali (es: XML Rule Language in JBoss Rules - ex. Drools - ma, attenzione, nel manuale anche loro stessi dicono: 'There are several scenarios that XML is desirable. However, we recommend that it is not a default choice ...') o linguaggi che descrivono comportamenti che necessitano di un controllo di esecuzione (es: per definire dei workflow o - con un salto di fantasia di un centimetro e mezzo - come base per il governo di un ESB, come nel caso di BPEL).
Avete altri esempi? Avete elenchi di altri metodi architetturali usati malamente?
Non siete d'accordo su quanto ho detto dell'XML e ne volete parlare?
Beh, provate a darmi un feedback, prometto che se ne ho voglia ci penso su...

Bye
    Depa
P.S.: poi magari salta fuori che avete ragione voi
P.P.S.: per quanto improbabile, intendo... ;)

6 commenti:

Anonimo ha detto...

Eh, noi, nel nostro framework utilizziamo xml per la configurazione dei services e ultimamente anche per la gui description. Quest'ultima cosa ce la siamo inventata per poter essere completamente flessibili (cambia la corporate styleguide, si passa da un thin ad un rich client, i possibili use case sono molteplici) e anche per rendere possibile l'implementazione di un gui decente, ergonomico, compatibile con la styleguide e così via, anche da gente che non è molto pratica di html, javascript, ajax, e così via). Ora abbiamo un problema di performance e ci stiamo attrezzando per fare un profiling e trovare la causa. E la lettura di questo post sembra confermare i miei timori...

Depa ha detto...

Isa, di fatto stai riportando due delle casistiche tipiche che avevo citato, da quanto capisco:
- configurazione (dei services dici: non capisco se si tratti di WS o di servizi per gli utenti - intendi dire che gestite così anche le autorizzazioni e le associazioni servizi/utenti? Non sarebbe strano, pensiamo al primo container di servlet che ci viene in mente...). Siamo in uno dei casi in cui sono normalmente incerto tra l'usare xml ed il DB. Personalmente, solitamente scelgo il DB (non si era capito?) e cerco di costruirci su una serie di form di amministrazione il più complete possibili. La flessibilità delle configurazioni per utente o ruolo, soprattutto laddove iniziano a crescere significativamente gli utenti (che so, intranet operativa e qualche migliaio di utenti...) preferisco gestirle su DB, anche per motivi di carico...
- GUI description (aka presentation layer aka V in MVC aka ...): nel 1998 mi hanno fatto gestire un framework che aveva XML alla base del presentation layer. Il framework era stato progettato da un professionista di grande livello ed esperienza dal quale ho imparato un sacco di cose. Prima che si potessero usare servlet e JSP per un MVC model 2, lui aveva realizzato lo stesso principio, usando l'xml al posto della JSP. Il disegno era avanzatissimo e potenzialmente flessibilissimo. Anzi, aveva introdotto anche altri principi (un form manager) che ancora oggi si ritrovano alla base del disegno di JSF o di ASP.NET.
Purtroppo il layout manager soffriva proprio di performance (causa parsing, heap etc. etc. - il parsing era in DOM, ma, vista la complessità di quello che doveva fare, anche in SAX sarebbe stato lo stesso, avremmo dovuto costruirci un nostro model e tanto valeva usare quello già pronto).

Magari non ti servono, ma mi impiccio degli affari tuoi e mi permetto di scrivere alcuni possibili suggerimenti (magari non applicabili alla vostra casistica, ma si fa per riempire pagine bianche e generare altre reazioni e interesse, come ben sai...):
- se siete in java e potete ancora farlo, passate a servlet e jsp, come da blueprint SUN sopra citato: potete fare delle jsp semplici da usare e flessibili tanto quanto (e più) di quello che fate con xml (avrò fatto quello che descrivi decine di volte in questo modo, compresa la gestione di M-Site e la possibilità di far disegnare le pagine a mo' di portlet, dinamicamente, via interfaccia Web ad un utente che non sa nulla di programmazione, in un progetto di un CMS)
- se vi siete spinti troppo in là, una cache è la soluzione meno invasiva (dando per scontato che il problema non stia nella realizzazione, ma solo nel fatto che dovete interpretare ogni volta la pagina): immagino tu conosca EHCache: potrebbe essere utile sparargli dentro gli xml parsati e cercarli là prima di rielaborarli (il massimo sarebbe poter salvare direttamente la pagina già elaborata, prima di mandarla in output).
- nella soluzione del punto precedente esiste un potenziale problema: se le vostre pagine presentano personalizzazioni user-dependent, rischiate solo di riempire la cache di pagine che usate solo da un utente, che magari ci passa solo una volta (risultato: occupazione inutile di ram, continui miss, etc. etc.). Potrebbe essere utile riuscire a spezzare la pagina in tante parti e cachare gli html prodotti separatamente, se fosse possibile riconoscerli. Anche in questo caso sarebbe stato meglio avere una JSP, perchè con un xml sarete probabilmente costretti a creare, se già non avete previsto qualcosa di simile, una sovrastruttura che vi permetta di individuare queste sotto-parti, mentre con una JSP si riesce a creare una tag library che permette di gestire in cache sotto-insiemi della pagina (e la compilazione non è mai male, per quando non si trova la pagina in cache). Relativamente facile da fare anche con l'EHCache sopra citato, ma ci sono librerie che lo fanno di mestiere, tipo OSCache. Si può fare qualcosa di simile anche partendo da un layout definito in xml, ma è chiaramente un po' più complesso.

A disposizione per approfondimenti - anche via mail, se preferisci - (ma non contare troppo sui tempi di risposta ;) )

Anonimo ha detto...

Alcuni appunti:

1. Il linguaggio di presentazione standard per il Web oggi è XHTML, che è XML, quindi anche il tuo Web designer, magari senza saperlo, o l'autore di pagine JSP, usano XML.

2. RDF non ha nulla a che vedere con XML.

3. "come base per definire nuovi linguaggi che richiedano interpretazione ed esecuzione: Apache Ant docet e certamente ha senso": NO, grazie! Apache Ant è di fatto un linguaggio di scripting e usare XML per un linguaggio di scripting è un abominio. Come riconosce il suo stesso autore, Duncan Davidson (il link era http://x180.net/Articles/Java/AntAndXML.html ma ora quella URL non esiste più), usare XML per Ant è stato un errore.

4. La differenza di efficienza tra SAX e DOM nel parsing può essere di alcuni ordini di grandezza, quantomeno come occupazione di memoria. Se vuoi mantenere l'efficienza di SAX e la flessibilità di DOM, puoi sempre usare uno streaming pull parser come StAX.

5. There is no silver bullet ;)

Depa ha detto...

Ugo, ti rispondo per punti
1. Verissimo, ma spero che la casistica a cui mi riferivo sia chiara: xml e xsl o layout manager ad hoc vs. (X)HTML generato in modo un po' più standard, seguendo linee guida note e, possibilmente, con codice compilato.

XHTML è certamente XML, ma recuperiamo "le competenze e gli strumenti specifici del front-end" che erano quelli che mi preoccupava buttare. XHTML viene correttamente letto e interpretato sia dal browser che da strumenti WYSIWYG, a differenza di un XML scritto allo scopo, che diventa un nuovo linguaggio (non standard) da imparare, da gestire più o meno manualmente e che rischia di essere inefficiente a meno di ulteriori sovrastrutture architetturali.

2. Come? E' lo stesso RDF di cui parlo io, ovvero quello relativo a queste specifiche del W3C? ;)

RDF, di per sè, non è XML, ma mi risulta che abbia parecchio a che vedere con l'XML, che usa a mani basse come base per la semantica, per descrivere i metadati (ovvero proprio per il motivo per cui lo citavo), rendendosi flessibile e riutilizzabile in diversi ambiti:
- la sintassi estesa di RDF si basa su XML, attraverso una serie di tag (con radice rdf:RDF)
- in particolare io non conosco sintassi non XML per descrivere proprietà strutturate (s:...) e tipizzazioni (rdf:type e relativa URI di definizione del tipo). Non escludo che questo sia un mio limite dovuto alle mie fonti di partenza, però...
- contenitori (rdf:_1, rdf:_2, ...)
- utilizzo di RDF Schema per definire classi e proprietà (relazioni, vincoli, etc. etc.)
- OWL stesso mi risulta essere una estensione di RDF/RDF Schema, basato sulla loro sintassi estesa in XML
- ...

3. Riconosco che, per i linguaggi di scripting l'xml sia un po' scomodo (bisogna scrivere troppo), ma quello che volevo mettere in luce era il fatto che si può riusare un parser e le basi per costruire un interprete. Utile se hai poco tempo, soprattutto. Andrò alla ricerca di quel link che mi suggerisci in qualche archivio, perchè sono curioso di conoscere altri motivi per cui Davidson ritenga un errore la scelta dell'XML, oltre alla scomodità di scrittura.

4. Assolutamente d'accordo riguardo all'efficienza dei due approcci (non ho avuto modo di provare StAX, andrò a cercarlo per giocarci, grazie per la segnalazione): la mia perplessità (forte) riguarda l'uso efficiente dell'XML per scambiare (importare/esportare) grosse quantità di dati e mi permane un dubbio (decisamente più leggero) nell'utilizzo per le configurazioni di comportamenti dinamici nelle architetture software.

5. Totalmente d'accordo: è, di fatto, un riassunto ed una parafrasi del titolo e introduzione del mio post. Sono stato troppo banale? ;)

Anonimo ha detto...

RDF non dipende da XML. E' possibile rappresentare un grafo RDF come documento XML (RDF/XML) ma questa è solo una rappresentazione. Tra l'altro è una rappresentazione che la maggior parte di esperti di SemWeb con cui ho parlato tende a deprecare, favorendo N3.

Di fatto, un modello RDF è un grafo i cui nodi sono URI o valori letterali e i cui archi sono URI. In tutto questo non c'è un briciolo di XML. Quelli che tu chiami "contenitori", se ho capito bene, solo solo bNodes, o nodi anonimi, che non hanno una URI ma un identificatore, diciamo così, temporaneo.

A sua volta, uno schema RDF è semplicemente un modello RDF che descrive un insieme di possibili modelli RDF.

Depa ha detto...

Ugo, e quando mai ho detto che RDF 'dipende' dall'XML? Ho solo evidenziato che i due sono parecchio legati. RDF è il modello, RDF/XML una delle sue View.

Comunque, alcuni estratti dal W3C:
This Primer is designed to provide the reader with the basic knowledge required to effectively use RDF. It introduces the basic concepts of RDF and describes its XML syntax [...] RDF also provides an XML-based syntax (called RDF/XML) for recording and exchanging these graphs [...] To represent RDF statements in a machine-processable way, RDF uses the Extensible Markup Language [XML].

Per la Wikipedia RDF è una particolare applicazione XML e chiama canonica la rappresentazione in XML.

Il W3C, nella pagina specifica dell'RDF dice che le specifiche di RDF sono build on URI and XML technologies.

Anch'io ho letto delle varie preferenze per N3 (ci credo, è molto più leggera, meno verbosa, a parità di espressività), ma nei link del Web Semantico del W3C che ho fornito nel precedente commento i primi 2 sono, rispettivamente, su RDF/XML e RDF Schema (il che non rende preferibile RDF/XML rispetto ad N3, ma il parsing è gratis, il Web Semantico si fonda su XML - dalle specifiche di OWL: The Semantic Web will build on XML's ability to define customized tagging schemes [XML] and RDF's flexible approach to representing data [RDF Concepts] e, sinceramente, anche se ci sono proposte per usare OWL con N3, non conosco specifiche ufficiali a proposito.

Quelli che io chiamo contenitori (perchè sempre li ho visti tradotti con questo termine in italiano) sono quelli che la specifica chiama Containers (v. anche il doc della semantica). Si tratta, in effetti, di bnodes, comunque, hai capito bene.