21

Apr

Vediamo di anticipare il buon Dino Esposito ;)

A riciao a tutti

Prendendo spunto dal "famoso" corso di Dino Esposito http://dotnetlombardia.org/blogs/tonyexpo/archive/2010/04/18/corso-pattern-e-best-practices-su-asp-net-4-di-dino-esposito-24-25-maggio-2010-milano.aspx approfitto di questo blog per vedere insieme alcuni elementi del programma che magari ci fanno ricordare delle buone consuetudini :)

Il corso tratta come sviluppare software (principlamente web) seguendo i vari standard cross-platform utilizzabili in ASP.NET in tutte le sue forme seguendo un po le varie architetture e i vari design pattern. Per approfondire, c'è un interessate community http://www.ugialt.net/MainPage.ashx 

Troviamo poi consigli e linee guida da seguire per sviluppare un software in modo corretto, dove corretto sta per manutenibile, estendibile e testabile.

Ecco il primo spunto ;) ricordiamoci i principi base del OOD (object oriented desgin): trovare gli oggetti giusti (pertinenti), disaccoppiarli e riutilizzare il codice:

1) Scegliere il giusto oggetto è la prima sfida e dovremmo muoverci scegliendo gli oggetti di business più pertinenti nel dominio di appartenenza (l'applicazione da un punto di vista funzionale), fattorizzarli nelle giuste classi con la giusta coesione, e definire le corrette interfacce pubbliche, relazioni di ereditarietà e associazioni (es: fattura con i suoi elementi).

La coesione indica che un dato modulo software (routine, classe o libreria) implementa un insieme di responsabilità che ne sono strettamente collegate.
Questo significa che una rountine che chiede all'utente dei dati, li processa a modo suo, li scrive in un db e poi li manda in stampa non dovrebbe esistere perchè ogni volta che si dovrà cambiare, aggiornare o manutenere uno qualunque di quei comportamenti si dovrà rimettere mano alla routine, significa anche che la routine non è riutilizzabile se non in quello specifico programma.
 
2) L'accoppiamento misura il livello di dipendenza che c'è tra due moduli software. Il disaccoppiamento di due moduli facilita il riuso del codice e sponsorizza la coesione dei moduli specializzandoli in un definito compito.
 
3) Il riutilizzo del codice è un aspetto importante del nostro lavoro, altrimenti ogni volta dovremmo reinventare la ruota. Nel libro del GoF (Gang of four) si parla ad esempio di 2 possibili tecniche: white-box, che vuole l'ereditarietà come elemento principe del riutilizzo e dell'estensione di un implementazione con nuove funzionalità, e black-box, in cui si usa l'object composition tecnica che vuole la creazione di oggetti contenente un insieme di altri oggetti che sommati danno la funzionalità desiderata. In caso di aggiunta di funzioni di dovrebbe usare la white-box, altrimenti la black-box con l'object composition.

 

Secondo spunto interessante, SOLID è un acronimo per definire 5 design pattern particolarmente importanti:

Single Responsability Principle: è un principio per cui un modulo software dovrebbe avere un unico motivo di esistere, e quindi di essere aggiornato, così da favorire la coesione.
 
Open Close Principle (OCP): è un principio secondo il quale un modulo dovrebbe essere sempre estendibile, e mai modificabile. Nel suo linguaggio, aperto a estensioni, chiuso a modifiche. 
Questo per garantire la riduzione degli errori eventualmente dati da modifiche, e per sponsorizzare l'ereditarietà.
 
Liskov Substitution Principle (LSP): è un principio secondo il quale si estende il concetto di polimorfismo (una classe figlia è sostituibile ad una classe madre) così che una sottoclasse dovrebbe essere sempre sostituibile alla superclasse garantendo il funzionamento dei metodi originali e aggiungendo nuove funzionalità (simile all'open close principle) rinunciando in effetti all'override dei metodi, a meno di garantirne l'uguaglianza del risultato. 
 
Interface segretation principle: altro principio che (secondo me) rafforza l'OCP o il LSP dicendo che un iterfaccia non dovrebbe costringere ad implementare metodi inutili alla funzionalità della stessa. Il consiglio in pratica è usare la granularità giusta, un'interfaccia persona è troppo astratta per aggiungere sia ad esempio la p.iva che il cf per poi popolarne solo 1 delle 2, è meglio fare 2 interfacce (persona fisica, persona giuridica) e avere la possibilità di mischiarle come si vuole nell'implementazione di un oggetto (che ricordiamo, ha una sola classe madre, ma puo impementare N interfacce)

Dependency Inversion Principle: è un pattern di sviluppo chiamato così perchè mira a ridurre le dipendenze sbagliate, dove per sbagliate si intende nella direzione sbagliata. Mi spiego: sviluppando su due livelli, (alto e basso) andremo a creare una nostra applicazione ad alto livello in cui definiamo una sorta di workflow utilizando solo interfacce (quindi eliminando le dipendenze verso il basso livello) che verranno poi popolate con istanze reali dal framework che andremo ad usare. Questo fa si che non si debbano sparpagliare molte dipendenze tra i nostri assembly, rendendo rigido il nostro progetto, e fa si che si centralizzi magari in modo configurabile un gestore di istanze riutilizzabili per tutti i nostri task (dei mini workflow), andando anche in fase di test a darci la possibilità di usare degli oggetti finti appunto senza toccare 1 riga di codice.
Vedi: http://dotnetlombardia.org/blogs/tonyexpo/archive/2010/04/17/dipendency-injection.aspx

 

Alla prossima

by Antonio Esposito on 4/21/2010