Il diagramma di attività è un tipo di diagramma all’interno dell’Unified Modeling Language (UML). Questo lin­guag­gio di mo­del­la­zio­ne grafica definisce le forme per rap­pre­sen­ta­re la pro­gram­ma­zio­ne orientata agli oggetti e specifica 14 tipi di grafici. A ognuno di questi sono assegnate forme spe­ci­fi­che. Uti­liz­zan­do le regole di notazione si possono astrarre sistemi e processi e vi­sua­liz­zar­li in modo chiaro. L’UML non solo modella i sistemi software, ma anche i processi aziendali. I diagrammi delle attività sono par­ti­co­lar­men­te 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) ap­par­ten­go­no all’insieme di diagrammi com­por­ta­men­ta­li in UML. Mentre un diagramma di struttura cattura lo stato di un sistema, cioè gli oggetti esistenti e le loro gerarchie, nonché le in­ter­con­nes­sio­ni in un de­ter­mi­na­to momento, i diagrammi com­por­ta­men­ta­li de­scri­vo­no lo scorrere cro­no­lo­gi­co dei flussi di dati. Accanto al diagramma di attività, ap­par­ten­go­no 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 pro­gram­ma­zio­ne 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 in­for­ma­ti­co, decorsi use case o aziendali. Ad esempio l’attività “preparare un’omelette al formaggio” si suddivide in molti altre sot­toat­ti­vi­tà: le azioni. Esse possono sot­to­sta­re a un ordine cro­no­lo­gi­co. 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 im­ma­gi­na­re flussi paralleli. Quando due persone si occupano della pre­pa­ra­zio­ne di una frittata, è possibile svolgere si­mul­ta­nea­men­te 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 suc­ces­si­va.

In un caso di uso queste persone sarebbero attori. In un diagramma di attività hanno si­cu­ra­men­te un ruolo im­por­tan­te, ma non hanno alcuna notazione. Si spostano da un punto iniziale a un punto finale at­tra­ver­san­do i flussi di controllo o di oggetti per passare da un’azione alla suc­ces­si­va. In mezzo ci sono barriere oc­ca­sio­na­li, i co­sid­det­ti pin, che accadono solo a de­ter­mi­na­te con­di­zio­ni, 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 in­for­ma­zio­ni al nodo dell’azione, dove avvia un’azione e (se spe­ci­fi­ca­to) memorizza il risultato come valore. Se il risultato e il token cor­ri­spon­do­no alle spe­ci­fi­che impostate in un pin, questo pin di output invia il token dell’oggetto all’azione suc­ces­si­va at­tra­ver­so un flusso di oggetti. Per poter iniziare questa azione il token deve essere conforme alle spe­ci­fi­che del pin di input. I token di controllo, d’altra parte, si muovono solo at­tra­ver­so i flussi di controllo e fungono da in­di­ca­to­ri. Iniziano un’azione ma non inviano dati.

Nell’esempio descritto, ovvero “preparare un’omelette al formaggio”, uti­liz­zia­mo il diagramma di attività per rap­pre­sen­ta­re il corso cro­no­lo­gi­co di un caso di uso. I programmi del caso di uso invece rap­pre­sen­ta­no i requisiti di sistema necessari nel caso di ap­pli­ca­zio­ne.

I diagrammi di attività UML 2 na­tu­ral­men­te si possono uti­liz­za­re anche per altri scopi oltre a quelli delle attività quo­ti­dia­ne. In­nan­zi­tut­to ci aiutano a rap­pre­sen­ta­re i processi in modo strut­tu­ra­to nei sistemi software. Ad esempio gli analisti aziendali li uti­liz­za­no per rendere le spe­ci­fi­che per gli svi­lup­pa­to­ri di software. Con il lin­guag­gio grafico gli esperti si scambiano in­for­ma­zio­ni su un livello ge­ne­ral­men­te com­pren­si­bi­le 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 pro­gram­ma­zio­ne.

Se si integra uno strumento UML adatto nel proprio ambiente di sviluppo integrato, il diagramma può fungere da quadro di codice mediante con­ver­sio­ne XML in un lin­guag­gio di pro­gram­ma­zio­ne.

L’Object Ma­na­ge­ment Group (OMG) che specifica l’UML, riassume i possibili compiti dei diagrammi di attività UML 2 come segue:

  • pro­gram­ma­zio­ne com­pu­te­riz­za­ta pro­ce­du­ra­le che assegna attività alle gerarchie
  • nei modelli orientati agli oggetti, le attività agiscono come metodi che de­scri­vo­no più det­ta­glia­ta­men­te i processi
  • rap­pre­sen­ta­zio­ne dei flussi di lavoro e dei processi aziendali
  • per le attività dei sistemi ap­pli­ca­ti­vi com­pu­te­riz­za­ti le attività spe­ci­fi­ca­no i processi a livello di sistema

Le notazioni per i diagrammi di attività UML

Le forme all’interno dell’UML possono essere intese come com­po­nen­ti di frasi della lingua. Pertanto il lin­guag­gio di mo­del­la­zio­ne assegna im­por­tan­za a ciascuna forma. I mo­di­fi­ca­to­ri de­scri­vo­no questi in modo più det­ta­glia­to e li mettono in relazione tra di loro. Inoltre gli stampi talvolta ri­chie­do­no certe altre forme o etichette per creare un diagramma si­gni­fi­ca­ti­vo. Proprio come la lingua parlata ha senso solo se vengono ri­spet­ta­te alcune regole gram­ma­ti­ca­li di base, l’UML funziona come mezzo di co­mu­ni­ca­zio­ne solo se ci si attiene alle spe­ci­fi­che.

UML 2.5 è la specifica più recente del lin­guag­gio di mo­del­la­zio­ne e pertanto co­sti­tui­rà la base di queste spie­ga­zio­ni. L’UML definisce la notazione dei tipi di grafici in base alle loro aree di ap­pli­ca­zio­ne. Poiché il diagramma di attività UML mappa il flusso dei processi di sistema nei casi d’uso, la me­ta­mo­del­la­zio­ne assegna loro le forme cor­ri­spon­den­ti.

Come vengono rap­pre­sen­ta­ti vi­si­va­men­te i singoli com­po­nen­ti e quali funzioni assolvono i simboli nei diagrammi di attività UML?

Attività

UML 2 specifica un’attività (activity in inglese) come com­por­ta­men­to che assegna un ordine di suc­ces­sio­ne alle unità sot­to­stan­ti (azioni e oggetti). Per farlo si uti­liz­za­no modelli di dati e di flusso di controllo. Il diagramma di attività può essere rap­pre­sen­ta­to come parte di un sistema più vasto in com­bi­na­zio­ne con altri tipi di diagrammi. Un grande ret­tan­go­lo ar­ro­ton­da­to con­tras­se­gna l’attività come sistema chiuso (si può anche tra­la­scia­re). Nella parte inferiore dell’immagine potete vedere l’attività “cuocere gli asparagi”. Scrivete il titolo nella testa del ret­tan­go­lo grande. Il corpo a propria volta contiene frecce e nodi (ret­tan­go­li), che sim­bo­leg­gia­no in dettaglio azioni, oggetti e controllo o flusso di dati dell’attività.

Le attività in UML valgono come classi (la cui me­ta­clas­se è il com­por­ta­men­to). In questo modo si possono definire più pre­ci­sa­men­te at­tra­ver­so le proprietà e ciò può in­fluen­za­re gli elementi su­bor­di­na­ti. Un’attività viene con­si­de­ra­ta com­ple­ta­ta quando un token si è spostato dal punto di partenza at­tra­ver­so 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.

N.B.

UML 1 definisce i diagrammi di attività in modo diverso rispetto a UML 2. La versione pre­ce­den­te assegnava loro il ruolo di un diagramma di stato spe­cia­liz­za­to che ne re­strin­ge­va i loro usi. Se usate un Tool UML, dovete ac­cer­tar­vi che supporti la for­mu­la­zio­ne de­si­de­ra­ta, ideal­men­te la versione UML 2.5 o suc­ces­si­ve.

Azioni: nodi di attività che rap­pre­sen­ta­no il com­por­ta­men­to

Un’azione (in inglese: action, exe­cu­ta­ble node) è un elemento del modello ge­rar­chi­ca­men­te su­bor­di­na­to all’attività: l’azione è un’istanza della classe “attività”. Le azioni rap­pre­sen­ta­no un com­por­ta­men­to all’interno di un sistema. Sono i mattoni di base uti­liz­za­ti per esprimere il com­por­ta­men­to in UML. Sono uti­liz­za­ti nei diagrammi di attività e nelle in­te­ra­zio­ni.

Quando create un diagramma di attività uti­liz­za­te la notazione “azione” per rap­pre­sen­ta­re le parti ese­gui­bi­li di un’attività. Nell’esempio sopra l’azione “Pelare gli asparagi e metterli in pentola” è un paso nel processo di com­ple­ta­men­to dell’attività “cuocere gli asparagi”. Le azioni prendono in­for­ma­zio­ni di input, le elaborano e producono in­for­ma­zio­ni di output. Un’azione non si arresta finché non è com­ple­ta­ta.

All’interno dei diagrammi di attività UML le azioni ap­par­ten­go­no 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 tra­spor­ta­no i token di controllo). Le azioni ge­sti­sco­no 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 con­ver­to­no per l’ela­bo­ra­zio­ne nell’azione e quindi generano l’output dell’oggetto che prosegue come token oggetto.

Fatto

La categoria del nodo attività è stata in­tro­dot­ta in UML 2. Ne esistono tre sottotipi: nodi di controllo, nodi oggetto e nodi ese­gui­bi­li (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 sod­di­sfa­no le con­di­zio­ni spe­ci­fi­ca­te di un nodo) o in parallelo.

Soltanto quando le con­di­zio­ni impostate sui pin vengono sod­di­sfat­te i dati ese­gui­ran­no un’azione (pin di input) o l’azione re­sti­tui­rà 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 ret­tan­go­lo ar­ro­ton­da­to. Tuttavia ci sono azioni spe­ci­fi­che che i mo­del­li­sti possono usare per de­scri­zio­ni più spe­ci­fi­che. Alcuni di questi esprimono UML con la sua notazione. Queste sono le sot­to­spe­cie delle azioni:

  1. Opaque Actions, ovvero “azioni opache”. Fungono da se­gna­po­sto o sono spe­ci­fi­ca­te dalla concreta (non spe­ci­fi­ca­ta da UML) sintassi del testo.
  2. In­vo­ca­tion Actions, azioni che causano un de­ter­mi­na­to com­por­ta­men­to, di­ret­ta­men­te o in­di­ret­ta­men­te. Esse includono:
    • call actions: una call behavior action chiama di­ret­ta­men­te un com­por­ta­men­to. Una call operation action invece invia una richiesta a un oggetto che chiama un com­por­ta­men­to connesso. La start object behavior action porta di­ret­ta­men­te un oggetto a eseguire il suo com­por­ta­men­to di istanza. Se non ne è spe­ci­fi­ca­to nessuno, può attivare il com­por­ta­men­to del clas­si­fi­ca­to­re so­vraor­di­na­to (clas­si­fier behavior).

La notazione di un’azione che causa un com­por­ta­men­to consiste di un ret­tan­go­lo ar­ro­ton­da­to. Lì si inserisce il nome del com­por­ta­men­to che si intende ri­chia­ma­re. Inoltre le call behavior actions sono con­tras­se­gna­te con un’icona a forma di tridente, come mostrato nell’immagine sotto, che è intesa a rap­pre­sen­ta­re l’ulteriore ra­mi­fi­ca­zio­ne ge­rar­chi­ca ri­sul­tan­te 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 de­sti­na­zio­ne e quindi non bloccano il flusso degli oggetti. L’azione termina non appena il messaggio è stato inviato. Pertanto potrebbe ef­fet­ti­va­men­te avere un argument input, come ad esempio i parametri, ma non produrre alcun result output. Inoltre i messaggi possono dirigersi di­ret­ta­men­te a più de­sti­na­ta­ri. Ap­par­ten­go­no a questo tipo send signal action, broadcast signal action e send object action.

Le send signal actions dif­fe­ri­sco­no nella loro notazione dalla forma usuale (il ret­tan­go­lo ar­ro­ton­da­to): al suo posto un pentagono punta come una grande freccia in direzione del segnale trasmesso. Se il contenuto di una send objet action è co­sti­tui­to anche da un segnale, è possibile uti­liz­za­re la stessa notazione.

  1. Le object actions cambiano lo stato degli oggetti (cioè le istanze di una classe). Possono crearle o di­strug­ger­le, con­fron­tar­le con altre istanze e quindi as­se­gnar­le a una classe o mo­di­fi­ca­re la clas­si­fi­ca­zio­ne. Di con­se­guen­za 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 di­strug­go­no l’oggetto sul pin di input;
    • test identity actions, che esaminano se due valori sul pin di input rap­pre­sen­ta­no lo stesso oggetto;
    • read self actions, che de­ter­mi­na­no il proprio oggetto di contesto;
    • value spe­ci­fi­ca­tion actions, che esaminano le spe­ci­fi­che del valore. La notazione reca l’etichetta value spe­ci­fi­ca­tion;
    • read extent actions che trovano tutti gli oggetti di una classe nonché gli oggetti delle loro spe­ci­fi­che. Per motivi pratici i mo­del­la­to­ri di solito limitano la gamma;
    • re­clas­si­fy object actions che mo­di­fi­ca­no la classe per l’oggetto sul pin di input;
    • read is clas­si­fied object actions per de­ter­mi­na­re se un oggetto sul pin di input ap­par­tie­ne a una classe;
    • start clas­si­fier behavior actions che fungono per un oggetto da trigger per un com­por­ta­men­to de­ter­mi­na­to dalla relative classe. Il com­por­ta­men­to procede in modo asincrono.
  2. Le link actions mo­di­fi­ca­no il com­por­ta­men­to delle as­so­cia­zio­ni (relazioni tra clas­si­fier, di solito due classi) e le loro istanze, i link. Questi includono:
    • read link actions, che re­cu­pe­ra­no valori (link end data) su una pagina di un’as­so­cia­zio­ne;
    • 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 can­cel­la­no i link e link objects se cor­ri­spon­do­no a un valore link end data spe­ci­fi­ca­to.
  3. Le link object actions, come le link actions, in­fluen­za­no il com­por­ta­men­to dei link objects, ma guardano gli oggetti da an­go­la­zio­ni diverse. Ecco le istanze di link object actions:
    • read link object end actions, che re­cu­pe­ra­no gli oggetti finali dai link object (o oggetti di col­le­ga­men­to);
    • read link object end qualifier actions, che re­cu­pe­ra­no i valori finali del clas­si­fier dagli oggetti di col­le­ga­men­to;
    • create link object actions, che sono par­ti­co­la­ri create link actions con le quali si creano oggetti di col­le­ga­men­to.
  4. Le struc­tu­ral feature actions sta­bi­li­sco­no il com­por­ta­men­to delle ca­rat­te­ri­sti­che strut­tu­ra­li nei diagrammi di attività. Per questo hanno bisogno di un pin di input, dato che di solito sono sia un oggetto che una ca­rat­te­ri­sti­ca strut­tu­ra­le spe­ci­fi­ca­ta sta­ti­ca­men­te at­tri­bui­ta a un clas­si­fier. L’azione della ca­rat­te­ri­sti­ca strut­tu­ra­le influisce su entrambi gli elementi. Ci sono i seguenti tipi:
    • read struc­tu­ral feature action, che legge i valori delle ca­rat­te­ri­sti­che strut­tu­ra­li e li passa come output;
    • add struc­tu­ral feature value actions, che ri­chie­do­no un value input pin. Esso specifica il valore che l’azione assegna a una ca­rat­te­ri­sti­ca strut­tu­ra­le;
    • remove struc­tu­ral feature value actions che sot­trag­go­no valore da una ca­rat­te­ri­sti­ca strut­tu­ra­le. Un value input pin con mol­te­ci­pli­tà 1..1 specifica questo valore;
    • clear struc­tu­ral feature actions, che rimuovono tutti i valori di un elemento della struttura.
  5. Le variable actions in­flui­sco­no sulle variabili spe­ci­fi­ca­te sta­ti­ca­men­te che vengono definite da un’attività o da un nodo di attività strut­tu­ra­to (struc­tu­red activity node). Ce ne sono tre tipi:
    • add variable value actions, che ne­ces­si­ta­no di un value input pin. Esso deve essere dello stesso tipo della variabile e le aggiunge esat­ta­men­te un valore;
    • remove variable value actions, che rimuovono un valore spe­ci­fi­ca­to dal pin;
    • clear variable actions, che rimuovono tutti i valori di una variabile.
  6. Le accept event actions ap­par­ten­go­no ai co­sid­det­ti 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 ve­ri­fi­ca­no uno o più stati tra quelli pre­scrit­ti. L’UML descrive tre spe­cia­liz­za­zio­ni:
    • accept call action, che hanno un trigger che accetta i call events (eventi di chiamata). Due result output pins e un return in­for­ma­tion output pin com­ple­ta­no la di­spo­si­zio­ne. Se deve essere eseguita una reply action, le in­for­ma­zio­ni ne­ces­sa­rie vengono me­mo­riz­za­te nel return in­for­ma­tion output pin.
  • reply actions, che hanno una con­nes­sio­ne con le accept call actions. Da un lato i trigger devono cor­ri­spon­de­re in modo che l’azione di risposta in caso di un call event possa ri­spon­de­re all’azione di ac­cet­ta­zio­ne della chiamata eseguita in pre­ce­den­za. D’altra parte il com­por­ta­men­to so­vraor­di­na­to colloca il valore di output nel return in­for­ma­tion input pin della reply action;
  • le un­mar­shall actions in­ter­ro­ga­no i valori delle ca­rat­te­ri­sti­che strut­tu­ra­li degli oggetti. Per ri­co­no­sce­re l’oggetto hanno un pin di input dell’oggetto. I valori ottenuti vengono emessi su un pin di output.
Fatto

Se i dati strut­tu­ra­ti di un oggetto o i dati ele­men­ta­ri di un programma devono essere tra­sfe­ri­ti ad altri programmi o parti di programmi o se si desidera me­mo­riz­zar­li, allora vengono con­ver­ti­ti in un formato adatto. Questo processo è chiamato mar­shal­ling (o mar­sha­ling). Il processo opposto, l’un­mar­shal­ling (o un­mar­sha­ling), ri­tra­sfor­ma questi dati “congelati” in oggetti ese­gui­bi­li. Un esempio in merito è il tra­sfe­ri­men­to di diagrammi UML da uno strumento a un altro programma tramite la con­ver­sio­ne XML.

  1. Le struc­tu­red 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 com­por­ta­men­to è de­ter­mi­na­to da nodi e fronti di attività e dall’altro che certe sot­to­spe­cie di queste azioni, in virtù della loro semantica, pre­scri­vo­no un com­por­ta­men­to specifico per i nodi ese­gui­bi­li, in par­ti­co­la­re per quanto riguarda la loro sequenza.

Queste sono le sot­to­spe­cie delle azioni strut­tu­ra­te:

  • I con­di­tio­nal nodes (nodi con­di­zio­na­li) sono co­sti­tui­ti da una o più clausole che rap­pre­sen­ta­no i diversi rami delle possibili azioni ese­gui­bi­li. Una clausola contiene un segmento test e un segmento body, i quali a propria volta com­pren­do­no nodi ese­gui­bi­li privi di in­ter­se­zio­ni. 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) de­scri­vo­no un gruppo di azioni che si ripetono all’interno di un ciclo. Le azioni si sud­di­vi­do­no in tre sezioni: setup, test e body. Il loop esegue sempre in­nan­zi­tut­to il setup, a cui seguono test o body, che quindi si ripetono al­ter­na­ti­va­men­te.
  • I sequence nodes (nodi di sequenza) impongono un ordine sui nodi ese­gui­bi­li all’interno dei loro confini. Questi li rap­pre­sen­ta­no con i flussi di dati come bordi di attività (ovvero semplici frecce). Le frecce possono puntare li­be­ra­men­te dentro o fuori rispetto alla struttura.
  1. Le expansion regions sono un’altra forma di nodi di attività strut­tu­ra­ti. Accettano una o più raccolte di valori come input. Sulla via verso la regione di espan­sio­ne 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’ese­cu­zio­ne vale come un’ese­cu­zio­ne di espan­sio­ne (expansion execution). Un co­sid­det­to nodo di espan­sio­ne (un tipo di nodo oggetto) indica l’in­ter­fac­cia alla regione di espan­sio­ne. Ester­na­men­te si vi­sua­liz­za­no i loro valori come una raccolta, mentre all’interno i singoli elementi della col­le­zio­ne sono con­si­de­ra­ti valori. Per la notazione disegnate un ret­tan­go­lo ar­ro­ton­da­to con una linea trat­teg­gia­ta. I nodi di espan­sio­ne rap­pre­sen­ta­no ret­tan­go­li con segmenti e sono disegnati di­ret­ta­men­te sulla linea, come mostrato di seguito. La seg­men­ta­zio­ne dovrebbe rap­pre­sen­ta­re l’elenco delle raccolte di valori.
  1. Le reduce actions (azioni di riduzione) stimolano un com­por­ta­men­to 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.
  2. Le raise exception actions (azioni che causano un’eccezione) cessano au­to­no­ma­men­te non appena causano un’eccezione. Perciò non terminano come azioni normali che finiscono quando l’azione è stata eseguita fino al suo com­ple­ta­men­to. Si espandono verso l’esterno at­tra­ver­so il sistema fino al nodo di attività strut­tu­ra­to suc­ces­si­vo. Se questo ha un gestore che cor­ri­spon­de all’eccezione, l’azione si in­ter­rom­pe, al­tri­men­ti continua a dif­fon­der­si.

Nodi oggetto: nodi di attività che dirigono i token oggetto

I nodi oggetto sono sot­toin­sie­mi dei nodi di attività. In generale, un oggetto in UML è l’istanza più piccola occupata dal valore. Nel diagramma di attività gli oggetti rap­pre­sen­ta­no i dati. Mentre un’azione viene eseguita, i nodi oggetto con­ten­go­no tali dati. Perché solo i token di controllo possono portare di­ret­ta­men­te 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 in­tro­dot­ti per la prima volta nel diagramma di attività UML 2. Sono elementi tipizzati. Se un nodo oggetto cor­ri­spon­de a un tipo par­ti­co­la­re, i token oggetto che viaggiano su di esso devono avere valori cor­ri­spon­den­ti. Un’eccezione sono i token nulli che possono far a meno di un valore (sono conformi a qualsiasi nodo oggetto).

I noti oggetto pre­scri­vo­no la suc­ces­sio­ne in cui i token li ab­ban­do­na­no. Ci sono quattro modi per farlo:

  • di­sor­di­na­to (non stabilito)
  • ordinato (com­por­ta­men­to definito dal mo­del­la­to­re)
  • 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 mo­del­la­zio­ne:

  1. Il pin: ai pin si è già accennato in questa ese­cu­zio­ne. Il primo grafico mostrava la notazione base dei pin. A causa del loro ruolo di col­le­ga­men­to tra azioni e flussi di oggetti, i mo­del­la­to­ri in genere li disegnano come piccoli ret­tan­go­li di­ret­ta­men­te sull’icona di azione. I pin di input (anche input pins) sono con­tras­se­gna­ti 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 vi­sua­liz­za­re i pin dello stesso tipo in modo ab­bre­via­to (a sinistra) o come disegnare i pin di input e output se si omettono le frecce (a destra).
  1. Nodo del parametro di attività: l’attività ap­par­tie­ne alla me­ta­clas­se della de­scri­zio­ne dei com­por­ta­men­ti. Secondo UML, ogni com­por­ta­men­to ha un parametro. Prima di eseguire un com­por­ta­men­to, è possibile immettere i valori per l’ela­bo­ra­zio­ne. Dopo l’ela­bo­ra­zio­ne ri­ce­ve­re­te i nuovi valori. I parametri in questa struttura sono i se­gna­po­sto che con­sen­to­no l’im­mis­sio­ne 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 con­se­guen­za 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.
  1. Nodo buffer: il nodo buffer (central buffer node) si utilizza in modo simile ai pin di­ret­ta­men­te nel diagramma delle attività. Questo nodo oggetto memorizza i valori in qualsiasi punto del diagramma. A dif­fe­ren­za 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 è co­sti­tui­to da un semplice ret­tan­go­lo. La sua funzione par­ti­co­la­re viene vi­sua­liz­za­ta con lo ste­reo­ti­po <<cen­tral­Buf­fer>>.
  2. Nodo del datastore (o di ar­chi­via­zio­ne dati): i nodi del datastore tra flussi di oggetto si azionano come i nodi buffer senza vin­co­lar­li a un’azione. Questo sottotipo del nodo buffer ha una par­ti­co­la­ri­tà: memorizza una copia di ciascun token inviato fino a quando l’attività so­vraor­di­na­ta è com­ple­ta­ta. Per questo ogni valore esiste una volta sola nel nodo di ar­chi­via­zio­ne dati. Quindi, se il nodo memorizza già un token oggetto con un’identità fissa, non acquisirà nuovi token che abbiano esat­ta­men­te le stesse proprietà. Come per tutti i nodi oggetto il nodo di ar­chi­via­zio­ne dati è rap­pre­sen­ta­to come un ret­tan­go­lo. Per di­stin­guer­lo scrivete lo ste­reo­ti­po <<datastore>> nell’in­te­sta­zio­ne.

Nodi di controllo: nodi di attività che in­di­riz­za­no i token di controllo

All’interno di un diagramma di attività UML i token si spostano at­tra­ver­so varie azioni finché l’attività non viene com­ple­ta­ta dal primo token che arriva al nodo finale. Poiché diversi token possono at­tra­ver­sa­re questo processo nello stesso momento, è ne­ces­sa­rio un certo ordine. I nodi di controllo servono proprio a garantire un processo chiaro. Essi ge­sti­sco­no solo i flussi di controllo che si trovano sul percorso che va dall’inizio del diagramma di attività at­tra­ver­so le azioni fino alla fine dell’attività. I nodi di controllo non possono me­mo­riz­za­re i token della cache, di­ver­sa­men­te dai nodi oggetto come il nodo buffer.

Una dif­fe­ren­za si­gni­fi­ca­ti­va tra i flussi oggetto e di controllo è che solo i token di controllo migrano sui flussi di controllo. Questi token non con­ten­go­no dati, a dif­fe­ren­za dei token oggetto. Sono soltanto in­di­ca­to­ri, pertanto le azioni non ri­chie­do­no nodi oggetto (pin in par­ti­co­la­re) per rac­co­glie­re e passare i token di controllo. Un token di controllo avvia un’azione, passa alla suc­ces­si­va e quindi la mette in movimento. Controlla perciò l’ese­cu­zio­ne dell’attività in modo cro­no­lo­gi­co.

Tra i simboli del diagramma di attività UML i nodi di controllo sono pro­ba­bil­men­te i più diversi. Ap­par­ten­go­no ai nodi dell’attività. UML 2 distingue sei tipi:

  1. 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 im­me­dia­ta­men­te in movimento il flusso di controllo. Se esistono più nodi iniziali, i ri­spet­ti­vi flussi di controllo iniziano in modo si­mul­ta­neo. Anche i nodi di attività strut­tu­ra­ti possono avere nodi iniziali. Essi iniziano im­me­dia­ta­men­te se l’attività strut­tu­ra­ta viene ini­zia­liz­za­ta, purché non siano state impostate con­di­zio­ni 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 par­ti­co­la­ri­tà dei nodi di inizio è che i token di controllo che sono po­si­zio­na­ti sul nodo iniziale all’inizio di un’attività, possono rimanere lì se il flusso di controllo non accetta il token offerto o è bloccato.
  2. I nodi finali terminano il flusso di un’attività. Ci sono due tipi di nodi terminali: l’activity final node termina l’intera attività, di­strug­gen­do 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 con­ti­nua­no quelle asincrone fino al loro com­ple­ta­men­to. 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 al­ter­na­ti­va quando modellate più punti finali nel diagramma di attività.
  1. I nodi di pa­ral­lel­liz­za­zio­ne e di sin­cro­niz­za­zio­ne (fork nodes e join nodes), detti anche bi­for­ca­zio­ni, sono nodi di controllo con una notazione quasi identica che ri­spec­chia i compiti relativi. Un nodo di pa­ral­le­liz­za­zio­ne divide un fronte di attività in entrata in più flussi con­tem­po­ra­nei in uscita. Nel nodo di pa­ral­le­liz­za­zio­ne 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 de­sti­na­zio­ne del flusso in uscita, esso viene eliminato dal nodo di origine. Se la de­sti­na­zio­ne suc­ces­si­va non accetta il proprio token, il nodo di pa­ral­le­liz­za­zio­ne può ec­ce­zio­nal­men­te tenere il token finché non viene accettato.

I nodi di sin­cro­niz­za­zio­ne fun­zio­na­no esat­ta­men­te 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 (ope­ra­zio­ne and). Ciò accade secondo il principio “First In First Out”. Se scrivete una specifica di valore per il nodo di sin­cro­niz­za­zio­ne tramite joinSpec, il nodo aspetta i token che sod­di­sfa­no espli­ci­ta­men­te questi requisiti, prima di ri­la­scia­re token.

  1. I nodi di di­ra­ma­zio­ne e di con­nes­sio­ne (decision notes e merge nodes) con­di­vi­do­no lo stesso simbolo nel diagramma di attività. La guida dei flussi è di nuovo la ca­rat­te­ri­sti­ca di­stin­ti­va di queste notazioni di nodi. Un nodo ra­mi­fi­ca­to 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 di­ra­ma­zio­ne (decision input flow). Se i flussi in uscita rap­pre­sen­ta­no 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 con­nes­sio­ne riunisce più flussi in entrata in un unico flusso in uscita. Al contrario del nodo di sin­cro­niz­za­zio­ne, tuttavia, il nodo di con­nes­sio­ne non riunisce i token in uno nuovo o sin­cro­niz­za 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 con­nes­sio­ne offre sem­pli­ce­men­te tutti i token in entrata per la freccia in uscita.

In sintesi

Se volete creare un diagramma di attività in UML e mo­di­fi­ca­re il concetto in team, è im­por­tan­te attenersi alla notazione. Soltanto così si ga­ran­ti­sce la com­pren­si­bi­li­tà generale di questo lin­guag­gio di mo­del­la­zio­ne grafica. In questo articolo vi abbiamo pre­sen­ta­to i prin­ci­pa­li nodi di azione e frecce con le loro funzioni. Inoltre abbiamo il­lu­stra­to tutte le notazioni di base e spe­ci­fi­che per i diagrammi di attività in base alle spe­ci­fi­che di UML 2.5.1.. Le spe­ci­fi­che espli­ci­ta­te in modo esaustivo di tutti i simboli del diagramma di attività UML sono di­spo­ni­bi­li sul sito web dell’Object Ma­na­ge­ment Group.

Vai al menu prin­ci­pa­le