MokaByte Numero  38  - Febbraio  2000
Proiezione dinamica
della Design View
I parte
diagrammi di interazione


di 
Luca 
Vetti Tagliati
Sequence e Collaboration Diagram dello Unified Modeling Languag: modellazione del comportamento dinamico di un sistema.
 

Scopo del presente articolo è proseguire nel percorso di analisi della “Design View”, seconda vista dello “Unified Modeling Language”, iniziato negli articoli precedenti ([8] e [9]) introducendo i meccanismi che consentono di analizzare il comportamento dinamico di un sistema

Introduzione
Gli elementi che costituiscono un qualsivoglia sistema non vengono assemblati semplicemente per persistere in una posizione di riposo, bensì interagiscono tra loro scambiandosi messaggi al fine di raggiungere uno scopo ben preciso. In ogni sistema, dunque, ciascuna componente svolge un determinato compito ed interagisce con altri oggetti al fine di produrre un risultato “globale”, una funzionalità che va ben oltre la “semplice” somma dei risultati prodotti dai singoli oggetti.
Mentre, l’aspetto statico di un sistema è documentabile per mezzo dei class ed object diagram, per ciò che concerne il comportamento dinamico, l’UML fornisce quattro tipologie di diagrammi: statechart, sequence, collaboration ed activity. Anche gli use case permettono di illustrare aspetti dinamici del sistema, da un punto di vista funzionale e quindi, con un livello di astrazione molto elevato
Il Sequence diagram descrive come gli oggetti interagiscono temporalmente tra loro. Viene quindi visualizzata la sequenza di messaggi che gli oggetti inviano e ricevono al fine di realizzare una determinata funzione. In questo tipo di diagrammi, l’attenzione viene focalizza sul fattore tempo.
Il Collaboration Diagram, come il precedente, illustra l’interazione tra oggetti, però, in questo caso, l’attenzione viene spostata dal fattore tempo al fattore spazio. Ciò equivale a dire che si evidenzia l’organizzazione strutturale degli oggetti che si scambiano i messaggi.
L’Activity Digram rappresenta un ulteriore istanza dei digrammi di interazione in cui l’attenzione viene centrata sulle attività da svolgere: non a caso presenta molte analogie con i famosissimi Flow Chart. Negli Activity Diagram, un oggetto interagisce con un altro realizzando determinate attività.
Lo statechart diagram, in sintesi, descrive un automa a stati finiti, costituito da stati, transizioni, eventi ed attività. In altre parole, mostra in quali stati un oggetto può transitare durante il suo ciclo di vita: dalla sua istanziazione alla relativa distruzione. Per ogni stato viene descritto il relativo comportamento, gli eventi che ne determinano l’entrata e l’uscita, ecc. Questo tipologia di diagramma evidenzia il comportamento di un oggetto in funzione di un insieme ordinato di eventi.

Poiché tutti i diagrammi testé presentati permettono di modellare/documentare un’interazione, nell’ambito della descrizione di ciascuna di esse, è sufficiente (ed opportuno) utilizzare una sola tipologia di tali diagrammi. Pertanto, di volta in volta, è necessario selezionare quale tipologia, e quindi quale aspetto, permette di illustrare l’interazione con maggiore chiarezza.
Tipicamente si tende a preferire i Sequence Diagram, sia perché il fattore tempo risulta più intuitivo, sia perché è possibile introdurli fin dalle primissime fasi dell’analisi al fine di presentare degli “scenari” di use case (consultare articolo [7]). Si preferisce ricorrere agli altri quando il Sequence risulta troppo complicato e quindi poco leggibile.
Si tenga presente che “una interazione ben strutturata è come un algoritmo ben strutturato – efficiente, adattabile, e comprensibile- (Grady Booch).
Prima di proseguire nell’analisi di dettaglio dei singoli diagrammi, si ritiene opportuno procedere con l’illustrazione dei concetti che stanno alla base di ogni interazione.
 
 
 

Concetti base  - Comunicazione tra oggetti
Un’interazione è un comportamento che include lo scambio di messaggi tra un insieme di oggetti al fine di produrre una determinata funzionalità. In questo contesto, al termine “messaggio” non va attribuito un significato strettamente testuale, esso è utilizzo per indicare una comunicazione esplicita tra oggetti realizzata attraverso un qualsivoglia meccanismo. Nella stragrande maggioranza dei casi si tratta di una semplice operazione di invocazione di funzione (pardon metodo). Chiaramente, nulla vieta che due oggetti comunichino effettivamente per mezzo di un vero e proprio scambio di messaggi, effettuato attraverso un opportuno meccanismo di comunicazione, nella stessa macchina o attraverso una rete (comunicazioni via Socket, invocazione di metodi remoti: RPC, RMI, CORBA, ecc.).
Nel linguaggio UML, una singola interazione tra oggetti, ossia lo scambio di un messaggio, è rappresentato graficamente per mezzo di un segmento che li unisce. In articolare si possono incontrare le seguenti tipologie di messaggi:

  1. SINCRONI: questi tipi di messaggio permettono di realizzare una tipologia di comunicazione indicata con la denominazione di “rendezvou”; si tratta di un meccanismo che consente di sincronizzare l’esecuzione parallela di due o più processi: un vero appuntamento virtuale. Ciò implica che la “procedura” che gestisce il messaggio ricevuto deve concludersi prima che l’oggetto “mittente” possa proseguire la relativa esecuzione. Lo scambio sincrono di messaggi tra oggetti attivi, inizia con l’oggetto chiamante che esegue un’operazione di spedizione di un messaggio e si pone in uno stato di attesa. L’oggetto chiamato accetta l’invocazione, esegue le relative elaborazioni e quindi invia un messaggio all’oggetto chiamante, eventuale corredato con un risultato di ritorno. A questo punto i due oggetti possono proseguire nella loro evoluzione indipendentemente gli uni dagli altri. Chiaramente, si tratta di una semplice schematizzazione che non tiene conto di problematiche più complesse come la perdita di messaggi, partial failure, ecc..
  2. ASINCRONI: il meccanismo di comunicazione realizzato da questa tipologia di messaggi viene spesso indicato con la denominazione di “mailbox”, in quanto è caratterizzato dall’assenza di un esplicito messaggio di ritorno all’oggetto chiamante: proprio come avviene con il servizio postale…(Qui l’ironia sarebbe troppo facile!) Lo scambio asincrono di un messaggio tra oggetti attivi prevede che l’oggetto chiamante esegua un’operazione di invio e quindi proceda per la propria esecuzione. Nel frattempo, l’oggetto destinatario accetta il messaggio quando è pronto (sono quindi necessari meccanismi di accodamento dei segnali ricevuti) e prosegue per la esecuzione.
  3. GENERICI o SEMPLICI: sono utilizzati per rappresentare un flusso di controllo semplice. In particolare servono per visualizzare come il flusso di controllo viene scambiato tra due oggetti senza scendere nei dettagli della comunicazione. Si ricorre a questa tipologia di messaggi quando i dettagli della comunicazione non sono noti o si ritengono irrilevanti per la fase di progettazione in corso.
Figura 1. Rappresentazione grafica delle diverse tipologie di messaggi.

 

Sequence Diagram
I Sequence Diagram sono un’istanza dei diagrammi di interazione la cui caratteristica è focalizzare l’attenzione sull’ordinamento temporale dei messaggi. Dal punto di vista grafico i Sequence Diagram utilizzano una rappresentazione bidimensionale basata su due assi: l’asse verticale che indica il trascorrere del tempo, e quello orizzontale utilizzato per mostrare gli oggetti coinvolti nella sequenza dei messaggi. Tipicamente, i diagrammi di sequenza, vengono tracciati inserendo l’oggetto che istanza l’interazione a sinistra, proseguendo poi verso destra aggiungendo via via gli altri oggetti che ricevono o spediscono i messaggi: partecipano all’interazione (Figura 2).
 
 
 

Figura 2 . Esempio di Sequence Diagram

 
 

Le caratteristiche che distinguono i Sequence Diagram dai Colaboration (riportati di seguito) sono, sostanzialmente due:

  1. è presente la linea di vita (lifeline) di ogni oggetto. Come evidenziato in figura 2, si tratta di una linea tratteggiata che si estende verticalmente a partire dalla rappresentazione del relativo oggetto. In un Sequence Diagram, molti oggetti esistono per tutta la durata dello “scenario” e pertanto vengono riportati in alto, altri invece, vengono creati durante l’interazione (si consideri l’istanza della classe “Order”). In questo caso, la lifeline inizia a seguito della ricezione di un apposito messaggio di creazione: stereotipo “<<create>>”. Ancora, alcuni oggetti vengono distrutti durante l’interazione. Ciò accade con la ricezione di un altro specifico messaggio: stereotipo “<<destroy>>” (Si consideri sempre l’istanza della classe “Order”). La distruzione di un oggetto viene ulteriormente evidenza per mezzo del simbolo grafico a forma di “X”. Da tener presente che Rose non permette di rappresentare correttamente la generazione, durante l’interazione, di un oggetto né la relativa distruzione.
  2. è evidenziato il flusso di controllo (focus of control). Si tratta di un rettangolo sovrapposto alla lifeline che indica il periodo di tempo durante il quale un oggetto esegue un’azione, sia direttamente, sia per mezzo di procedure subordinate. L’inizio del rettangolo, ossia il lato minore superiore, viene allineato con l’avvio dell’azione, tipicamente corrispondente alla ricezione di un messaggio, mentre il lato parallelo in basso, ne rappresenta la terminazione della stessa che, generalmente, genera la spedizione di un messaggio. Sul “focus of control” è possibile evidenziare altri foucs annidati (ricorsioni, invio di messaggi a sé stessi, ecc.).


Si consideri il Sequence Diagram di figura 2. In primo luogo si può osservare che poiché l’attenzione viene focalizzata sulla proiezione dinamica del sistema, vengono presi in considerazione gli oggetti e non le classi da cui vengono istanziati. La notazione utilizzata è quella introdotta nell’articolo dedicato ai diagrammi delle classi e degli oggetti (vedere [8]).
Dall’analisi del diagramma, si può osservare che gli oggetti istanza delle classi “Sender”, “Order Tack”, “TicketDB” e “Account”, già esistono, ossia sono istanziati, prima che l’interazione abbia inizio. Mentre l’oggetto “Order” viene creato e distrutto durante l’interazione. Lo “scenario” è avviato dall’oggetto “Sender”, che invia un messaggio all’oggetto “OrderTraker”, ossia ne invoca il metodo “request()”. Si può facilmente constatare che la classe “Sender” rappresenta un attore esterno del sistema, e, come tale, è stato rappresentato per mezzo del relativo stereotipo.
L’oggetto “OrderTraker”, ricevuto il messaggio, invoca, a sua volta, il metodo “requestFreeTickets()”, dell’oggetto “TicketDB”, che, verosimilmente, si occupa di gestire le tabelle necessarie per memorizzare i dati relativi alla gestione vendita biglietti. L’esito del metodo “requestFreeTickets()”, valore booleano, viene inviato a ritroso all’oggetto “OrderTraker”. A questo punto si possono verificare due alternative:

  1. non ci sono sufficienti biglietti disponibili: il controllo torna all’oggetto “Sender” e l’iterazione finisce;
  2. il numero dei biglietti a disposizione soddisfa la richiesta: l’iterazione prosegue.
Si consideri la seconda alternativa. L’oggetto “OrderTraker”, ricevuto il parametro di ritorno con valore “true” (biglietti disponibili), invia un messaggio “<<create>>” all’oggetto “Order” e quindi lo istanzia. Non appena creato, l’oggetto “Order”si occupa di riservare i biglietti e a tal fine, invoca il metodo “reserve()” dell’oggetto “TicketDB”. Quest’ultimo, a sua volta, invoca il metodo di “debit()”, per addebitare il costo dei biglietti all’opportuno “Account”. L’oggetto “Account” risponde invocando il metodo “Bonus()” dell’oggetto “TicketDB” che dà luogo ad una invocazione ricorsiva dello stesso metodo. Terminata l’interazione, il controllo torna via via fino all’oggetto “sender” che aveva istanziato l’intero processo. Durante il passaggio a ritroso del controllo, l’oggetto “Order” viene distrutto.
In generale, i Sequence Diagram sono degli ottimi strumenti, utili anche per modellare/documentare sottosistemi o meccanismi di carattere genrale; non a caso vengono utilizzati per rappresentare gli scenari dei casi d’uso. 
Probabilmente, la loro caratteristica fondamentale è di essere molto intuitivi, e quindi adatti per la formalizzazione di processi da sottoporre ad un pubblico non necessariamente tecnico. Coloro che provengono da esperienze di progettazioni strutturate dovrebbero già possedere una certa familiarità con questa tipologia di diagrammi.
Nel diagramma di figura 3, è stato utilizzato un Sequence Diagram per illustrare il meccanismo di comunicazione utilizzato dall’RMI (Remote Method Invocation) per far comunicare classi presenti su diverse Java Virtual Machine.
 
 
 
Figura 1 Sequence diagram  relativo al meccanismo di comunicazione RMI

 

Figura 3. 

4. Collaboration Diagram.
I Collaboration Diagram sono diagrammi una seconda istanza dei interazione la cui peculiarità risiede nel focalizzare l’attenzione sull’organizzazione strutturale degli oggetti che partecipano all’interazione (inviano e/o ricevono messaggi). 
Le caratteristiche che contraddistinguono i Collaboration Diagram dai Seuqence sono essenzialmente due:
1. è presente il percorso (path). Al fine di evidenziare come gli oggetti sono collegati tra l’oro, è possibile realizzare opportune stereotipizzazioni dei link, come “<<self>>” per indicare che il messaggio è stato inviato da un oggetto a sé stesso, oppure “<<parameter>>” che specifica che l’oggetto è visibile in quanto è un parametro del mittente, ecc.
2. i messaggi vengono numerati. Ciò è necessario per evidenziare l’ordinamento temporale dei messaggi. Si aggiunge un prefisso al nome del messaggio che ne indica, appunto, la posizione nella sequenza temporale. A dir il vero, è possibile numerare anche i messaggi presenti nei Sequence Diagram, anche se ciò non sia assolutamente necessario: la sequenza temporale è ben visibile dal diagramma stesso, leggendolo dall’alto verso il basso.
 
 

Figura 4 Collaboration Diagram corrispondente al Sequence di figura 2.

 
 

Adornamenti
Con riferimento al punto 1, sono previste diverse stereotipizzazioni associabili ai link, intesi come collegamenti tra oggetti, tra le quali, le più importanti sono:

  • ·Global. Si applica agli oggetti che prendono parte ad un link per indicarne il “ruolo”. Evidenzia che un dato oggetto è in grado di “vederne” un altro a cui è connesso per mezzo di un parametro globale, che come tale è conosciuto dal sistema. Viene rappresentato per mezzo di un quadrato che racchiude il carattere ‘G’. Se tale parametro è condiviso, allora il quadrato è riempito con il colore bianco, altrimenti con quello nero. (vedere Figura 5).
  • Local. Vale il discorso riportato nel punto precedente. In questo caso, chiaramente, la visibilità tra gli oggetti è garantita da una variabile locale. La lettera inserita nel quadratino è la ‘L’.
  • Parameter. Come sopra.Field. Come sopra.
  • Self. Indica un’autoinvocazione.


Chiaramente, è sempre possibile ricorrere ai famosi “tagged value”.
 
 

Figura 5  Esempio di collaboration Diagram con evidenziati i ruoli “Global” e “Field”

 

Notazione dei messaggi
Quando si realizzano i Collaboration Diagram, bisogna porre attenzione alla notazione utilizzata. La sintassi generale prevede i seguenti simboli:

<predecessore> [<condizione di guardia>] [<sequenza di espressioni>]
[<valore di ritorno> := <segnatura del metodo>]

dove:
<predecessore> := <sequenza di numeri>, ‘,’ … ‘/’

La sequenza di numeri serve ad introdurre un ordinamento temporale dei messaggi. Ovviamente, i messaggi con numero d’ordine minore sono generati (e verosimilmente gestiti) prima di altri con numeri d’ordine superiore.
Il numero d’ordine di ciascun messaggio può essere strutturato secondo un preciso criterio gerarchico, al fine di evidenziare sotto messaggi o processi annidati.

<condizione di guardia> := [ <condizione> ]

Per ciò che concerne la condizione di guardia, può essere espressa in qualsivoglia pseudocodifica, l’importante è curarne la leggibilità e racchiudere la condizione tra parentesi quadre.

[<sequenza di espressioni> := * [ <clausola iterativa>] : [<operazione>]

Il simbolo “sequenza di espressioni” rappresenta un vero e proprio ciclo “for”. E’ necessario premettere il carattere asterisco proprio per evidenziare il ciclo, dopodiché va specificato l’indice, con il relativo dominio, ed infine l’operazione che si intende iterare, separata dalla precedente per mezzo dei due punti.
Esempio:

1.1. * [ind = 0..n-1] : sendMessagge(ind)

Per terminare, il valore di ritorno prevede una sintassi ben conosciuta: 

<valore di ritorno> := <segnatura del metodo>

Per esempio: rit = getSender(n)
Esempi di messaggi:

1: repaint()
2.1 [t < 100] : wait()
3., 4., 5. : sendNotification(listener)
 

Considerazioni relative alle due tipologie di diagrammi
I Collaboration ed i Sequence diagram sono semanticamente equivalenti: ciò significa che si può passare da una rappresentazione all’altra, in modo automatico e senza ridurne il contenuto informativo.
Alcuni tool, tra cui Rational Rose, permettono di passare da un Sequence Diagram all’equivalente Collaboration automaticamente.
Entrambi i diagrammi possono essere utilizzati anche per evidenziare aspetti salienti della use case view, attraverso un livello di astrazione, che considerata la fase del ciclo di vita del sistema, non può che essere elevato.
I Sequence vanno a realizzare i famosi scenari degli use case. In particolare vengono utilizzati per illustrarne graficamente il flusso degli eventi. In questo caso si utilizza una serie di Sequence Diagram: il primo per illustrare lo scenario principale, tipicamente quello in cui tutto si realizza correttamente. I rimanenti Sequence vengono utilizzari per documentare flussi secondari e casi particolari.
Considerata l’equivalenza semantica, ne segue che ogniqualvolta sia possibile utilizzare un Sequence è anche plausibile utilòizzare un Collaboration. Ciononostante, questi ultimi non vengono utilizzati per illustrare degli scenari, bensì per cominciare a dare un’organizzazione, in termini di collaborazione, agli use case.
A questo punto il lettore potrebbe avere qualche perplessità circa il criterio da utilizzarsi per selezionare il diagramma che, di volta in volta, meglio descrive una determinata interazione.
Tipicamente si tende ad utilizzare il Sequence Diagram, sia perché è già presente, seppur in forma molto generale, sin dalle primissime fasi di analisi, sia perché risulta molto intuitivo.
 
 
 

Conclusioni
Il presente articolo è stato dedicato all’introduzione dell’analisi del comportamento dinamico del sistema: “Eppur si muove!”. In particolare sono stati introdotti i diagrammi utilizzati per analizzare/documentare le interazioni, ossia i Sequence e i Collaboration Diagram, che, verosimilmente, sono i più utilizzati per la proiezione dinamica della logical view. Si è anche visto che si tratta di diagrammi semanticamente equivalenti, da una tipologia è sempre possibile passare all’altra senza ridurne il contenuto informativo. La differenza sostanziale risiede nell’aspetto dell’interazione al quale si vuole conferire maggior enfasi. Nei Sequenmce Diagram l’attenzione è focalizzata sull’ordinamento temporale dei messaggi, ,mentre nei Collaboration, si preferisce dare risalto all’organizzazione strutturale degli oggetti che si scambiano i messaggi.
Tipicamente è abbastanza difficile che un singolo diagramma sia in grado di illustrare esaurientemente un’intera iterazione, pertanto non è infrequente il caso in cui sia necessario ricorrere a diversi diagrammi per illustrare un determinato aspetto del sistema.
“Una interazione ben strutturata è come un algoritmo ben strutturato – efficiente, adattabile, e comprensibile- (Grady Booch).
 

Bibliografia
7.1. [1] The Unified Modeling Language User Guide
Grady Booch, James Rumbaugh, Ivar Jacobson
Addison Wesley
Questo libro vanta il primato di essere stato scritto dai progettisti originali del linguaggio, sebbene sia conosciuto come “Grady’s book”, dal nome del suo primo autore. La mancanza di una sua copia (magari autografata!) può generare giudizi di scarsa professionalità per coloro che operano nel settore della progettazione O.O... Ciò però, costituisce una condizione necessaria, ma non sufficiente, in quanto bisogna, assolutamente, aggiungere una copia del [3] e una del [4]. Sono soldi spesi bene! Forse, il limite del libro, se proprio se ne vuole trovare uno, è quello di essere poco accessibile ad un pubblico non espertissimo di progettazione O.O. Un altro piccolo inconveniente è che, probabilmente, taluni esempi possano sembrare di carattere accademico: poco rispondenti alle problematiche del mondo reale.
7.2. [2] UML Toolkit
Hans-Erik Eriksson, Magnus Penker
Wiley
Questo libro si fa particolarmente apprezzare per via del taglio pratico dello stesso. Illustra in modo semplice il linguaggio, attraverso numerosi esempi, limitando le digressioni di carattere teorico. Si suppone infatti, che coloro che si occupano di progettazione O.O. abbiano una certa familiarità con i relativi concetti. Chissà perché si ha la sensazione che non sia sempre così! Naturalmente, studiare libri che illustrano gli aspetti teorici dell’informatica, è sempre qualcosa più che auspicabile. È altresì vero però, che coloro che non hanno tempo da perdere, per la lettura di concetti arcinoti, gradiscono arrivare rapidamente al nocciolo. Ciò spesso equivale a strappare alle nottate lavorative ore preziose per il sonno.
7.3. [3] The Unified Modeling Language Reference Manual
Grady Booch, James Rumbaugh, Ivar Jacobson
Addison Wesley
Il commento da riportare per questo libro, noto per come “Rumbaugh’s book”, è sostanzialmente equivalente a quanto riportato per il primo. Esso però offre un livello di difficoltà decisamente inferiore, e pertanto dovrebbe essere più accessibile. Come suggerisce il nome, si tratta di un manuale, per cui ne rispetta la tipica struttura.
7.4. [4] Design Patterns: Elements of Reusable Object-Oriented Software
Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides, Grady Booch
Addison Wesley.
Si tratta di un ottimo libro che bisogna assolutamente avere se si vuole lavorare nell’ambito della progettazione O.O. . I “pattern” riportati, forniscono un ottimo ausilio al processo di disegno del software. L’utilizzo del libro contribuisce ad aumentare la produttività, fornisce soluzioni chiare, efficienti e molto eleganti. La fase di disegno del software, spesso, si riduce ad individuare e personalizzare i “pattern” che risolvono la problematica specifica. Si è di fronte ad una nuova frontiera della progettazione O.O.: il riutilizzo di parti del progetto. L’unica pecca imputabile, è che i vari diagrammi non sempre rispettano il formalismo UML.
7.5. [5] www.omg.org
Si tratta del sito ufficiale del Object Managment Group.
7.6. [6] www.mokabyte.it, numero 34 (Ottobre 1999)
UML e lo sviluppo del software.
7.7. [7] www.mokabyte.it, numero 35 (Novembre 1999)
Use Case: l’analisi dei requisiti secondo l’U.M.L.
7.8. [8] www.mokabyte.it, numero 36 (Dicembre 1999)
Diagrammi delle classi e degli oggetti: proiezione statica della Design View.
7.9. [9] www.mokabyte.it, numero 37 (Gennaio 2000)
Proiezione statica della “Design View” parte seconda: esempi “celebri” di diagrammi delle classi..

Chi volesse mettersi in contatto con la redazione può farlo scrivendo a mokainfo@mokabyte.it