Diagrammi di sequenza: visualizzare lo scambio di messaggi in un sistema con UML

Il diagramma di sequenza è un tipo di diagramma dell’Unified Modeling Language (UML). L’UML è un linguaggio di modellazione orientato agli oggetti ed è costituito da elementi grafici. L’UML modella sistemi e processi di programmazione orientata agli oggetti, nonché processi aziendali. L’obiettivo è quello di presentare chiaramente fatti complessi. A questo scopo l’UML stabilisce una notazione standardizzata.

Un modulo rappresenta sempre un particolare componente o comportamento. Il cosiddetto metamodello definisce le unità linguistiche e il loro significato all’interno dell’UML. Ciò include anche la determinazione di come alcuni elementi possano interagire tra loro e quali gerarchie esistano tra le rispettive unità linguistiche.

L’UML rappresenta elementi e relazioni sotto forma di diagrammi. L’UML2 distingue 14 diversi tipi di diagrammi, assegnandoli a una delle tre diverse categorie: diagrammi strutturali, diagrammi comportamentali e diagrammi di interazione.

  • I diagrammi di struttura (in inglese: structure diagrams) rappresentano un sistema e le sue componenti in uno stato statico e illustrano le relazioni tra singoli elementi o tra elementi e concetti sovraordinati. Un esempio di ciò è il diagramma di classe.
  • I diagrammi di comportamento (in inglese: behavior diagrams) rappresentano i processi e il comportamento di un sistema dinamico. A differenza dei diagrammi di struttura anche l’ordine dei processi e perciò il tempo sono rilevanti nella rappresentazione. Un esempio di ciò è il diagramma di attività.
  • I diagrammi di interazione (in inglese: interaction diagrams) sono diagrammi comportamentali. Sono elencati separatamente perché modellano un comportamento specifico, cioè le interazioni tra gli elementi del sistema. Gli elementi costitutivi fondamentali delle interazioni sono le cosiddette linee di vita: oggetti (cioè le più piccole componenti indipendenti della programmazione orientata agli oggetti) che rappresentano i singoli partecipanti in un’interazione. Il diagramma di interazione più comunemente utilizzato è il diagramma di sequenza.

I diagrammi di sequenza: utilizzo e particolarità

Il diagramma di sequenza UML presenta le occorrenze degli eventi in ordine cronologico, pertanto a volte viene indicato come un diagramma di eventi o uno scenario di eventi. L’ordine (ovvero la successione precisa) è più importante di tempi specifici. Tuttavia è possibile includere restrizioni nel modello: ad esempio un limite di tempo per un particolare processo (come l’immissione del codice PIN presso il bancomat) può causare un evento (restituzione della carta se non si verifica alcun comando dopo un certo periodo di tempo).

Il diagramma di sequenza descrive fondamentalmente come gli oggetti (e le istanze) scambiano messaggi in un ordine particolare. Gli oggetti sono la base elementare dei diagrammi UML. A seconda del tipo di diagramma, rappresentano alcune caratteristiche di un elemento del sistema. Nelle interazioni gli oggetti sono linee di vita.

In un sistema vengono costantemente fatte richieste e inviate risposte. Il destinatario prende quindi una decisione in base alla richiesta specifica e alle sue regole predeterminate. Una simile rete di possibili decisioni e interazioni è solitamente rappresentata da un diagramma di attività. Se immaginate tutte le decisioni possibili (“sì” o “no”) come un diagramma ad albero, probabilmente si presenta l’immagine di una rete fortemente ramificata. Il diagramma di sequenza mostra solo un percorso specifico all’interno di questa rete.

Il diagramma di sequenza si differenzia dal diagramma del caso d’uso UML, in particolare per il suo ordine dettagliato: se un processo aziendale deve essere reintrodotto, il caso d’uso fornisce una buona panoramica sui requisiti. D’altra parte, se si desidera specificare casi concreti e pianificazioni, si utilizza un diagramma di sequenza. In quest’ultimo potete rappresentare singole sezioni in modo più dettagliato. Con questo cosiddetto scenario di applicazione si controllano accuratamente le connessioni logiche del caso d’uso.

I diagrammi di sequenza UML sono inoltre utili se si desidera rappresentare graficamente operazioni complicate per renderle più comprensibili. La modellazione chiara identifica rapidamente le stazioni che una singola attività deve compiere per completarle correttamente. In questo modo potete pianificare e testare i vostri metodi anche prima di implementarli nell’attività aziendale quotidiana o in un sistema informatico.

Per rappresentare le strutture di controllo di un linguaggio di programmazione di alto livello collegate diversi diagrammi di sequenza l’uno con l’altro in un frammento combinato.

N.B.

I diagrammi di sequenza supportano l’analisi logica per sottosezioni di sistemi. Se la tempistica dei processi gioca un ruolo importante, questo tipo di diagramma è particolarmente indicato. Tuttavia non ha senso utilizzarlo per presentare un intero sistema. Piuttosto, puntate a un diagramma comportamentale appropriato come il diagramma del caso d’uso, il diagramma di stato o il diagramma di attività. Questi illustrano anche relazioni più ampie in un modo chiaro e facile da capire.

Diagrammi di sequenza UML: notazione ed esempi

Un diagramma UML dovrebbe aiutare a garantire che tutte le parti interessate comprendano meglio i sistemi complessi. Per fare ciò il linguaggio di modellazione utilizza simboli visivi. Per eccezioni e gruppi di applicazione specifici l’UML può essere anche personalizzato. Tuttavia ha più senso impostarlo come specificato dallo standard dell’OMG (Object Management Group) per evitare che insorgano problemi di comprensione. Le seguenti specifiche sono conformi allo standard UML nella versione UML 2.5.

Linee di vita

La linea di vita rappresenta la cronologia di un processo. La sua testa consta di un rettangolo che in genere include il nome dell’oggetto e il nome della classe. Se il nome dell’oggetto è mancante, la linea di vita rappresenta un’istanza senza nome dell’oggetto. In questo caso si può assumere che tutti gli oggetti della stessa classe agiscano allo stesso modo in questa sequenza. La linea di vita rappresenta sempre solo un singolo operando. Se l’operando ha diverse caratteristiche, occorre selezionarne una. Per concludere si può dire: la molteplicità non è mai >1.

Fatto

Un operando di ingegneria informatica è un oggetto che è influenzato da un operatore. Gli operandi possono essere costanti o variabili. Ad esempio un operando semplice è la variabile X. Gli operatori possono essere semplici operatori aritmetici come “+” e “-”. Nella programmazione si usano questi componenti per funzioni semplici come “x= t *4” fino a sofisticati algoritmi.

Dalla testa rettangolare scende una linea tratteggiata. Questa linea rappresenta il passare del tempo. Verso il basso il tempo evolve linearmente. Lungo la timeline i messaggi vengono inviati e vengono fornite le risposte. Un messaggio che è pianificato per essere inviato dopo un altro messaggio rimane più in basso nella timeline. La notazione non indica mai precisi momenti, come data e ora, ma indica soltanto l’ordine temporale. I messaggi vengono sempre posizionati uno sotto l’altro a meno che non esistano in frammenti combinati in parallelo.

Le linee di vita indicano per quanto tempo un oggetto è coinvolto attivamente in un processo: ciò si può desumere dalla lunghezza della linea di vita paragonata alle altre. Alcuni oggetti vengono distrutti prima che il processo sia terminato. Contrassegnate gli oggetti non più necessari con una X sulla loro linea di vita nel punto in cui devono essere distrutti.

Il diagramma di sequenza, offrendo una panoramica molto dettagliata, è particolarmente adatto per verificare la robustezza del vostro sistema. Potete utilizzare tre stereotipi di classe della linea di vita:

  • entità
  • confine
  • elemento di controllo

Nell’immagine sopra potete vedere le tre linee di vita insieme alla notazione: l’entità ha una testa rotonda situata su una linea orizzontale. Al confine una linea scende nel mezzo del cerchio e si connette a una linea verticale, come una T inclinata che si allontana di lato dalla testa. La testa del comando consiste in una freccia che si trasforma in un cerchio. Di tutti questi stereotipi di classe, la linea tratteggiata della vita scende verticalmente verso il basso.

Se ad esempio avete già sviluppato un concetto basato su un diagramma del caso d’uso, il diagramma di sequenza può aiutarvi a elaborare, tra le altre cose, le singole fasi, tenendo conto degli attori e degli oggetti concepibili.

I confini (in inglese: boundaries) rappresentano interfacce che interagiscono con attori esterni. Ad esempio questi oggetti potrebbero essere interfacce utente, nel qual caso l’attore sarebbe una persona. Le entità (in inglese: entities), d’altra parte, rappresentano contenitori di dati o oggetti che contengono dati di sistema. Affinché i confini e le entità possano comunicare, è necessario un elemento di controllo. Il controllo non deve essere necessariamente un oggetto. Funziona anche un metodo attribuito a uno degli altri due elementi. L’elemento di controllo combina entità e confini come mediatore. Controlla i segnali dei due elementi e verifica per quanto riguarda la logica.

I tre stereotipi comunicano secondo quattro regole:

  • gli oggetti di confine sono l’interfaccia per la comunicazione con gli attori. Pertanto gli attori comunicano soltanto con i confini.
  • Al contrario gli oggetti di controllo comunicano con altri oggetti di controllo, oltre che con entità e confini. Non interagiscono invece con gli attori.
  • I confini quindi comunicano con oggetti di controllo e attori.
  • Le entità sono profondamente radicate nel sistema come portatori di dati. Scambiano solo dati con gli oggetti di controllo.

Messaggi

Il messaggio è un elemento base del diagramma di sequenza. Nella programmazione orientata agli oggetti un sistema consiste di oggetti. L’UML rappresenta questi oggetti come nodi collegati dai cosiddetti bordi. Nell’UML questi bordi svolgono compiti diversi. Nel diagramma di sequenza UML modellano i messaggi di metaclasse. La notazione prescrive una linea come forma base del bordo. Le frecce sono una forma speciale di bordo che rappresenta una relazione direzionale o un flusso di informazioni. Nel diagramma di sequenza simboleggiano i messaggi. Diversi tipi di messaggi sono visualizzati in modo diverso, come mostrato nella figura qui sotto.

Date al messaggio un’etichetta che mostri il suo contenuto. Per i messaggi semplici utilizzate il seguente modulo:

[Nome messaggio] : [attribute "="] nome segnale o nome operazione [argomenti] [":" valore restituito]

Gli argomenti validi per i messaggi sono:

  • costanti
  • valori jolly (valori simbolici che rappresentano un valore legale X nel diagramma)
  • attributi del mittente
  • parametri dell’interazione circostante
  • attributi della classe sovraordinata

I messaggi hanno una firma che specifica il contenuto del messaggio. La firma si riferisce a un segnale o a un’operazione e deve comparire dopo ciascuno. Ciò significa che il contenuto del messaggio o avvia un’operazione (cioè un’attività) sul ricevitore o invia un segnale, perciò scambia soltanto informazioni.

Inoltre i messaggi si differenziano in sincroni o asincroni. Per i messaggi asincroni il mittente non attende una risposta, ma riprende immediatamente il suo comportamento. I messaggi sincroni attendono una risposta e bloccano il canale sul quale stanno inviando.

Questi sono i tipi di messaggio standardizzati nel diagramma di sequenza UML:

  • Messaggi asincroni del tipo (MessageSort) asynchCall, i quali chiamano un’operazione e ne attivano l’esecuzione. Per i messaggi asincroni il sistema non attende una risposta dal destinatario, ma continua i suoi processi senza interruzioni. I parametri di funzionamento e gli attributi dei messaggi devono corrispondere.
    • Il tipo asynchSignal viene utilizzato per le istanze di segnale. Rappresenta la spedizione e la ricezione di messaggi asincroni. Tale messaggio è causato da un’azione di invio asincrona del segnale. Qui gli attributi del segnale determinano gli argomenti del messaggio.
    • Notazione: i messaggi asincroni sono modellati come una freccia con una linea continua e una punta aperta.
  • I messaggi sincroni chiamano solo le operazioni, nessun segnale. Il tipo di messaggio è chiamato synchCall. I messaggi sincroni attendono una risposta dell’operazione prima di riprendere il proprio comportamento. I messaggi sincroni si rappresentano con una freccia la cui punta è piena.
  • Risposte: il destinatario di un messaggio lo rispedisce al mittente dopo che l’operazione è giunta a conclusione. Il simbolo per questo ha una punta di freccia aperta o colorata. La linea corrispondente è tratteggiata.
  • createMessage è un tipo di messaggio che segnala una nuova istanza di una linea di vita. In questo modo il sistema crea un nuovo oggetto nel diagramma di sequenza. Questo tipo di messaggio è l’unico che punta direttamente alla testa della linea di vita. Altri messaggi devono puntare alla linea di vita tratteggiata. createMessage ha una freccia con una punta aperta e una linea tratteggiata come la risposta, ma punta nella direzione opposta.
  • deleteMessage segnala il momento in cui un’istanza della linea di vita viene distrutta. Potete disegnare il messaggio di cancellazione come una freccia, opzionalmente con il tiolo <>. Deve sempre indicare una Destruction Occurrence Specification. Chiamato anche evento di distruzione, questa specifica dell’occorrenza dell’evento segna la distruzione di un oggeto sulal linea di runtime con una X.

Messaggi di qualsiasi tipo potrebbero non avere mittente o destinatario o potrebbe essere sconosciuto. Lo standard UML presuppone quindi che la rispettiva istanza si trovi al di fuori dello schema descritto. Se conoscete il destinatario ma non il mittente, si tratta di un messaggio trovato. Là dove solitamente si indica il mittente, un piccolo cerchio pieno segnala la sua assenza. Con il messaggio perso funziona esattamente al contrario: se non conoscete il destinatario, modellate un cerchio pieno sulla punta della freccia.

Ci sono anche messaggi particolari come quelli inviati sulla propria linea di vita. La linea di vita invia quindi la ricorsività da una barra delle attività. Una nuova attivazione si attiva sulla stessa linea di vita anche mentre l’attivazione è ancora in corso. Il suo punto di partenza accetta il messaggio inviato. È possibile utilizzare questo tipo di messaggio, ad esempio, quando un’operazione viene eseguita più volte e l’oggetto deve quindi fare riferimento a se stesso. I messaggi tra due linee di vita possono anche produrre attivazioni sovrapposte. Di seguito daremo un’occhiata più da vicino alle specifiche per le attivazioni.

Un’altra parte importante del messaggio è il suo parametro: i parametri sono specifiche di valore. Il sistema valuta queste dimensioni quando invia un messaggio con una firma. Ciò accade nella specifica della prestazione, cioè nel punto in cui viene inviato il messaggio. Il risultato specifica i valori per gli attributi del segnale o i parametri di input dell’operazione a seconda del destinatario. L’operazione quindi elabora ulteriormente il valore e produce un parametro di output.

Una caratteristica speciale è il parametro jolly (wildcard): se al messaggio mancano tutti i parametri, la sintassi richiede una stringa vuota. Questo simbolo indica che il valore del parametro non è impostato, tuttavia è valido nel senso dei parametri o degli attributi del destinatario, comportandosi come un Joker. I caratteri jolly sono dei metacaratteri per singole lettere o intere stringhe. Molti conoscono l’asterisco (*) in quanto metacarattere. In UML è il trattino (“-”) a fungere da simbolo jolly, ovvero da metacarattere.

I messaggi di risposta possono avere solo un’espressione per parametro con al massimo un operando. Se il mittente di una risposta non emette alcun valore, anche il messaggio non ha valori specifici da inviare. Normalmente il messaggio modella i parametri di output di un mittente (cioè i valori che risultano da un’operazione) come operandi. Senza un parametro di output, l’operando deve rimanere vuoto. In questo caso semplicemente non modellate alcun valore di ritorno, ma il metacarattere jolly. Se è presente un operando, il sistema lo valuta nuovamente alla specifica dell’aspetto. Il risultato della valutazione specifica i valori per il parametro “out”, “inout” e “return”.

Fatto

I parametri IN, OUT e INOUT indicano se un’istanza accetta o restituisce valori. Il parametro IN indica che un’istanza sta ricevendo ed elaborando i valori ma non li sta inviando. Il parametro OUT specifica che non assume valori, ma li emette soltanto. Il parametro INOUT consente sia i valori in entrata che in uscita. Se non si definisce nessuno di questi valori, il sistema IN sarà quello predefinito.

L’UML specifica tre simboli che definiscono il destinatario del messaggio come espressione del parametro. Il destinatario è il cosiddetto obiettivo di assegnazione del messaggio (in inglese: Assignment Target). Il messaggio di risposta assegna il valore di ritorno del parametro di output del mittente. Questi sono i simboli standardizzati:

  • Unknown
  • Interaction Parameter
  • Attribute

Unknown (sconosciuto) è un parametro vuoto e rappresenta il carattere jolly. Il parametro di interazione (Interaction Parameter) è un ownedParameter dell’interazione alla quale appartiene. Cioè l’interazione possiede il parametro, il quale ha un nome. I parametri di operazione e i parametri di interazione hanno lo stesso tipo. Gli attributi possono essere nominati senza restrizioni e rappresentano il nome di un comportamento di contesto che determina la linea di vita a cui il messaggio ritorna o l’interazione circostante. Se l’interazione non definisce il comportamento, agisce essa stessa come un contesto.

I gates, ovvero le porte, sono semplicemente punti alla fine di un messaggio. Appartengono al tipo MessageEnd (fine del messaggio) e segnano il mittente e il destinatario di un messaggio. I gates chiariscono il flusso di informazioni e mostrano come si muovono i messaggi tra due frammenti di interazione. In particolare rappresentano punti di connessione per i messaggi tra gli utilizzi delle interazioni e le interazioni, nonché tra operandi di interazione all’interno e all’esterno di un frammento combinato. Si pongono sulla cornice del diagramma.

Il diagramma di sequenza UML ha quattro tipi di gates che differiscono a seconda dei frammenti di interazione a cui sono associati:

  • La porta fattuale: gli utilizzi dell’interazione rinviano da un diagramma all’altro. La porta fattuale (in inglese: Actual Gate) apre la connessione con il bordo esterno dell’interazione per messaggi al di fuori dell’interazione, alla quale rimanda l’utilizzo dell’interazione. La porta ha perciò un’associazione con l’utilizzo dell’interazione e accetta i messaggi in entrata e in uscita.
  • La porta formale: affinché un’interazione sia in grado di scambiare messaggi con un utilizzo di interazione, è necessaria una porta formale (in inglese: Formal Gate). Essa si trova all’interno del frame.
  • La porta interna per frammenti combinati: all’interno di un frammento combinato si trova un gate al frame che scambia i messaggi con estremità di messaggi dal frammento combinato con messaggi con estremità dei messaggi all’esterno del frammento combinato. In inglese prende il nome di Inner Combined Fragment Gate).
  • La porta esterna per frammenti combinati: questa porta si trova all’esterno di un frammento combinato. Essa forma il polo opposto alla porta interna (in inglese: Outer Combined Fragment Gate).

Le porte hanno nomi espliciti o impliciti che devono corrispondere in coppia. Le porte fattuali e formali devono coincidere, così come le porte interne ed esterne per i frammenti combinati. Inoltre i messaggi devono andare nella stessa direzione e avere gli stessi inconfondibili valori di proprietà nonché lo stesso MessageSort.

Un ruolo particolare è giocato dai messaggi nei diagrammi di comunicazione. Questo tipo di diagramma è una forma semplice del diagramma di sequenza. I diagrammi di comunicazione modellano il modo in cui interagiscono le linee di vita. A differenza dei diagrammi di sequenza, si concentrano sull’architettura del sistema e su come essa influisca sul flusso dei messaggi.

Sebbene sia possibile mostrare un’architettura dettagliata, i frammenti di interazione come i frammenti combinati non la utilizzano. Di conseguenza manca un elemento strutturale. Invece, numerate i messaggi: talvolta i messaggi possono traghettarne altri. L’ordine dei messaggi in uscita differisce dall’ordine dei messaggi in arrivo. Tuttavia lo standard UML non consiglia tali messaggi non sequenziali nel diagramma di comunicazione.

La notazione UML del diagramma di comunicazione detta un semplice diagramma di sequenza: un rettangolo con un’etichetta pentagonale nell’intestazione. L’etichetta “sd” contrassegna questo tipo di diagramma. Inoltre notate il nome dell’interazione: i messaggi qui hanno una forma diversa e collegano le linee di vita rettangolari (UML: nodi oggetto) come linee semplici (UML: linee).

Annotate la descrizione della sequenza (in inglese: Sequence Expression) insieme a una freccia rivolta verso il ricevitore. Il nome della sequenza ha la seguente forma: [Integer|Name] [Repetition]. L’integer specifica la gerarchia degli elementi nidificati. Se uno dei due Integer (ad esempio 1.2.2 e 1.2.3) si differenzia in due messaggi, il sistema li manda uno dopo l’altro. Il nome d’altra parte significa trasmissione simultanea. Il sistema manda due messaggi con i nomi di sequenza 1.2.3a e 1.2.3b in modo simultaneo per via dell’identico Integer. La ripetizione contiene una restrizione che determina quando viene mandato il messaggio o un valore che determina quanto spesso il messaggio viene ripetuto.

Guards

In UML la Guard controlla il comportamento di un elemento, che deve:

  • Soddisfare una determinata condizione
  • Non superare o scendere al disotto di un determinato valore o
  • Confermare un’affermazione

Pertanto una Guard è una limitazione: solo quando il vincolo è soddisfatto, l’elemento interessato può eseguire un determinato comportamento. Ci sono molti diversi elementi che possono avere una tale guardia: azioni, attributi, comportamenti e altri. L’UML non prescrive precisi criteri di linguaggio, ma offre OCL, l’Object Constraint Language, come opzione nativa. Vengono spesso utilizzate anche le variabili booleane.

Una restrizione di interazione di questo tipo consiste in una tale espressione booleana. Il vincolo funge da custode per l’operando all’interno di un frammento combinato. Solo se il valore del vincolo è vero, il frammento di interazione che lo circonda inizia il proprio comportamento. Annotate la limitazione tra parentesi quadre sulla linea di vita sopra una specifica di esecuzione. La standardizzazione consente frammenti combinati senza limiti di interazione. In questo caso il sistema presuppone che i messaggi in arrivo siano veri.

Frammenti di interazione nei diagrammi di sequenza

Quando create un diagramma di sequenza le linee di vita e i messaggi sono i componenti più importanti. L’UML2 raccomanda una cornice per questo tipo di diagramma, tuttavia non è obbligatorio. La cornice (frame) limita un processo secondario, il cosiddetto frammento di interazione. Tutte le linee di vita e i messaggi necessari si trovano all’interno del frame. Esso consiste in un rettangolo con un’etichetta nell’angolo in alto a sinistra. L’indicatore per un diagramma di sequenza è l’abbreviazione sd, solitamente in grassetto. Accanto si inserisce il nome dell’interazione come mostrato nell’immagine qui sotto.

Oltre al limite ottico il frame serve anche ad aspetti funzionali. Se si creano più diagrammi di sequenza (o altre interazioni), il frame delimita le rappresentazioni una dall’altra. Se desiderate che i vari frammenti di interazione comunichino tra di loro, modellate un messaggio (freccia piena) sul bordo del frame. Nella figura sopra il sistema manda il messaggio 5 verso l’esterno. Il punto in cui la freccia incontra il frame è chiamato gate (porta). Esso ha una funzione all’interno del diagramma, ma non ha una propria notazione.

In UML i frammenti di interazione appartengono ai nodi. Questo concetto sovraordinato è inteso in modo molto generale. Le proprietà e i compiti dei nodi sono specificati da UML a seconda dei rispettivi tipi di diagramma nel quale si incontra uno specifico nodo. In generale si può dire che i nodi sono elementi di modello all’interno di un sistema o processo sul quale si può installare un artefatto. L’UML connette i nodi attraverso linee che rappresentano lo scambio di informazioni o graficamente attraverso le frecce o semplicemente con delle linee.

In UML si possono creare diagrammi di sequenza che contengono parti annidate. I frame aiutano a rappresentare in modo ordinato i singoli frammenti.

I diagrammi di sequenza possono contenere i frammenti di interazione utilizzo di interazione, invarianti di stato, specifiche di occorrenza eventi, specifiche di esecuzione e frammenti combinati.

Usi dell’interazione

Gli utilizzi di interazione costituiscono una sottoclasse che stabilisce e prescrive la notazione, la costruzione e il comportamento di due metaclassi. Queste metaclassi sono l’uso dell’interazione e la parziale decomposizione.

L’utilizzo dell’interazione come metaclasse è un frammento di interazione che richiama o utilizza un’altra interazione. Se il diagramma di sequenza si fa troppo complesso, in questo modo potrete ottenere maggiore chiarezza. Infatti potete visualizzare l’interazione alla quale l’uso dell’interazione rimanda nel diagramma attuale in una black box. Per identificare l’interazione richiamata in modo inequivocabile scrivete nel corpo (campo nel quale le istanze eseguono le operazioni) la seguente sintassi:

  • Nome dell’attributo (attributo di una linea di vita nell’utilizzo dell’interazione che riceve il valore di ritorno)
  • Nome della collaborazione (uso della collaborazione identificato che connette interazioni e collaborazioni l’una all’altra)
  • Nome dell’interazione dell’elemento richiamato
  • io-Argument: argomenti in/out dell’interazione
  • valori di ritorno (risposta dell’interazione richiamata)

Potete modellare l’uso dell’interazione come rettangolo con un’etichetta pentagonale nell’angolo in alto a sinistra. Lì scrivete l’abbreviazione “ref” (dall’inglese: “referral”).

Poiché l’utilizzo dell’interazione punta su altri diagrammi, questi fattori esterni determinano il loro comportamento. Mentre l’interazione collegata attinge a porte formali (in inglese gates), l’interazione di rimando dispone della porta reale.

La scomposizione parziale (in inglese: part decomposition) è appunto la divisione parziale e sequenziale di una linea di vita all’interno di un’interazione attraverso un’altra interazione. L’utilizzo di tale scomposizione consente di separare i dettagli l’uno dall’altro e di poter quindi osservare più da vicino le singole sotto-funzioni. Sia che i messaggi dalla linea di vita decomposta siano in entrata che in uscita sono considerati porte effettive. Essi sono collegati alle porte formali dell’azione di decomposizione. I gate e i parametri di entrambi gli elementi devono corrispondere. Come uso dell’interazione, la scomposizione parziale ha anche l’etichetta “ref” ed è definita dall’interazione connessa.

Barra delle attività/specifiche di esecuzione

La barra delle attività, in inglese execution specification (detta comunemente anche semplicemente attivazione), indica il tempo su una linea di vita in cui un oggetto esegue un comportamento o passa attraverso un’azione. Modellate inoltre anche il tempo in cui un oggetto coinvolto invia un messaggio o attende una risposta, poiché la barra delle attività indica un periodo di tempo astratto durante il runtime. Come per l’intero diagramma, il tempo non è una grandezza assoluta, ma relativa. Anche il comportamento passivo, come l’attesa di una risposta, deve essere inserito come attivazione nel diagramma di sequenza.

L’UML rappresenta la semantica di una specifica di esecuzione con la struttura semplice <start,end>. La notazione per la execution specification consente due forme. Modellate un rettangolo lungo e stretto con riempimento grigio sulla linea di vita. Normalmente l’attivazione in questo modulo non implica un’etichetta nel corpo. In alternativa tracciate un rettangolo bianco leggermente più largo sulla linea di vita. Lì avete lo spazio per etichettare la barra delle attività. Se un oggetto esegue un’azione durante il runtime, specificate il nome dell’azione.

L’inizio e la fine segnano le specifiche dell’occorrenza dell’evento, in breve specifiche dell’occorrenza (in inglese: Event Occurrence Specification). All’inizio di un’attivazione sta l’evento di inizio, alla fine l’evento di chiusura. Questi frammenti rappresentano ciascuno un singolo momento ed esistono su un’unica linea di vita. La specifica dell’occorrenza dell’evento rappresenta l’inizio o la fine di un’azione. La specifica di occorrenza del messaggio (Message Occurence Specification) fornisce il segnale per inviare e ricevere un messaggio. Pertanto il loro valore dipende sempre dal messaggio o dall’azione.

L’attivazione non ha una notazione separata. Esiste implicitamente ai bordi esterni del rettangolo della specifica di esecuzione. Quando la specifica di esecuzione subisce un’azione atomica, le associazioni iniziale e finale si riferiscono alla stessa specifica di occorrenza. È possibile evidenziare ciò con una linea di collegamento tra l’azione e le specifiche di occorrenza in entrata.

Fatto

Un’azione atomica appare come una blackbox. È una sequenza indivisibile che consta di diverse semplici operazioni che non si possono osservare perché sono eseguite in maniera estremamente veloce. Un’azione atomica viene quindi completata quasi immediatamente.

Mentre altre specifiche di occorrenza non richiedono alcuna notazione, contrassegnate le distruzioni delle specifiche di occorrenza dei messaggi con una X maiuscola. Essa contrassegna la risoluzione di un’istanza di oggetto in un punto particolare sulla linea di vita. La linea di vita si conclude con essa. Le istanze subordinate o le specifiche delle occorrenze in punti successivi della timeline non sono quindi valide. Dopo la distruzione dell’oggetto non esistono più.

A volte le specifiche di esecuzione si sovrappongono. Ad esempio, se un oggetto invia un messaggio a se stesso, una execution specification invia un messaggio a un’altra istanza di quella classe. Entrambe le specifiche sono talvolta simultaneamente sulla stessa linea di vita. Nel diagramma di sequenza UML rappresentate questa circostanza con rettangoli che si sovrappongono.

State invariant

La State Invariant (o invariante di stato) è un vincolo di runtime. La linea di vita rappresenta un oggetto. Durante il runtime questo oggetto cambia il proprio stato attraverso la specifica di esecuzione. L’invariante di stato esamina l’oggetto per il suo cambiamento di stato nella specifica di esecuzione appena prima di eseguire la successiva specifica di occorrenza. Tutte le precedenti azioni implicite all’interno della specifica di esecuzione sono considerate eseguite.

La state invariant specifica un valore limite. Se questo valore è uguale allo stato dell’oggetto, la traccia è valida. Se l’oggetto non soddisfa la restrizione, la sua traccia non è valida.

In base alla notazione del diagramma di sequenza UML, l’invariante di stato è tra parentesi graffe sulla specifica di esecuzione. In alternativa potete utilizzare il rettangolo arrotondato dello stato di classe.

Frammenti combinati

I frammenti combinati appartengono ai frammenti di interazione. Questi frammenti sono elementi astratti del sistema e rappresentano le unità di interazione. Ciò significa che fanno parte di un’interazione. D’altra parte sono anche esse stesse piccole interazioni. I frammenti combinati in un diagramma di sequenza determinano il comportamento di più frammenti di interazione. Ma loro stessi formano soltanto il frame. Dunque sono definiti da operatori di interazione e operandi di interazione. Gli operandi contengono uno o più messaggi. Sulla linea di vita di fronte a un frammento combinato una restrizione, chiamata anche guard, sorveglia l’operando contenuto.

Come precedentemente descritto, gli operandi sono quantità costanti o variabili che subiscono un processo. Gli operatori influenzano il comportamento degli operandi. Ad esempio, l’operatore booleano OR può prescrivere che siano eseguiti l’operando A o l’operando B (o entrambi). All’interno di un frammento combinato un operando stabilisce che un particolare messaggio venga inviato a determinate condizioni. L’operatore determina quali relazioni hanno gli operandi all’interno di un frammento e la loro relazione con il frammento principale.

Operatori di interazione

L’UML definisce 12 operatori di interazione.

Alternative:

Nell’ambito del frammento combinato con l’operatore di interazione “Alternative”, un frammento subordinato può inviare un solo messaggio se viene soddisfatta una particolare condizione. Altrimenti un frammento concorrente all’interno del frame invia il proprio messaggio. Nella figura sopra potete vedere un esempio di un frammento combinato con l’operatore “Alternativa”. Per l’etichetta si usa l’abbreviazione “alt”. Il frame rettangolare è diviso da una linea tratteggiata orizzontale. L’area superiore rappresenta una condizione.

Guard:

La Guard (guardia) controlla se la condizione dell’operando è soddisfatta. In tal caso il sistema invia un messaggio nell’area delle condizioni. In caso contrario invia un messaggio nell’area dell’alternativa. Un operando all’interno di questo frammento combinato ha sempre bisogno di una guardia giudicata veritiera (“true”) per essere eseguito. Se l’operando delle condizioni non ha una esplicita guard, si assume una guardia implicita. Questo frammento rappresenta quindi sempre una decisione aut aut.

Option:

Questo frammento combinato nel diagramma di sequenza va modellato come l’alternativa, poiché l’option (opzione) rappresenta anche una decisione. Tuttavia c’è un solo operando. La decisione quindi riguarda se l’operando debba essere eseguito o meno. L’operando con una condizione non può essere vuoto, mentre la sua alternativa è vuota. Un frammento con l’operatore di interazione “Option” è contrassegnato dall’etichetta “opt”.

Interruzione:

Un frammento combinato interrompe il frammento sovraordinato con l’operatore di interazione “break”. Se una linea di vita soddisfa la condizione dell’operando, il sistema esegue il frammento combinato. In questo modo ignora il resto del frammento sovraordinato. Affinché tutte le linee di vita possano esaurire la durata della propria vita, occorre includere ciascuna linea di vita nel frammento combinato. Altrimenti, una linea di vita potrebbe fermarsi nel mezzo di un processo senza essere adeguatamente distrutta. Se il frammento break manca di una guardia, la decisione è non deterministica. Pertanto consigliamo di utilizzare una guard.

Fatto

Il non determinismo è un concetto di informatica teorica che mira a semplificare la modellazione. Allo stesso tempo un sistema ha più di un modo per ottenere lo stesso risultato a partire da uno stesso valore di partenza. Nella pratica vengono utilizzati prevalentemente algoritmi deterministici con un solo percorso di calcolo. Un algoritmo non deterministico, d’altra parte, prende un percorso imprevedibile nel calcolo, anche se si avvia il sistema con le stesse informazioni. Poiché l’algoritmo produce risultati significativamente più diversi rispetto a un algoritmo deterministico, il compito dovrebbe essere meno complesso. I modelli astratti semplificano i sistemi complessi. Pertanto sono adatti per prefigurare diversi calcoli con l’algoritmo non deterministico.

Il ciclo:

Un frammento combinato con l’operatore di interazione “loop” ripete il proprio operando. Il numero esatto di passaggi è determinato dalla guardia. La guard può includere porte di ripetizioni e variabili booleane. Nell’etichetta del frame annotate i limiti di ripetizione come segue: loop (X,Y). Le variabili X e Y indicano ciascuna un numero naturale. X è il numero minimo di ripetizioni (“min-int”), mentre Y è il numero massimo di ripetizioni (“max-int”). X deve essere un numero non negativo, mentre Y deve essere un numero non negativo maggiore o uguale a 0.

In alternativa potete annotare la variabile booleana nel corpo del frame accanto all’etichetta. Essa limita ulteriormente la ripetizione. Se la condizione della variabile booleana non è più soddisfatta e viene raggiunto il numero minimo di ripetizioni, il ciclo si arresta. Annotate la restrizione tra parentesi quadre. Questa restrizione si riferisce a fattori esterni come gli input di un attore.

A un bancomat si dispone, ad esempio, la possibilità di inserire il PIN tre volte. Se il PIN è sbagliato, vi verrà richiesto di riprovare. Nel diagramma di sequenza UML, annotate il messaggio “Inserire PIN” e la relativa risposta “PIN errato. Riprovare” con le frecce corrispondenti. L’etichetta ha la forma del loop (0,2). La variabile booleana è [PIN errato]. Se il PIN è errato, il ciclo si ripeterà due volte, mentre se è corretto, il sistema sbloccherà il ciclo. Se viene superato il numero massimo di tentativi, il ciclo si interromperà, ma il processo verrà annullato come non valido.

N.B.

Se non si specificano i limiti di ripetizione, il minimo è 0 e il massimo è infinito. Se il minimo e il massimo hanno lo stesso valore, dovete inserire un solo limite.

In parallelo:

Di solito la posizione di una freccia sulla linea di vita nel diagramma di sequenza prescrive sempre un ordine cronologico. In un frammento combinato con l’operatore di interazione “in parallelo”, i suoi operandi sono autorizzati a eseguire i loro processi contemporaneamente.

Potenzialmente gli operandi intrecciano il loro ordine di processo. Tuttavia l’ordine specificato all’interno degli operandi viene sempre mantenuto. Nel diagramma di sequenza UML modellate questo frammento combinato con un frame solido. Separate visivamente i diversi operandi con linee tratteggiate, simili a quelle dell’alternativa. Nell’etichetta inserite l’abbreviazione “par” (vedi l’illustrazione in Critical Region). Se gli operandi devono lavorare in parallelo su un’unica linea di vita, l’UML consente una scorciatoia: la co-region svolge esattamente questo compito. Per farlo riepilogate semplicemente le voci degli eventi interessati con una parentesi quadra.

Sezione critica:

Utilizzando una sezione critica il sistema evita che possano errori verificarsi quando più processi condividono le risorse. All’interno di questa area di sistema solo un processo alla volta utilizza la risorsa. Inoltre il sistema dà la priorità al rispettivo processo. Con l’etichetta “critical” definite una sezione critica (in inglese: critical region). Ciò impedisce ad altri operatori di interazione di influenzare un frammento sovraordinato. Ad esempio blocca le tracce nidificate di un frammento parallelo e combinato nel diagramma di sequenza.

Una hotline del fornitore di gas nel grafico sopra accetta più chiamate in parallelo e le inoltra contemporaneamente ai dipendenti della hotline. Se si tratta tuttavia di un caso di emergenza con sospetto di odore di gas, il sistema dà la priorità al messaggio e inoltra la chiamata al servizio di emergenza attraverso la sezione critica (critical region). La sezione critica impedisce che i flussi di informazione del frammento sovraordinato vengano evasi in parallelo con il messaggio dalla sezione critica. Solo le linee di vita nella sezione critica si comportano in questo modo.

Assertion:

L’operatore di interazione “assertion” imposta lo stato di continuità. Le sequenze all’interno di un operando con l’etichetta assert sono considerate come valide continuazioni. L’asserzione afferma che tutte le sequenze al di fuori del frammento terminano in tracce non valide.

Ignorare/considerare

Un diagramma di sequenza UML rappresenta una parte del sistema in dettaglio. Mentre ci sono alcuni messaggi che potete tralasciare, ce ne sono altri di cui avete bisogno. Utilizzate l’operatore di interazione “ignore” per escludere alcuni messaggi. Queste informazioni emergono nel sistema su una traccia, ma non nel frammento ignore. La notazione prescrive un’etichetta in questa forma: ignore {messaggio1,messaggio2}.

I frammenti combinati con l’operatore di interazione “consider” invece considerano alcuni messaggi in un frammento. Tutti gli altri messaggi che passano attraverso il frammento vengono ignorati dal sistema. I messaggi da includere vanno anche loro racchiusi tra parentesi graffe: consider {messaggio3,messaggio4}.

Questi due operatori hanno compiti in conflitto. Tuttavia entrambi si verificano spesso in frammenti nidificati. Ad esempio i modellatori spesso associano assert a ignore (nella seguente forma: assert ignore {Msg1,Msg2}) o assert e consider (nella seguente forma: assert consider {Msg3,Msg4}).

Negativo:

Per contrassegnare un errore di sistema si utilizza l’operatore di interazione “negativo”. Il frammento combinato include quindi tracce non valide. Ad esempio l’operatore viene utilizzato nella rappresentazione di un processo di accesso attraverso un diagramma di sequenza. Modellate la linea di vita di un attore sulla strada per il time out e inquadrate questo messaggio di errore con il frammento negativo. L’etichetta per fare questo è neg. Attraverso la modellazione esplicita delle tracce non valide nel frammento combinato negativo tutti gli altri frammenti sono considerati positivi. Le loro tracce sono perciò valide.

Sequenza rigorosa:

All’interno di un frammento combinato potrebbe essere importante rispettare un ordine rigoroso. L’etichetta strict impone ai suoi operandi una sequenza rigorosa. Ciò vale per il primo livello del frammento. Gli operandi negli altri frammenti nidificati sono soggetti al loro ordine proprio.

Sequenza debole:

I frammenti combinati con l’operatore di interazione sequence rappresentano un ordine debole. Il comportamento tra gli operandi influisce sulle proprietà di traccia piuttosto che sugli operatori di interazione. Pertanto un sequenziamento debole può agire come un frammento parallelo. Ciò accade quando gli operandi partecipano a diverse linee di vita. A propria volta il sequenziamento debole diventa un ordine rigoroso quando i suoi operandi appaiono sulla stessa linea di vita. L’etichetta è seq.

Il sequenziamento debole è definito dalle seguenti proprietà:

  1. Le specifiche degli eventi all’interno di un operando mantengono il loro ordine.
  2. Le specifiche degli eventi che operano su differenti linee di vita e non si verificano all’interno dello stesso operando compaiono in ordine arbitrario.
  3. Se le specifiche dell’evento agiscono sulla stessa linea di vita ma in diversi operandi, il loro posto sulla linea di vita prescrive il loro ordine. Il primo operando viene prima del secondo.

Continuazione:

La continuazione (in inglese: continuation) non è certo un frammento indipendente. Soltanto nei frammenti combinati alternativa e sequenza debole ottiene la propria semantica, la quale prescrive alla continuazione la stessa forma degli stati: un rettangolo con angoli arrotondati. In opposizione allo stato, una continuazione copre opzionalmente diverse linee di vita.

A seconda di come organizzate la continuazione nel diagramma di sequenza, cambia anche il loro compito. Se la continuazione è all’inizio del diagramma di interazione, modellate il comportamento della continuazione. Se invece la continuazione è alla fine del vostro frammento di interazione, essa inoltra il processo al passo successivo. Se assegnate un nome alla vostra continuazione (come nell’esempio: nonOK), il frammento successivo sulla linea di vita deve avere una continuazione con lo stesso nome (nonOK) o non potrà modellare alcuna continuazione. Se la continuazione è da sola nel frammento, ciò corrisponde a una continuazione alla fine del frammento.

In sintesi

Se volete rappresentare gli esempi di applicazione in modo dettagliato o controllare la logica di un sistema, create un diagramma di sequenza. La notazione vi consente di modellare il flusso del messaggio nel corso della durata di un oggetto. Potete anche rappresentare le operazioni complesse in modo chiaro utilizzando frammenti di interazione nidificati. Il diagramma di sequenza è senza dubbio uno dei diagrammi comportamentali UML più utilizzati.

Hai trovato questo articolo utile?
Per offrirti una migliore esperienza di navigazione online questo sito web usa dei cookie, propri e di terze parti. Continuando a navigare sul sito acconsenti all’utilizzo dei cookie. Scopri di più sull’uso dei cookie e sulla possibilità di modificarne le impostazioni o negare il consenso.
Page top