Diagrammi di attività: mostrare in modo chiaro i processi cronologici delle attività con UML
Il diagramma di attività è un tipo di diagramma all’interno dell’Unified Modeling Language (UML). Questo linguaggio di modellazione grafica definisce le forme per rappresentare la programmazione orientata agli oggetti e specifica 14 tipi di grafici. A ognuno di questi sono assegnate forme specifiche. Utilizzando le regole di notazione si possono astrarre sistemi e processi e visualizzarli in modo chiaro. L’UML non solo modella i sistemi software, ma anche i processi aziendali. I diagrammi delle attività sono particolarmente utili in entrambe le aree. Ma per quale scopo si dovrebbe creare un diagramma di attività?
Il fine dei diagrammi di attività
I diagrammi di attività UML (in inglese activity diagrams) appartengono all’insieme di diagrammi comportamentali in UML. Mentre un diagramma di struttura cattura lo stato di un sistema, cioè gli oggetti esistenti e le loro gerarchie, nonché le interconnessioni in un determinato momento, i diagrammi comportamentali descrivono lo scorrere cronologico dei flussi di dati. Accanto al diagramma di attività, appartengono a questo gruppo il diagramma del caso d’uso (use case diagram) e il diagramma di stato (state machine diagram). I diagrammi di attività sono simili nel loro uso e notazione ai diagrammi di flusso ma sono adatti alla programmazione orientata agli oggetti.
In sostanza si può dire che il diagramma di attività modella il corso delle attività. Si può trattare di processi all’interno di un sistema informatico, decorsi use case o aziendali. Ad esempio l’attività “preparare un’omelette al formaggio” si suddivide in molti altre sottoattività: le azioni. Esse possono sottostare a un ordine cronologico. Un’azione sarebbe ad esempio “sbattere le uova”, seguita dall’azione “condire l’uovo con sale e pepe”. La prima azione rende possibile la seconda, sono perciò connesse in una sorta di flusso.
Si possono tuttavia anche immaginare flussi paralleli. Quando due persone si occupano della preparazione di una frittata, è possibile svolgere simultaneamente le due azioni “fare le uova” e “tagliare le erbe”. In questo modo l’attività ha due punti di partenza, da cui le persone partono con le proprie attività, passando da un’azione a quella successiva.
In un caso di uso queste persone sarebbero attori. In un diagramma di attività hanno sicuramente un ruolo importante, ma non hanno alcuna notazione. Si spostano da un punto iniziale a un punto finale attraversando i flussi di controllo o di oggetti per passare da un’azione alla successiva. In mezzo ci sono barriere occasionali, i cosiddetti pin, che accadono solo a determinate condizioni, ad esempio quando entrambe le persone sono presenti.
Nel diagramma delle attività queste “persone” si chiamano token. Esistono due tipi di token nel diagramma di attività UML: il primo è il token dell’oggetto, che trasmette le informazioni al nodo dell’azione, dove avvia un’azione e (se specificato) memorizza il risultato come valore. Se il risultato e il token corrispondono alle specifiche impostate in un pin, questo pin di output invia il token dell’oggetto all’azione successiva attraverso un flusso di oggetti. Per poter iniziare questa azione il token deve essere conforme alle specifiche del pin di input. I token di controllo, d’altra parte, si muovono solo attraverso i flussi di controllo e fungono da indicatori. Iniziano un’azione ma non inviano dati.
Nell’esempio descritto, ovvero “preparare un’omelette al formaggio”, utilizziamo il diagramma di attività per rappresentare il corso cronologico di un caso di uso. I programmi del caso di uso invece rappresentano i requisiti di sistema necessari nel caso di applicazione.
I diagrammi di attività UML 2 naturalmente si possono utilizzare anche per altri scopi oltre a quelli delle attività quotidiane. Innanzitutto ci aiutano a rappresentare i processi in modo strutturato nei sistemi software. Ad esempio gli analisti aziendali li utilizzano per rendere le specifiche per gli sviluppatori di software. Con il linguaggio grafico gli esperti si scambiano informazioni su un livello generalmente comprensibile e chiaro. Una volta che tutti i processi sono stati chiariti e gli errori risolti, il diagramma delle attività serve da modello pulito per la programmazione.
Se si integra uno strumento UML adatto nel proprio ambiente di sviluppo integrato, il diagramma può fungere da quadro di codice mediante conversione XML in un linguaggio di programmazione.
L’Object Management Group (OMG) che specifica l’UML, riassume i possibili compiti dei diagrammi di attività UML 2 come segue:
- programmazione computerizzata procedurale che assegna attività alle gerarchie
- nei modelli orientati agli oggetti, le attività agiscono come metodi che descrivono più dettagliatamente i processi
- rappresentazione dei flussi di lavoro e dei processi aziendali
- per le attività dei sistemi applicativi computerizzati le attività specificano i processi a livello di sistema
Le notazioni per i diagrammi di attività UML
Le forme all’interno dell’UML possono essere intese come componenti di frasi della lingua. Pertanto il linguaggio di modellazione assegna importanza a ciascuna forma. I modificatori descrivono questi in modo più dettagliato e li mettono in relazione tra di loro. Inoltre gli stampi talvolta richiedono certe altre forme o etichette per creare un diagramma significativo. Proprio come la lingua parlata ha senso solo se vengono rispettate alcune regole grammaticali di base, l’UML funziona come mezzo di comunicazione solo se ci si attiene alle specifiche.
UML 2.5 è la specifica più recente del linguaggio di modellazione e pertanto costituirà la base di queste spiegazioni. L’UML definisce la notazione dei tipi di grafici in base alle loro aree di applicazione. Poiché il diagramma di attività UML mappa il flusso dei processi di sistema nei casi d’uso, la metamodellazione assegna loro le forme corrispondenti.
Come vengono rappresentati visivamente i singoli componenti e quali funzioni assolvono i simboli nei diagrammi di attività UML?
Attività
UML 2 specifica un’attività (activity in inglese) come comportamento che assegna un ordine di successione alle unità sottostanti (azioni e oggetti). Per farlo si utilizzano modelli di dati e di flusso di controllo. Il diagramma di attività può essere rappresentato come parte di un sistema più vasto in combinazione con altri tipi di diagrammi. Un grande rettangolo arrotondato contrassegna l’attività come sistema chiuso (si può anche tralasciare). Nella parte inferiore dell’immagine potete vedere l’attività “cuocere gli asparagi”. Scrivete il titolo nella testa del rettangolo grande. Il corpo a propria volta contiene frecce e nodi (rettangoli), che simboleggiano in dettaglio azioni, oggetti e controllo o flusso di dati dell’attività.
Le attività in UML valgono come classi (la cui metaclasse è il comportamento). In questo modo si possono definire più precisamente attraverso le proprietà e ciò può influenzare gli elementi subordinati. Un’attività viene considerata completata quando un token si è spostato dal punto di partenza attraverso le azioni fino all’endpoint. L’endpoint distrugge poi il token. Ciò vale anche per tutti gli altri token, e in questo modo l’attività ferma tutte le azioni sincrone.
UML 1 definisce i diagrammi di attività in modo diverso rispetto a UML 2. La versione precedente assegnava loro il ruolo di un diagramma di stato specializzato che ne restringeva i loro usi. Se usate un Tool UML, dovete accertarvi che supporti la formulazione desiderata, idealmente la versione UML 2.5 o successive.
Azioni: nodi di attività che rappresentano il comportamento
Un’azione (in inglese: action, executable node) è un elemento del modello gerarchicamente subordinato all’attività: l’azione è un’istanza della classe “attività”. Le azioni rappresentano un comportamento all’interno di un sistema. Sono i mattoni di base utilizzati per esprimere il comportamento in UML. Sono utilizzati nei diagrammi di attività e nelle interazioni.
Quando create un diagramma di attività utilizzate la notazione “azione” per rappresentare le parti eseguibili di un’attività. Nell’esempio sopra l’azione “Pelare gli asparagi e metterli in pentola” è un paso nel processo di completamento dell’attività “cuocere gli asparagi”. Le azioni prendono informazioni di input, le elaborano e producono informazioni di output. Un’azione non si arresta finché non è completata.
All’interno dei diagrammi di attività UML le azioni appartengono ai nodi di attività. Le frecce collegano le azioni tra loro. UML distingue tra i flussi di oggetti (flussi di dati) e i flussi di controllo (che trasportano i token di controllo). Le azioni gestiscono solo i flussi di controllo. Se ci sono flussi di dati che migrano tra le azioni, i pin (nodi oggetto) accettano i token oggetto come input, li convertono per l’elaborazione nell’azione e quindi generano l’output dell’oggetto che prosegue come token oggetto.
La categoria del nodo attività è stata introdotta in UML 2. Ne esistono tre sottotipi: nodi di controllo, nodi oggetto e nodi eseguibili (le azioni). Tra questi tre sottotipi non ci sono gerarchie: finché non sono collegati uno all’altro o definiti all’interno di un gruppo di attività, possono essere eseguiti in qualsiasi ordine (ovvero non appena i token in arrivo soddisfano le condizioni specificate di un nodo) o in parallelo.
Soltanto quando le condizioni impostate sui pin vengono soddisfatte i dati eseguiranno un’azione (pin di input) o l’azione restituirà un risultato (pin di output). Anche se un’azione ha più flussi di controllo in entrata, ognuno deve offrire un token prima di iniziare un’azione.
Per azioni all’interno del diagramma di attività la sintassi astratta contiene la forma semplice del rettangolo arrotondato. Tuttavia ci sono azioni specifiche che i modellisti possono usare per descrizioni più specifiche. Alcuni di questi esprimono UML con la sua notazione. Queste sono le sottospecie delle azioni:
- Opaque Actions, ovvero “azioni opache”. Fungono da segnaposto o sono specificate dalla concreta (non specificata da UML) sintassi del testo.
- Invocation Actions, azioni che causano un determinato comportamento, direttamente o indirettamente. Esse includono:
- call actions: una call behavior action chiama direttamente un comportamento. Una call operation action invece invia una richiesta a un oggetto che chiama un comportamento connesso. La start object behavior action porta direttamente un oggetto a eseguire il suo comportamento di istanza. Se non ne è specificato nessuno, può attivare il comportamento del classificatore sovraordinato (classifier behavior).
La notazione di un’azione che causa un comportamento consiste di un rettangolo arrotondato. Lì si inserisce il nome del comportamento che si intende richiamare. Inoltre le call behavior actions sono contrassegnate con un’icona a forma di tridente, come mostrato nell’immagine sotto, che è intesa a rappresentare l’ulteriore ramificazione gerarchica risultante dall’azione.
- Send actions: le azioni di invio nel diagramma di attività inviano dati sempre in modo asincrono (i diagrammi di sequenza, ad esempio, conoscono anche i messaggi sincroni). Ciò significa che non aspettano una risposta dall’oggetto di destinazione e quindi non bloccano il flusso degli oggetti. L’azione termina non appena il messaggio è stato inviato. Pertanto potrebbe effettivamente avere un argument input, come ad esempio i parametri, ma non produrre alcun result output. Inoltre i messaggi possono dirigersi direttamente a più destinatari. Appartengono a questo tipo send signal action, broadcast signal action e send object action.
Le send signal actions differiscono nella loro notazione dalla forma usuale (il rettangolo arrotondato): al suo posto un pentagono punta come una grande freccia in direzione del segnale trasmesso. Se il contenuto di una send objet action è costituito anche da un segnale, è possibile utilizzare la stessa notazione.
- Le object actions cambiano lo stato degli oggetti (cioè le istanze di una classe). Possono crearle o distruggerle, confrontarle con altre istanze e quindi assegnarle a una classe o modificare la classificazione. Di conseguenza in UML 2 esistono le seguenti istanze di azioni oggetto:
- create object actions, che generano istanze di una classe, cioè oggetti;
- destroy object actions, che distruggono l’oggetto sul pin di input;
- test identity actions, che esaminano se due valori sul pin di input rappresentano lo stesso oggetto;
- read self actions, che determinano il proprio oggetto di contesto;
- value specification actions, che esaminano le specifiche del valore. La notazione reca l’etichetta value specification;
- read extent actions che trovano tutti gli oggetti di una classe nonché gli oggetti delle loro specifiche. Per motivi pratici i modellatori di solito limitano la gamma;
- reclassify object actions che modificano la classe per l’oggetto sul pin di input;
- read is classified object actions per determinare se un oggetto sul pin di input appartiene a una classe;
- start classifier behavior actions che fungono per un oggetto da trigger per un comportamento determinato dalla relative classe. Il comportamento procede in modo asincrono.
- Le link actions modificano il comportamento delle associazioni (relazioni tra classifier, di solito due classi) e le loro istanze, i link. Questi includono:
- read link actions, che recuperano valori (link end data) su una pagina di un’associazione;
- create link actions, che creano link (non hanno pin di output perché i link in sé non sono dati) e link objects;
- destroy link actions che cancellano i link e link objects se corrispondono a un valore link end data specificato.
- Le link object actions, come le link actions, influenzano il comportamento dei link objects, ma guardano gli oggetti da angolazioni diverse. Ecco le istanze di link object actions:
- read link object end actions, che recuperano gli oggetti finali dai link object (o oggetti di collegamento);
- read link object end qualifier actions, che recuperano i valori finali del classifier dagli oggetti di collegamento;
- create link object actions, che sono particolari create link actions con le quali si creano oggetti di collegamento.
- Le structural feature actions stabiliscono il comportamento delle caratteristiche strutturali nei diagrammi di attività. Per questo hanno bisogno di un pin di input, dato che di solito sono sia un oggetto che una caratteristica strutturale specificata staticamente attribuita a un classifier. L’azione della caratteristica strutturale influisce su entrambi gli elementi. Ci sono i seguenti tipi:
- read structural feature action, che legge i valori delle caratteristiche strutturali e li passa come output;
- add structural feature value actions, che richiedono un value input pin. Esso specifica il valore che l’azione assegna a una caratteristica strutturale;
- remove structural feature value actions che sottraggono valore da una caratteristica strutturale. Un value input pin con molteciplità 1..1 specifica questo valore;
- clear structural feature actions, che rimuovono tutti i valori di un elemento della struttura.
- Le variable actions influiscono sulle variabili specificate staticamente che vengono definite da un’attività o da un nodo di attività strutturato (structured activity node). Ce ne sono tre tipi:
- add variable value actions, che necessitano di un value input pin. Esso deve essere dello stesso tipo della variabile e le aggiunge esattamente un valore;
- remove variable value actions, che rimuovono un valore specificato dal pin;
- clear variable actions, che rimuovono tutti i valori di una variabile.
- Le accept event actions appartengono ai cosiddetti punti di attesa (wait points). Ciò significa che l’azione è in attesa di un evento (event) dal pool di eventi dell’oggetto di contesto. L’azione possiede dei trigger che attivano l’azione quando si verificano uno o più stati tra quelli prescritti. L’UML descrive tre specializzazioni:
- accept call action, che hanno un trigger che accetta i call events (eventi di chiamata). Due result output pins e un return information output pin completano la disposizione. Se deve essere eseguita una reply action, le informazioni necessarie vengono memorizzate nel return information output pin.
- reply actions, che hanno una connessione con le accept call actions. Da un lato i trigger devono corrispondere in modo che l’azione di risposta in caso di un call event possa rispondere all’azione di accettazione della chiamata eseguita in precedenza. D’altra parte il comportamento sovraordinato colloca il valore di output nel return information input pin della reply action;
- le unmarshall actions interrogano i valori delle caratteristiche strutturali degli oggetti. Per riconoscere l’oggetto hanno un pin di input dell’oggetto. I valori ottenuti vengono emessi su un pin di output.
Se i dati strutturati di un oggetto o i dati elementari di un programma devono essere trasferiti ad altri programmi o parti di programmi o se si desidera memorizzarli, allora vengono convertiti in un formato adatto. Questo processo è chiamato marshalling (o marshaling). Il processo opposto, l’unmarshalling (o unmarshaling), ritrasforma questi dati “congelati” in oggetti eseguibili. Un esempio in merito è il trasferimento di diagrammi UML da uno strumento a un altro programma tramite la conversione XML.
- Le structured actions sono definite da UML 2 nei diagrammi di attività sia come azioni che come gruppi di attività (vedi sopra). Ciò significa da un lato che il loro comportamento è determinato da nodi e fronti di attività e dall’altro che certe sottospecie di queste azioni, in virtù della loro semantica, prescrivono un comportamento specifico per i nodi eseguibili, in particolare per quanto riguarda la loro sequenza.
Queste sono le sottospecie delle azioni strutturate:
- I conditional nodes (nodi condizionali) sono costituiti da una o più clausole che rappresentano i diversi rami delle possibili azioni eseguibili. Una clausola contiene un segmento test e un segmento body, i quali a propria volta comprendono nodi eseguibili privi di intersezioni. In primo luogo la clausola esegue l’azione nell’area di test. Se il suo valore di output è true, la clausola esegue l’azione nella regione body.
- I loop nodes (nodi di loop) descrivono un gruppo di azioni che si ripetono all’interno di un ciclo. Le azioni si suddividono in tre sezioni: setup, test e body. Il loop esegue sempre innanzitutto il setup, a cui seguono test o body, che quindi si ripetono alternativamente.
- I sequence nodes (nodi di sequenza) impongono un ordine sui nodi eseguibili all’interno dei loro confini. Questi li rappresentano con i flussi di dati come bordi di attività (ovvero semplici frecce). Le frecce possono puntare liberamente dentro o fuori rispetto alla struttura.
- Le expansion regions sono un’altra forma di nodi di attività strutturati. Accettano una o più raccolte di valori come input. Sulla via verso la regione di espansione il pin di input copia ciascun token in arrivo sul numero di elementi di raccolta. Tutti i nodi acclusi lavorano su ciascun valore della raccolta. Un’esecuzione vale come un’esecuzione di espansione (expansion execution). Un cosiddetto nodo di espansione (un tipo di nodo oggetto) indica l’interfaccia alla regione di espansione. Esternamente si visualizzano i loro valori come una raccolta, mentre all’interno i singoli elementi della collezione sono considerati valori. Per la notazione disegnate un rettangolo arrotondato con una linea tratteggiata. I nodi di espansione rappresentano rettangoli con segmenti e sono disegnati direttamente sulla linea, come mostrato di seguito. La segmentazione dovrebbe rappresentare l’elenco delle raccolte di valori.
- Le reduce actions (azioni di riduzione) stimolano un comportamento fino a quando da un insieme di valori si verifica un singolo valore. Per farlo l’azione combina gli elementi dell’insieme. L’azione ha quindi due parametri interni ma solo un parametro out o return.
- Le raise exception actions (azioni che causano un’eccezione) cessano autonomamente non appena causano un’eccezione. Perciò non terminano come azioni normali che finiscono quando l’azione è stata eseguita fino al suo completamento. Si espandono verso l’esterno attraverso il sistema fino al nodo di attività strutturato successivo. Se questo ha un gestore che corrisponde all’eccezione, l’azione si interrompe, altrimenti continua a diffondersi.
Nodi oggetto: nodi di attività che dirigono i token oggetto
I nodi oggetto sono sottoinsiemi dei nodi di attività. In generale, un oggetto in UML è l’istanza più piccola occupata dal valore. Nel diagramma di attività gli oggetti rappresentano i dati. Mentre un’azione viene eseguita, i nodi oggetto contengono tali dati. Perché solo i token di controllo possono portare direttamente a termine un’azione. I token oggetto, d’altro canto, entrano come valore su un pin di input e vengono passati dal pin di output al flusso dell’oggetto.
I nodi oggetto sono stati introdotti per la prima volta nel diagramma di attività UML 2. Sono elementi tipizzati. Se un nodo oggetto corrisponde a un tipo particolare, i token oggetto che viaggiano su di esso devono avere valori corrispondenti. Un’eccezione sono i token nulli che possono far a meno di un valore (sono conformi a qualsiasi nodo oggetto).
I noti oggetto prescrivono la successione in cui i token li abbandonano. Ci sono quattro modi per farlo:
- disordinato (non stabilito)
- ordinato (comportamento definito dal modellatore)
- FIFO (First In First Out): l’ordine di entrata e di uscita rimane lo stesso
- LIFO (Last In First Out): l’ordine è opposto (l’ultimo a entrare è il primo a uscire)
Se volete creare un diagramma di attività, potete scegliere tra quattro tipi di nodi oggetto per la modellazione:
- Il pin: ai pin si è già accennato in questa esecuzione. Il primo grafico mostrava la notazione base dei pin. A causa del loro ruolo di collegamento tra azioni e flussi di oggetti, i modellatori in genere li disegnano come piccoli rettangoli direttamente sull’icona di azione. I pin di input (anche input pins) sono contrassegnati da una freccia nella direzione dell’azione. Per i pin di uscita (noti anche come output pins), la freccia si allontana dall’azione. Il seguente grafico mostra come visualizzare i pin dello stesso tipo in modo abbreviato (a sinistra) o come disegnare i pin di input e output se si omettono le frecce (a destra).
- Nodo del parametro di attività: l’attività appartiene alla metaclasse della descrizione dei comportamenti. Secondo UML, ogni comportamento ha un parametro. Prima di eseguire un comportamento, è possibile immettere i valori per l’elaborazione. Dopo l’elaborazione riceverete i nuovi valori. I parametri in questa struttura sono i segnaposto che consentono l’immissione o l’emissione di questi valori. Il nodo del parametro di attività (activity parameter node) gestisce questa attività per il diagramma di attività UML. Pertanto i nodi dei parametri di attività sono sempre all’inizio e alla fine di un’attività. Di conseguenza tale nodo ha solo frecce di attività in entrata o in uscita. Disegnate il nodo del parametro di attività di input con le frecce in uscita e il nodo dell’attività di output con le frecce in entrata. Per ogni parametro esiste un nodo del parametro di attività dello stesso tipo.
- Nodo buffer: il nodo buffer (central buffer node) si utilizza in modo simile ai pin direttamente nel diagramma delle attività. Questo nodo oggetto memorizza i valori in qualsiasi punto del diagramma. A differenza del pin, tuttavia, si trova da solo, senza essere legato a un nodo di attività. Il nodo del buffer collega sia gli oggetti in entrata che quelli in uscita con altri nodi oggetto (ad esempio un pin) tramite il flusso dell’oggetto. Il nodo buffer serve a tamponare i flussi di oggetti in entrata e in uscita. Il token verrà inviato solo quando un nodo oggetto all’altra estremità del flusso diverrà libero e accetterà i parametri dell’oggetto. In base alla notazione UML questo nodo è costituito da un semplice rettangolo. La sua funzione particolare viene visualizzata con lo stereotipo <<centralBuffer>>.
- Nodo del datastore (o di archiviazione dati): i nodi del datastore tra flussi di oggetto si azionano come i nodi buffer senza vincolarli a un’azione. Questo sottotipo del nodo buffer ha una particolarità: memorizza una copia di ciascun token inviato fino a quando l’attività sovraordinata è completata. Per questo ogni valore esiste una volta sola nel nodo di archiviazione dati. Quindi, se il nodo memorizza già un token oggetto con un’identità fissa, non acquisirà nuovi token che abbiano esattamente le stesse proprietà. Come per tutti i nodi oggetto il nodo di archiviazione dati è rappresentato come un rettangolo. Per distinguerlo scrivete lo stereotipo <<datastore>> nell’intestazione.
Nodi di controllo: nodi di attività che indirizzano i token di controllo
All’interno di un diagramma di attività UML i token si spostano attraverso varie azioni finché l’attività non viene completata dal primo token che arriva al nodo finale. Poiché diversi token possono attraversare questo processo nello stesso momento, è necessario un certo ordine. I nodi di controllo servono proprio a garantire un processo chiaro. Essi gestiscono solo i flussi di controllo che si trovano sul percorso che va dall’inizio del diagramma di attività attraverso le azioni fino alla fine dell’attività. I nodi di controllo non possono memorizzare i token della cache, diversamente dai nodi oggetto come il nodo buffer.
Una differenza significativa tra i flussi oggetto e di controllo è che solo i token di controllo migrano sui flussi di controllo. Questi token non contengono dati, a differenza dei token oggetto. Sono soltanto indicatori, pertanto le azioni non richiedono nodi oggetto (pin in particolare) per raccogliere e passare i token di controllo. Un token di controllo avvia un’azione, passa alla successiva e quindi la mette in movimento. Controlla perciò l’esecuzione dell’attività in modo cronologico.
Tra i simboli del diagramma di attività UML i nodi di controllo sono probabilmente i più diversi. Appartengono ai nodi dell’attività. UML 2 distingue sei tipi:
- I nodi iniziali (initial nodes) iniziano un’attività. Ci può essere più di un nodo di partenza per attività. Quando inizia un’attività il nodo iniziale mette immediatamente in movimento il flusso di controllo. Se esistono più nodi iniziali, i rispettivi flussi di controllo iniziano in modo simultaneo. Anche i nodi di attività strutturati possono avere nodi iniziali. Essi iniziano immediatamente se l’attività strutturata viene inizializzata, purché non siano state impostate condizioni per il loro avvio. Poiché gli initial nodes sono all’inizio, tutti le loro frecce sono frecce di attività in uscita e sono sempre flussi di controllo. Un’ulteriore particolarità dei nodi di inizio è che i token di controllo che sono posizionati sul nodo iniziale all’inizio di un’attività, possono rimanere lì se il flusso di controllo non accetta il token offerto o è bloccato.
- I nodi finali terminano il flusso di un’attività. Ci sono due tipi di nodi terminali: l’activity final node termina l’intera attività, distruggendo tutti i token compresi nell’attività, non appena riceve il primo token. Vengono mantenuti soltanto i token oggetto in output dei nodi di parametro dell’attività. Anche tutte le azioni sincrone si fermano, mentre continuano quelle asincrone fino al loro completamento. I nodi finali accettano tutti i token in entrata. Al contrario dei nodi di inizio, un nodo finale presenta frecce di attività soltanto in arrivo. Non si esclude la presenza di più di un nodo finale. Se disegnate il diagramma di attività con più di un nodo finale, le azioni si fermano prima di aver raggiunto il proprio scopo, poiché un token ha già raggiunto il primo punto finale. Il flow final node ferma un flusso di controllo e distrugge tutti i token in entrata e non tocca altri flussi di controllo. In tal modo questo nodo finale diventa una pratica alternativa quando modellate più punti finali nel diagramma di attività.
- I nodi di parallellizzazione e di sincronizzazione (fork nodes e join nodes), detti anche biforcazioni, sono nodi di controllo con una notazione quasi identica che rispecchia i compiti relativi. Un nodo di parallelizzazione divide un fronte di attività in entrata in più flussi contemporanei in uscita. Nel nodo di parallelizzazione può entrare una sola freccia di attività. Se si tratta di un flusso di controllo, anche tutte le frecce in uscita sono flussi di controllo, e vale lo stesso principio per i flussi di oggetti. Il nodo crea copie dei token in entrata per tutti i flussi in uscita. Se un token è accettato alla destinazione del flusso in uscita, esso viene eliminato dal nodo di origine. Se la destinazione successiva non accetta il proprio token, il nodo di parallelizzazione può eccezionalmente tenere il token finché non viene accettato.
I nodi di sincronizzazione funzionano esattamente al contrario. Diverse frecce entrano ma soltanto una esce. Se il totale delle frecce in entrata consiste in flussi di controllo, allora è un flusso di controllo a lasciare il nodo. Se c’è anche un solo flusso di oggetti al di sotto, l’UML specifica la freccia in uscita come flusso di oggetti. Se come in questo caso entrano anche token di controllo, essi decadono e soltanto i token oggetto usciranno. Se due oggetti hanno la stessa identità, il nodo li unisce in un unico token. In generale i token escono soltanto quando ne offrono uno a tutte le frecce in entrata (operazione and). Ciò accade secondo il principio “First In First Out”. Se scrivete una specifica di valore per il nodo di sincronizzazione tramite joinSpec, il nodo aspetta i token che soddisfano esplicitamente questi requisiti, prima di rilasciare token.
- I nodi di diramazione e di connessione (decision notes e merge nodes) condividono lo stesso simbolo nel diagramma di attività. La guida dei flussi è di nuovo la caratteristica distintiva di queste notazioni di nodi. Un nodo ramificato richiede almeno una e al massimo due frecce in entrata. L’UML chiama la freccia primaria in entrata (primary incoming edge), mentre la seconda flusso dell’input di diramazione (decision input flow). Se i flussi in uscita rappresentano flussi di oggetti o di controllo, dipende dalla freccia primaria. Il compito del nodo è quello di decidere tra le frecce in uscita. Il nodo offre il suo nodo in arrivo senza copiarlo, perciò il token può prendere una sola direzione.
Un nodo di connessione riunisce più flussi in entrata in un unico flusso in uscita. Al contrario del nodo di sincronizzazione, tuttavia, il nodo di connessione non riunisce i token in uno nuovo o sincronizza i tipi di frecce in entrata. Perciò per un flusso di controllo in uscita tutte le frecce in entrata devono anche essere flussi di controllo, e lo stesso vale per i flussi di oggetti. Il nodo di connessione offre semplicemente tutti i token in entrata per la freccia in uscita.
Se volete creare un diagramma di attività in UML e modificare il concetto in team, è importante attenersi alla notazione. Soltanto così si garantisce la comprensibilità generale di questo linguaggio di modellazione grafica. In questo articolo vi abbiamo presentato i principali nodi di azione e frecce con le loro funzioni. Inoltre abbiamo illustrato tutte le notazioni di base e specifiche per i diagrammi di attività in base alle specifiche di UML 2.5.1.. Le specifiche esplicitate in modo esaustivo di tutti i simboli del diagramma di attività UML sono disponibili sul sito web dell’Object Management Group.