Metodologie e progettazione di un software con UML

Metodologie e progettazione di un software con UML

UML e metodologie per la progettazione del software

All’inizio degli anni ’90 esistevano molte metodologie orientate agli oggetti; ognuna si basava sulle esperienze di autori e su punti di vista diversi. Queste metodologie sono concorrenti sul mercato. Scegliere una metodologia più adatta ad una certa azienda spesso non è ad alcun titolo una decisione razionale, ma piuttosto è più simile ad un atto di fede. Nei vent’anni successivi alle prime esperienze con le metodologie di sviluppo orientate agli oggetti furono investiti molti soldi nello sviluppo di varie notazioni per la descrizione di problemi tecnici e le relative soluzioni. Cosi sì affermò il linguaggio UML (Unified Modeling Language). Questo linguaggio fù sviluppato da tre autori, cioè James Rumbaugh, Grady Booch e Ivar Jacobson i quali a sua volta avevano sviluppato singolarmente tre metodologie orientate agli oggetti.

  1. OMT
  2. OOAD
  3. OOSE

Ognuno di questi metodi aveva, naturalmente, i suoi punti di forza e i suoi punti deboli. Ad esempio, l’OMT si rivelava ottimo in analisi e debole nel design. Booch 1991, al contrario, eccelleva nel disegno e peccava in analisi. OOSE aveva il suo punto di forza nell’analisi dei requisiti e del comportamento di un sistema ma si rivelava debole in altre aree.
UML è una notazione; i.e. non impone alcuna modalità di lavoro che possa portare a una metodologia ben precisa. Questo rende possibile adottare varie tecniche di sviluppo software basandosi su un’unica notazione: UML.

Metodologie e progettazione di un software con UML

Elenchiamo, qui di seguito, alcuni dei benefici derivanti dall’utilizzo del linguaggio UML:

  • un sistema software, grazie al linguaggio UML, viene disegnato professionalmente e documentato ancor prima che ne venga scritto il relativo codice da parte degli sviluppatori. Si sarà cosi in grado di conoscere in anticipo il risultato finale del progetto su cui si sta lavorando;
  • poichè la fase di disegno del sistema precede la fase di scrittura del codice, ne consegue che questa e resa piu agevole ed efficiente, oltre al fatto che in tal modo e più facile scrivere del codice riutilizzabile in futuro. I costi di sviluppo, dunque, si abbassano notevolmente con l’utilizzo del linguaggio UML;
  • è più facile prevedere e anticipare eventuali buchi nel sistema. Il software che si scrive, si comporterà esattamente come ci si aspetta senza spiacevoli sorpese finali;
  • l’utilizzo dei diagrammi UML permette di avere una chiara idea, a chiunque sia coinvolto nello sviluppo, di tutto l’insieme che costituisce il sistema. In questo modo, si potranno sfruttare al meglio anche le risorse hardware in termini di memoria ed efficienza, senza sprechi inutili o, al contrario, rischi di sottostima dei requisiti di sistema;
  • grazie alla documentazione del linguaggio UML diviene ancora più facile effettuare eventuali modifiche future al codice. Questo, ancora, a tutto beneficio dei costi di mantenimento del sistema.

Adesso, mostriamo brevemente una sintesi delle operazioni da svolgersi per una corretta serializzazione del lavoro di progettazione di un software:

  • Raccolta dei requisiti: E’ la prima fase di lavoro congiunto con il cliente, che partendo dalle sue intenzioni iniziali e dai suoi desideri, ha lo scopo di produrre un documento informale, scritto in linguaggio naturale, che elenca i requisiti e le specifiche richiesti. Deve essere il più possibile breve e chiaro;
  • Stesura del glossario: In questa fase si deve definire la terminologia del progetto, identificando con precisione e accurattezza le entità (eventi, persone, strutturazioni, ecc.) coinvolte nel sistema del mondo reale (ovvero del dominio del business) che hanno importanza per il sistema informatico obiettivo del progetto. E’ importante definire con precisione le entità allo scopo sia di definire meglio i loro scenari d’uso (Use Case), sia di individuare le classi entità (Class Diagram di analisi). Il risultato finale è il glossario;
  • Stesura degli Use Case Fase di Analisi: In questa fase devono essere individuati con precisione gli scenari di interazione fra il sistema e gli attori, ovvero le entità esterne al sistema con cui esso interagisce e comunica. I passi necessari in questa fase possono essere così suddivisi:
    1. Definizione esatta del boundary o conftne del sistema (entro sistemi particolarmente complessi questa fase pùo anche essere applicata a sottosistemi).
    2. Identificazione e definizione degli attori, ossia delle entità esterne con cui il sistema (o i sottosistemi) oggetto dell’analisi interagiscono e comunicano;
    3. Individuazione dei vari scenari di uso/interazione fra sistema ed attori, che corrisponderanno ai singoli casi d’uso, identificati da elissi nel diagramma;
    4. Definizione delle interazioni entro i singoli casi d’uso; tali interazioni, strutturate nella forma di richiesta dell’attore cui corrisponde una risposta del sistema, andranno a costituire i campi descrizione dei singoli casi d’uso (operazione detta in gergo “srotolamento” dello use case);
    5. Esame dei diagrammi così ottenuti e delle loro descrizioni per procedere alla raccolta a fattore comune di parti fra i singoli use case entro diagrammi, facendo uso delle relazioni extends ed include definibili tra i vari casi d’uso. Il passo 5 pùo essere iterato piu volte; occorre tenere conto della granularità del problema e del grado di definizione e precisione che si vuole raggiungere. Inoltre si deve considerare che un singolo caso d’uso spesso da origine ad una singola maschera (sia essa un menu testuale, una singola finestra in ambiente grafico o una pagina Web).
      Il prodotto di questo passo è l’insieme completo degli use case inseriti entro uno o più diagrammi, ciascuno dei quali corredato da una adeguata descrizione, strutturata chiaramente in forma di request-response, e considerando sia il percorso principale di interazione (basic course) sia gli eventuali percorsi alternativi (alternative course). Il diagramma e le descrizioni devono essere ben strutturati, chiari ed esaurienti in quanto tutti i passi successivi si baseranno su di essi;
  • Stesura del Class Diagram di analisi: In questa fase deve essere realizzato il diagramma delle classi di analisi. Esso deve indicare chiaramente tutte le classi entità, ossia le classi definibili come proiezioni nel dominio dell’applicazione software dell’entità del problema in cui l’applicazione software andrà ad operare, più eventuali altre classi individuate nel corso dell’analisi e che siano di una certa rilevanza per i concetti funzionali che definiscono i requisiti del progetto. In pratica nel diagramma, che è l’equivalente dal punto di vista del ruolo del diagramma Entità Relazione (ER) usato nelle metodologie di sviluppo più tradizionali, devono essere indicate in modo chiaro:
    1. tutte le classi entità che fanno parte del dominio del problema;
    2. gli attribuiti caratteristici di tali classi, eventualmente procedendo al la individuazione dei singoli attributi o dei gruppi che consentano una indentificazione univoca delle istanze delle classi ovvero dei singoli oggetti;
    3. le associazioni che intercorrono tra tali classi; queste associazioni (che corrispondono alle relazioni dei diagrammi ER) sono importanti perchè in sede di implementazione del codice indicheranno anche la visibilità necessaria tra le classi, cioe quali altre classi (eventualmente appartenenti ad altri package o namespace) potranno essere viste da una certa classe e definendo quindi la loro interdipendenza;
    4. i versi di tali associazioni (ad esempio, se la classe magazzino deve conoscere la classe prodotto, non e sempre vero il contrario);
    5. le molteplicità di tali associazioni (es. uno a molti, molti a molti) e l’eventuale necessità di definire classi di associazione. Per esempio il concetto di proprietà di un’auto, una volta rappresentato nel dominio delle classi, pùo costuire una classe di associazione fra l’auto e la persona che ricopre il ruolo di proprietario;
    6. eventuali rapporti di inclusione legati a tali associazioni e suddivisi fra aggregazione e composizione. Si ricordi che l’eliminazione di una composizione, indicata con il diamante nero, elimina anche tutti i suoi elementi componenti, mentre l’eliminazione di una aggregazione, indicata nella rappresentazione UML dei class diagram con il diamante bianco/nero, non elimina anche i componenti che comunque hanno un ambito di sopravvivenza indipendente;
    7. eventuali rapporti di ereditarietà fra le classi ottenuti applicando i principi di generalizzazione e specializzazione, ovvero raccogliendo a fattor comune attributi e metodi o aggiungendone di nuovi.

Il processo che conduce al diagramma finale è ovviamente iterativo e pùo dirsi stabilizzato quando tutte le relazioni (in senso ampio) fra le classi sono chiaramente individuate. Il Class Diagram di analisi e fondamentale per tutti i passi successivi;

  1. Scelta architetturale: La scelta architetturale è un passo fondamentale in quanto le fasi successive ne verranno pesantemente condizionate. Esistono comunque regole generali che ne aiutano lo svolgimento quali il pattern ModelView-Controller (MVC) (che abbiamo visto) ed il conseguente approccio multicanale alla realizzazione delle interfacce utenti. Seguendo tale metodo si separa nettamente l’interfaccia utente vera e propria (View) che ha lo scopo di presentare i dati all’utente ed è ovviamente soggetta a vincoli, dal tipo di canale di comunicazione utilizzato (interfaccia a finestre grafiche, shell a caratteri, ecc.), dal reattore agli eventi trasmessi dall’utente (Controller) che usa i metodi forniti dagli strati interni dell’applicazione (Model e relativi Adapter) per garantire all’utente i servizi associati alle richieste effettuate. Grazie all’approccio multicanale, eventualmente corredato dall’uso di altri strati di Adapter, diviene possibile riutilizzare (almeno in buona parte) il Controller (ed ovviamente gli strati sottostanti) cambiando solo la View quando si cambia canale, passando, ad esempio, da una applicazione GUI ad una Web. La scelta dell’architettura deve anche segnalare limiti e criticita nel sistema che sarà realizzato. L’output di questa fase sono documenti tecnici architetturali che saranno poi corredati da eventuali Component Diagram e Deployment Diagram solo al termine della fase di progetto vera e propria;
  2. Definizione del class diagram di progetto Fase di Progettazione: In questa fase occorre definire chiaramente tutte le classi che fanno parte dell’applicazione software da implementare. Il Class Diagram di Progetto è l’elenco completo delle classi e di tutte le relazioni e su di esso si basa anche il dimensionamento della fase di sviluppo (ovvero la scrittura vera e propria del codice). Il processo che permette di giungere al diagramma delle classi di progetto e necessariamente iterativo. Si parte dal diagramma delle classi di analisi e progressivamente vengono inserite tutte le classi di servizio che permettono al programma nel suo insieme di operare correttamente ed in modo efficiente. Le classi di servizio sono ovviamente fortemente dipendenti nella loro struttura dall’architettura scelta e da eventuali framework utilizzati nel progetto. Se un diagramma di analisi ben fatto pùo essere spesso utilizzato con diverse tecnologie ad oggetti, ovvero essere punto di partenza per progetti analoghi realizzati su piattaforme diverse, un diagramma di progetto è chiaramente molto più influenzato dalla tecnologia usata. Il processo usa anche altri diagrammi UML:
    1. i diagrammi di interazione (sequence diagram, che evidenzia la sequenza temporale delle interazioni, e collaboration diagram, che chiarisce la dipendenza fra le classi) sono di importanza fondamentale sia per la definizione dei metodi che le classi offrono (e dei loro argomenti e valori di ritorno), sia per l’individuazione di eventuali colli di bottiglia che vengono risolti con l’inserimento di nuove classi o la cancellazione di quelle ridondanti. In teoria ad ogni use case corrisponde almeno un sequence o un collaboration diagram: infatti ogni corso di eventi individuato nell’analisi con gli use case dovrebbe produrre una precisa sequenza temporale di invocazione di metodi all’interno dell’insieme delle classi costituenti il sistema software. Non sempre è però indispensabile un’implementazione completa, specie se gli eventi presentano evidenti analogie e similitudini, nel qual caso basta apportare le opportune descrizioni di accompagnamento;
    2. i diagrammi di attività (activity diagram) derivano dagli Use Case è danno loro una sequenza temporale e logica. Inoltra possono aiutare molto nella definizione della mappa di navigazione tra le finestre, consentendo di definire completamente l’interfaccia utente di un applicativo ed eventualmente di realizzare i prototipi d’analisi;
    3. i diagrammi di stato (statechart diagram) sono anch’essi molto importanti per valutare l’evoluzione temporale delle singole classi (o meglio degli oggetti da esse istanziati) o di sottosistemi che esse vanno a costituire, aiutando ad individuare eventuali condizioni critiche o colli di bottiglia dell’applicazione.
      L’obiettivo finale è comunque la realizzazione del Class Diagram di Progetto, completo di tutte le classi. Spesso per motivi di chiarezza (specialmente in progetti grandi dove le classi sono molto numerose) il diagramma viene diviso in package o namespace, associazioni di classi corrispondenti ad unità funzionali, che indicano esternamente solo le reciproche relazioni. Ciascun package viene poi rappresentato completamente entro un diagramma di secondo livello. Quasi sempre questa suddivisione funzionale viene anche portata a livello implementativo servendosi delle aggregazioni tipiche dei linguaggi, come i package di Java o i namespace di C#. L’obiettivo deve essere sempre quello di avere un diagramma leggibile, che serve come mappa per lo sviluppo. Da questo diagramma possono anche essere generati gli scheletri delle classi attraverso opportuni strumenti, oppure essere estrapolati i Fogli di specifica, ossia i documenti che descrivono ciascuna classe con attributi, metodi, vincoli e controlli da implementare;
  3. Definizione delle strutture di contorno : Usando i diagrammi realizzati in precedenza si arriva a definire le parti implementative di contorno del progetto, che devono essere opportunamente documentate come segue:
    1. definizione della base di dati, attraverso un EER, eventualmente corredato dagli script di creazione delle tabelle e vincoli che genera la base di dati nello specifico DBMS scelto;
    2. definizione dell’insieme dei singoli componenti software (namespaces, librerie statiche o dinamiche, dll, ecc.) che devono essere prodotti, con l’indicazione delle loro interdipendenze, attraverso un opportuno Component Diagram;
    3. definizione della distribuzione dei componenti sulla o sulle piattaforme di produzione prescelte attraverso uno o più opportuni Deployment Diagram;
    4. stesura di opportuni documenti Readme ed altro che corredino il progetto e l’installazione; in particolare devono essere chiaramente indicati eventuali limiti e/o malfunzionamenti delle piattaforme software e hardware utilizzate;
    5. stesura dell’opportuno manuale utente dell’applicazione secondo i criteri stabiliti;
    6. definizione delle scadenze e pianificazione dell’esecuzione temporale del progetto in base ai dimensionamenti svolti e alle risorse a disposizione;
    7. definizione dei testi e dei singoli casi di test;
    8. pianificazione del collaudo e dell’entrata in produzione;
    9. definizione della successiva fase di manutenzione.

Pubblicato da Vito Lavecchia

Lavecchia Vito Ingegnere Informatico (Politecnico di Bari) Email: [email protected] Sito Web: https://vitolavecchia.altervista.org

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *