Il Refactoring di Oknotizie
Tuesday, 19 December 06
Circa una settimana fa io e il mio amico, socio, nonche' conducente di autovetture quando andiamo assieme ai matrimoni, Fabio, abbiamo iniziato il Refactoring di Oknotizie, internati nella sua stanza a Licata, adottati dai suoi genitori che ci alimentavano ogni qual volta le nostre condizioni psico-fisiche erano motivo di preoccupazione per l'equipe medica che ci segue costantemente durante le fasi di sviluppo. Tutto cio' ovviamente assistiti da forti dosi di caffe' custodito in un termos anti-proiettili preoccupato ad isolare questo importantissimo carburante per programmatori dallo scambio termico con l'ambiente circostante.
Refactoringche'?
Il Refactoring e' l'arte di trasformare codice di qualita' non eccelsa (perche' scritto in contesti reali in cui bisogna adattare il progetto al volo per quella nuovissima feature che non puo' aspettare un attimo, in cui le risorse di tempo sono limitate, e in cui i linguaggi utilizzati magari non offrono soluzioni brillanti per risolvere determinati problemi) in codice di buona qualita', tramite piccoli passaggi che sistemano una parte alla volta e che sostanzialmente lasciano l'applicazione funzionante.
In realta' dato un software abbastanza vasto, l'unico modo per renderlo di alta qualita' e' quello di eseguire il refactoring periodicamente, perche' scrivere programmi e' un'arte imperfetta, in cui la perfezione mai raggiunta si insegue per approssimazioni successive.
Nel nostro caso il refactoring mirava ad aumentare la qualita' del codice e la sua modularita' interna al fine di rendere l'implementazione di nuove funzionalita' a cui stiamo lavorando piu' semplice. Uno degli obiettivi chiave era quello di raggiungere una separazione completa tra il codice che ha a che fare con il database e il resto del programma. In pratica dalla fine del refactoring oknotizie accede al DB tramite una API ben definita, e non effettua alcuna query diretta.
Un modo migliore di pensare i database
Se vi dico di progettare un database per una rubrica telefonica online da dove inziate? Probabilmente buttate giu' un paio di tabelle SQL che modellano in maniera semplice ed efficace il problema. Per esempio potreste pensare ad una tabella voce con tre campi chiamati nome, cognome e tel. Al fine di avere un identificativo univico per ogni voce e' abbastanza sensato aggiungere un ID unico autoincrementale, e magari creare degli indici per il nome ed il cognome.
In realta' questo non e' un buon modo di progettare il database, o meglio, se siete dei designer davvero esperti potete anche iniziare dalle tabelle, ma solo perche' avete cosi' tanta pratica da pensare inizialmente all'interfaccia e compiere un processo di traduzione simultanea mentre scrivete l'SQL.
Il DB come una blackbox
Provate invece a pensare al database come una scatola nera, che potrebbe essere implementata in qualunque tecnologia (relazionale o no, SQL o Bdb, o magari tramite il filesystem!). Se il database e' una blackbox e vi chiedono di progettarne uno, tutto diventa piu' chiaro: dovete specificare quali sono le funzioni di quel database, e non la sua implementazione (la tabella o chi per lei).
In poche parole dovete progettare una API verso il DB. E specificare le sue funzionalita', e qual'e' la complessita' di ogni operazione in termini di tempo e spazio.
Torniamo all'esempio della rubrica telefonica. A questo punto il progetto non sarebbe piu' una tabella SQL abbastanza priva di significato, ma una API:
Se tra qualche tempo la vostra applicazione deve diventare un ordine di grandezza piu' complessa, fare qualcosa per cui non era stata progettata, o semplicemente volete migrare ad una tecnologia di database alternativa, ringrazierete voi stessi per aver preso questa strada in tempo.
Refactoringche'?
Il Refactoring e' l'arte di trasformare codice di qualita' non eccelsa (perche' scritto in contesti reali in cui bisogna adattare il progetto al volo per quella nuovissima feature che non puo' aspettare un attimo, in cui le risorse di tempo sono limitate, e in cui i linguaggi utilizzati magari non offrono soluzioni brillanti per risolvere determinati problemi) in codice di buona qualita', tramite piccoli passaggi che sistemano una parte alla volta e che sostanzialmente lasciano l'applicazione funzionante.
In realta' dato un software abbastanza vasto, l'unico modo per renderlo di alta qualita' e' quello di eseguire il refactoring periodicamente, perche' scrivere programmi e' un'arte imperfetta, in cui la perfezione mai raggiunta si insegue per approssimazioni successive.
Nel nostro caso il refactoring mirava ad aumentare la qualita' del codice e la sua modularita' interna al fine di rendere l'implementazione di nuove funzionalita' a cui stiamo lavorando piu' semplice. Uno degli obiettivi chiave era quello di raggiungere una separazione completa tra il codice che ha a che fare con il database e il resto del programma. In pratica dalla fine del refactoring oknotizie accede al DB tramite una API ben definita, e non effettua alcuna query diretta.
Un modo migliore di pensare i database
Se vi dico di progettare un database per una rubrica telefonica online da dove inziate? Probabilmente buttate giu' un paio di tabelle SQL che modellano in maniera semplice ed efficace il problema. Per esempio potreste pensare ad una tabella voce con tre campi chiamati nome, cognome e tel. Al fine di avere un identificativo univico per ogni voce e' abbastanza sensato aggiungere un ID unico autoincrementale, e magari creare degli indici per il nome ed il cognome.
In realta' questo non e' un buon modo di progettare il database, o meglio, se siete dei designer davvero esperti potete anche iniziare dalle tabelle, ma solo perche' avete cosi' tanta pratica da pensare inizialmente all'interfaccia e compiere un processo di traduzione simultanea mentre scrivete l'SQL.
Il DB come una blackbox
Provate invece a pensare al database come una scatola nera, che potrebbe essere implementata in qualunque tecnologia (relazionale o no, SQL o Bdb, o magari tramite il filesystem!). Se il database e' una blackbox e vi chiedono di progettarne uno, tutto diventa piu' chiaro: dovete specificare quali sono le funzioni di quel database, e non la sua implementazione (la tabella o chi per lei).
In poche parole dovete progettare una API verso il DB. E specificare le sue funzionalita', e qual'e' la complessita' di ogni operazione in termini di tempo e spazio.
Torniamo all'esempio della rubrica telefonica. A questo punto il progetto non sarebbe piu' una tabella SQL abbastanza priva di significato, ma una API:
(output) nomeFunzione (input)E cosi' via. Dopo che avete disegnato l'interfaccia potete finalmente implementare il vostro DB, qualunque sia la tecnologia che utilizzerete, e specialmente implementare una API che permetta a tutto il resto del codice di accedere al database senza curarsi dei dettagli implementativi.
(id) inserisciVoce(nome,cognome,tel) inserisce una voce nel DB. Tempo O(1) Spazio O(1)
() cancellaVoce(id) cancella una voce, dato il suo ID. Tempo O(1) Spazio: N/A
(lista di id) cercaVoceDalNome(nome) dato il nome o una sua parte, cerca una voce nel DB. Tempo O(1) se 'nome' esiste nel database O(N) se 'nome' e' una sottoparte di un nome esistente Spazio: N/A
Se tra qualche tempo la vostra applicazione deve diventare un ordine di grandezza piu' complessa, fare qualcosa per cui non era stata progettata, o semplicemente volete migrare ad una tecnologia di database alternativa, ringrazierete voi stessi per aver preso questa strada in tempo.
Do you like this article?
Subscribe to the RSS feed of this blog or use the newsletter service in order to receive a notification every time there is something of new to read here.
Note: you'll not see this box again if you are a usual reader.
Subscribe to the RSS feed of this blog or use the newsletter service in order to receive a notification every time there is something of new to read here.
Note: you'll not see this box again if you are a usual reader.
Comments
1
19 Dec 06, 13:36:47
Ovviamente condivido tutto quanto è stato scritto... solo una piccola nota: fissare la complessità delle procedure in fase di progettazione non è così immediato, poiché sono parametri strettamente legati all'implementazione.
19 Dec 06, 14:05:01
Ciao Emix,
si hai ragione, diciamo che chi ha studiato algoritmi almeno un po' nella vita puo' approssimare in maniera decente per query semplici (per fare un esempio non pensera' mai che si possa fare pattern matching complesso di N records in O(1)), ma dipende dalla tecnologia come hai giustamente fatto notare dunque non sai di preciso che limitazioni reali ci saranno.
Cio' che si puo' fare e' scrivere la complessita' nel tempo e nello spazio in termini teorici, utilizzando il miglior algoritmo e struttura dati conosciute.
La buona notizia e' che sbagliare la stima non e' cruciale :) La cosa importante e' creare l'API, e poi se qualcosa e' troppo lento... come si dice
"Qualunque programma abbastanza complesso si riduce in un esercizio di caching"
Io direi "richiede" perche' "si riduce" e' troppo stringente, ma rende l'idea ;)
si hai ragione, diciamo che chi ha studiato algoritmi almeno un po' nella vita puo' approssimare in maniera decente per query semplici (per fare un esempio non pensera' mai che si possa fare pattern matching complesso di N records in O(1)), ma dipende dalla tecnologia come hai giustamente fatto notare dunque non sai di preciso che limitazioni reali ci saranno.
Cio' che si puo' fare e' scrivere la complessita' nel tempo e nello spazio in termini teorici, utilizzando il miglior algoritmo e struttura dati conosciute.
La buona notizia e' che sbagliare la stima non e' cruciale :) La cosa importante e' creare l'API, e poi se qualcosa e' troppo lento... come si dice
"Qualunque programma abbastanza complesso si riduce in un esercizio di caching"
Io direi "richiede" perche' "si riduce" e' troppo stringente, ma rende l'idea ;)
19 Dec 06, 16:22:28
Quanto vorrei conoscervi di persona.. è cos' difficile contattarvi anche via web :)