Crearea și
editarea de diagrame UML
1.
Obiectul lucrării
UML este un limbaj pentru
specificarea, vizualizarea, construirea și documentarea elementelor sistemelor
software, fiind un standard pentru modelarea software. Obiectivele acestei
lucrări sunt prezentarea unor tipuri de diagrame UML și introducerea
aplicației de creare/editare a diagramelor UML.
2.
Introducere teoretică
UML (Unified Modeling Language)
este un limbaj pentru modelare util în domeniul software la realizarea
documentelor de specificații; în general, bun pentru comunicarea între
ingineri. Faza de analiză și concepție a unui proiect trebuie să
fie gata înainte de realizarea codului, pentru a obține o atenție sporită din
partea diverșilor dezvoltatori. Aceste etape au fost ignorate în trecut, dar în
prezent orice dezvoltator recunoaște importanța acestor faze deoarece s-a
dovedit că de acestea depinde producerea și refolosirea de software. Pentru
analiza și proiectarea programelor s-au creat limbajele de modelare. Unul
dintre aceste limbaje de modelare este limbajul de modelare unificat, UML (Unified
Modeling Language).
UML nu este un simplu limbaj de modelare orientat pe
obiecte, ci în prezent este limbajul universal standard pentru dezvoltatorii
software din toată lumea. UML este succesorul propriu-zis al celor mai bune
trei limbaje anterioare de modelare orientate pe obiecte (Booch, OMT și OOSE).
UML se constituie din unirea acestor limbaje de modelare și în plus deține o
expresivitate care ajută la rezolvarea problemelor de modelare pe care vechile
limbaje nu o aveau.
UML oferă arhitecturi de sisteme care funcționează pe
analiza și proiectarea obiectelor cu un limbaj corespunzător pentru
specificarea, vizualizarea, construirea și documentarea artefactelor sistemelor
software și, de asemenea, pentru modelarea în întreprinderi. UML este un limbaj
de modelare care oferă o exprimare grafică a structurii și comportamentului
software. Pentru aceasta exprimare grafică se utilizează notațiile UML.
Notațiile UML constituie un element esențial al limbajului pentru realizarea propriu-zisă a modelării, și anume, partea reprezentării grafice pe care se bazează orice limbaj de modelare. Modelarea în acest limbaj se realizează prin combinarea notațiilor UML în cadrul elementelor principale ale acestora, denumite diagrame.
În cadrul UML-ului există 9 tipuri de diagrame:
1.
diagrama
cazurilor de utilizare,
2.
diagrama de
secvență,
3.
diagrama de
colaborare,
4.
diagrama de
clase (cea mai utilizată),
5.
diagrama de
stări,
6.
diagrama de
componente,
7.
diagrama de
construcție,
8.
diagrama de
obiecte,
9.
diagrama de
activități.
3. Descrierea aplicației
Tehnologia
de bază a aplicației este Javascript, și anume, librăria jsuml, creată
de către Rafael Molina-Linares, Martin Vega-Leal
și José-Raúl Romero. Această librărie are o arhitectură bazată pe niveluri.
Gestionarea graficii, obiecte specifice diagramelor UML, se realizează folosind
obiectele aplicației, care sunt separate în diverse fișiere. Astfel, librăria
are două fișiere de bază:
· UDCod. Reprezintă nucleul librăriei
și se concentrează asupra funcționalităților de bază, precum trasarea de linii
și forme, gestionarea evenimentelor produse de utilizator.
· UDModules. Este nivelul care conține
obiectele UML.
Interfața inițială a aplicației se poate vizualiza în figura
1.
Fig. 1. Interfața inițială a aplicației.
În partea stânga sunt afișate acțiunile disponibile, cât și elementele specifice fiecărui tip de diagramă. Aceste elemente apar în momentul în care a fost selectată o diagramă sau o zonă de lucru. Acțiunile disponibile se pot observa în figura 2.
Fig. 2. Meniul principal al aplicației.
În
continuare, se vor descrie acțiunile în ordinea apariției lor în meniu. Așadar,
prima acțiune care se observă este cea de export/import de XML sau
deschidere/salvare Diagramă. La apăsarea butonului va apărea o nouă fereastră
cu meniul prezentat în figura 3.
Fig. 3. Meniul de export/import și deschidere/salvare de diagrame.
Acțiunea de export transformă toate elementele din canvas (pânza pe care se creează obiectele/diagramele) în documente de tip XML. Importul efectuează acțiunea opusă celei de export și generează diagrame UML pe baza unei scheme XML.
Pentru
a se punea salva zona de lucru în baza de date (MySQL), mai întâi trebuie să
fie apăsat butonul de export, după care se va deschide o fereastră în care se
poate introduce un nume și/sau se poate salva sub un nume deja aflat în baza de
date.
Introducerea
în baza de date se face folosind Ajax, care trimite către fișierul PHP (save.php)
numele zonei de lucru, cât și conținutul acesteia, conținut care este format
dintr-un XML. Zona de lucru poate conține una sau mai multe diagrame.
Pentru
a deschide o zonă de lucru se afișează o fereastră de unde se poate selecta zona
de lucru dorită. Această acțiune se face prin crearea unei cereri Ajax către
server, care va returna un răspuns conținând un XML. XML-ul este copiat în zona
de conținut text și se activează evenimentul de clic asupra butonul
import.
Acțiunea
Salvează poza are rolul de a exporta/salva diagrama curent deschisă cu
ajutorul funcției Javascript toDataURL. Această funcție este relativ
nouă în Javascript, fiind introdusă odată cu apariția standardului HTML5, și
citește toată informația din interiorul canvas-ului (pânzei de lucru), codând-o
în baza 64.
Butonul
Schimbă culoare afișează o fereastră (imaginea din figura 3) formată din
3 dreptunghiuri RGB (Red, Green, Blue), de unde se poate
efectua câte un clic asupra acestora, creând o nouă nuanță din combinarea celor
3 tipuri de culori.
Fig. 3. Alegerea unei culori
pentru un element din zona de lucru.
După ce a fost selectată culoarea dorită, se apasă butonul Ok, iar elementele UML care se vor aplica vor avea culoarea de fundal selectată anterior (vezi figura 4).
Fig. 4. Elementul Clasă colorat în albastru.
Pentru a șterge un element sau o legătură dintre elementele din diagramă se utilizează acțiunea Șterge Obiect. Aceasta se desfășoară în două etape:
1. Se efectuează clic pe acțiunea Șterge Obiect;
2. Se efectuează clic pe obiectul/legătura din diagrama
deschisă.
Dacă
este șters un obiect din diagramă, toate legăturile care vin înspre sau pleacă
dinspre acel obiect sunt șterse. După ce un obiect sau o legătură este
șters/ștearsă, aplicația redesenează (randează) obiectele din canvas, exact așa
cum erau înainte de a fi șters un obiect, mai puțin cel șters.
Diagrama nouă (de tip: clasă, cazuri de utilizare, stare) generează o nouă zonă de lucru atunci când asupra ei se efectuează un clic, elementele specifice diagramei selectate apărând în zona destinată acestora.
După
ce a fost selectată o diagramă, elementele specifice acelei diagrame apar în
zona destinată acestora. Aceste elemente sunt de două tipuri:
·
obiectele
specifice diagramei,
·
legăturile
dintre obiecte.
În UML, termenul de componentă desemnează un element
software din componența fizică a unui sistem. Astfel, o componentă poate fi:
cod binar, document, fișier conținând cod sursă sau date, tabelă a unei baze de
date etc. O componentă binară este o parte fizică și substituibilă a unui
sistem, care realizează o funcție și este în conformitate cu un set de
interfețe.
În figura 5 se poate observa un exemplu de utilizare a
un obiect componentă. Între obiectele de acest gen există o legătură de
dependență. Clasele sunt reprezentate prin dreptunghiuri împărțite în trei
compartimente și care conțin numele clasei (în compartimentul superior), lista
de atribute ale clasei (opțional) și lista de operații (opțional) cu
argumentele lor și tipul returnat.
Fig. 5. Exemplu de clasă care poartă numele Mașina, are 3 atribute și 3 metode.
Regulile de vizibilitate se aplică atât atributelor cât și operațiilor din clase și se referă la domeniul de acces permis unui membru al unei clase. Fiecare nivel de vizibilitate este reprezentat printr-un simbol:
· Private (-) :
accesibilitate numai din interiorul clasei;
· Public (+) :
accesibilitate la nivelul întregului sistem;
· Protected (#) :
accesibilitate în arborele de moștenire;
· Package (~) :
accesibilitate din interiorul pachetului care conține acea clasă.
Asocierea poate avea sau nu un nume care se va afla
tipărit în vecinătatea sa și va conține o săgeată precizând modul de citire al
acestuia. O asociere poate avea nume diferite pentru fiecare direcție. Fiecare
capăt al asocierii este un rol și fiecare rol poate avea un nume (nume de rol),
care arată cum este văzută clasa asociată lui de către o alta.
Fiecare rol indică multiplicitatea clasei sale (câte instanțe
ale clasei pot fi asociate cu o instanță a altei clase). Multiplicitatea poate
fi 1 (nu se marchează), 0-1 (marcată printr-un cerc alb) 0 sau mai multe
(marcată printr-un cerc negru) sau alte intervale de valori întregi care se
indica prin expresii de tipul 1+ (mai mult de o instanță), 3 (exact trei
instanțe) sau 2-4 (între 2 și 4 instanțe inclusiv).
Fig. 6. Exemplificarea
multiplicității pentru 3 clase.
Agregarea este o formă particulară de asociere care
exprimă o relație compus-componenți". O clasă are anumite părți, care
însă au o existență independentă. Agregarea este desemnată printr-un un mic
romb amplasat alături de clasa agregat.
Fig. 7. Exemplificarea agregării pentru două clase.
Compunerea este un caz particular de agregare, care exprimă o agregare prin conținere fizică.
Fig. 8. Exemplificarea agregării pe un caz particular.
Reprezentarea relației mașină-motor ca relație de compunere face ca fiecare mașină să aibă un motor unic, care nu poate fi înlocuit, iar motorul nu poate fi pus în altă mașină. Generalizarea constă în factorizarea elementelor comune (atribute, operații și constrângeri) ale unui ansamblu de clase într-o clasă mai generală, numită superclasă. Clasele sunt ordonate într-o ierarhie.
Fig. 9. Exemplu de generalizare a unei clase.
Între pachete pot exista
următoarele relații:
·
Import/export. Presupunând două pachete, A și B, dacă pachetul A
importă pachetul B, atunci elementele din A vor vedea elementele publice din B.
Partea publică a lui B reprezintă exportul pachetului B. Grafic, se reprezintă
printr-o relație de dependența stereotipizată <<import>>.
Fig. 10. Importul unui pachet.
·
Generalizare. Este asemănătoare generalizării claselor. Pachetele
mai specializate moștenesc elementele publice și protejate de la pachetul mai
general. La fel ca în cazul claselor, pachetele mai specializate pot înlocui
pachetele mai generale, oriunde sunt folosite acestea.
Fig. 11. Generalizarea unui pachet.
Interfața reprezintă o colecție de
operații care specifică un serviciu al unei clase sau al unei componente.
Fig. 12. Exemplu de folosire a unei
interfețe.
3.2. Diagramele de tip
cazuri de utilizare
Cazul de utilizare implică interacțiunile dintre actori
și sistem. Actorii pot fi oameni sau sisteme automate. Grafic, un caz de
utilizare se reprezintă printr-o elipsă. Fiecare caz de utilizare trebuie să
aibă un nume distinct de al celorlalte cazuri de utilizare. Numele este format
dintr-un șir de caractere și se numește nume simplu. Nume de cale este
numele cazului de utilizare prefixat de numele pachetului din care face parte
acesta.
Actorul reprezintă un set de roluri pe care
utilizatorul le folosește când interacționează cu cazurile de utilizare. Un
actor reprezintă un rol uman, un dispozitiv hardware sau orice alt sistem. O
instanță a unui actor reprezintă o interacțiune individuală cu sistemul.
Actorii nu fac parte din sistem. Ei se află în afara sistemului și pot fi
conectați la cazuri de utilizare prin asocieri.
Comportamentul unui caz de utilizare se poate
specifica prin descrierea fluxului de evenimente. Când se scrie fluxul de
evenimente, trebuie să se indice cum și când începe și se încheie cazul de
utilizare, când interacționează cu actorii, ce obiecte sunt schimbate, fluxul
de bază și variantele comportamentului.
Fig. 13. Exemplu al unei diagrame UML de tip cazuri de
utilizare.
3.3. Diagramele de stare
O diagramă de stare modelează viața unui obiect prin
stările sale și schimbările de stare care au loc pe parcursul vieții.
Schimbările de stare sunt determinate de evenimente. Diagramele de stări
modelează efectul acestor interacțiuni asupra stării interne a fiecărui obiect.
Mesajele din diagramele de interacțiune sunt evenimente care schimbă starea
internă a obiectelor. Examinând diagramele de interacțiune se pot descoperi
care sunt obiectele care ar trebui modelate prin diagrame de stări. Multe
obiecte sunt create, referite și apoi distruse. Ele au o singură stare
intermediară și deci nu are sens modelarea lor printr-o diagramă de stări. Alte
obiecte, însă, care răspund la mesaje în mod diferit pe parcursul vieții, se
pot preta la această modelare.
Stările sunt reprezentate prin dreptunghiuri rotunjite
iar tranzițiile prin săgeți deschise. Starea inițială și cea finală se
reprezintă astfel:
starea inițială
starea finală
Fig. 14. Stările inițială și finală.
Starea inițială identifică (punctează către) starea în care obiectul este creat. De exemplu, în figura 14 această stare este Create. Cu toate că notația pentru starea inițială include numai cercul plin, în practică starea inițială include și săgeata care pleacă din ea și starea în care obiectul este creat.
La sfârșitul vieții (activității) sale, obiectul atinge starea finală, din care nu mai poate ieși. Starea finală are toate proprietățile unei stări, cu o excepție: nu poate avea tranziții de ieșire. Numele stării de ieșire este specificat lângă simbolul grafic al stării finale.
O
simplă tranziție reprezintă o relație între două stări consecutive,
indicând faptul schimbării unei stări cu o alta. Prezența obiectului modelat în
prima stare va efectua anumite acțiuni, dar trecerea în starea a doua se va
produce atunci când anumite acțiuni vor fi terminate și după îndeplinirea
anumitor condiții suplimentare.
Tranziția începe atunci când un anumit eveniment se
petrece: terminarea executării acțiunii (do activity), trimiterea
mesajului sau emiterea semnalului. În trecere se indică numele acțiunii. Mai
mult chiar, în tranziție poate fi indicată acțiunea produsă de un obiect ca
reacția tranziției de la o stare la alta.
Executarea tranziției poate depinde nu numai de
petrecerea unui anumit eveniment, dar și de la îndeplinirea condiției
corespunzătoare, care se numește condiție gardă. Obiectul va trece de la
o stare la alta, numai în cazul în care a apărut acțiunea indicată și condiția
de gardă este îndeplinită.
Fig. 15. Exemplu al unei diagrame UML de stare.
Starea compusă (composite state) este o stare alcătuită din alte stări depuse.
Ultimele vor fi substările (substate) pentru primul element. Deși între
ele există relația de compoziție, grafic, toate vârfurile diagramei care
corespund substărilor depuse sunt reprezentate înăuntrul simbolului stării compuse.
În acest caz, dimensiunile simbolului grafic al stării compuse se măresc astfel
ca toate substările să fie incluse.
Fig. 16. Exemplu de stare compusă.
4.
Desfășurarea lucrării
Se instalează aplicația wamp (de
exemplu, în C:\wamp). După ce wamp-ul
a fost instalat, se va face un import al dump-ului. Pentru a face acest lucru
se deschide phpmyadmin, accesând URL-ul http://localhost/phpmyadmin. Aici se
deschide tab-ul Databases, se introduce numele bazei de date (jsuml),
se alege collation utf8_general_ci și se apasă butonul Create.
Având baza de date creată, următorul pas îl constituie
importul acesteia. În partea stângă a aplicației phpmyadmin, se observă numele
noii baze de date create. Se face clic pe acesta și apoi pe butonul Import. De
aici se va efectua upload-ul fișierului db.sql, făcând clic pe
butonul Browse/Choose din dreptul propoziției Browse your
computer. Se va selecta fișierul db.sql de pe hard-disk și se va apăsa
butonul GO. Se copiază directorul jsuml în C:\wamp.
Observație. Dacă numele bazei de date este altul
decât jsuml, sau utilizatorul mysql root are o parolă, se
pot modifica aceste date accesând fișierele open.php și save.php.
de unde se modifica doar cuvintele cu bold din următoarele linii:
$link = mysql_connect('localhost', 'root',
'password');
$db_selected = mysql_select_db('jsuml', $link);
unde: localhost
= numele serverului;
root = numele
utilizatorului bazei de date;
password = parola
asociată utilizatorului bazei de date,
jsuml = numele bazei de date.
Pentru a rula aplicația, se
accesează URL-ul http://localhost/jsuml, folosind ca browser ultima
versiune de Mozilla Firefox, Google Chrome sau Internet Explorer.
1.
Se selectează
diagrama nouă de tip clasă .
2.
Numele diagramei
curente se poate schimba făcând clic pe porțiunea de deasupra zonei de lucru . Noul nume va fi Diagrama Calculator.
3.
Se introduce un
pachet, astfel: se face clic pe elementul Container pentru pachet (Package)
și apoi încă un clic în zona de lucru în care se dorește a fi poziționat
elementul. Numele pachetului astfel introdus va fi ComponentePlacaBază.
Observație: orice
element poziționat în zona de lucru poate fi redimensionat cu drag&drop
deasupra pătratului din stânga jos a elementului .
4.
Se atașează
pachetului un număr de 4 clase (Rezistor, Condensator, Tranzistor, Diodă).
Acest lucru se face prin apăsarea elementului Clasă, modificarea numelui
clasei și adăugarea elementului de legătură Alcătuiește pentru a face
legătura dintre pachet și clasă.
Observație: numele clasei se poate schimba făcând clic pe porțiunea din partea de sus a elementului (vezi figura 16).
Fig. 16. Elementele unei clase.
5.
Se creează o
nouă clasă PlacaDeBază, care are ca atribute publice atributele Procesor și
PlacaVideo. Clasa PlacaDeBază va importa pachetul denumit ComponentePlacaBază, folosind elementul
Import public de pachete. Acest element se folosește ca și elementul
Alcătuiește.
Observație. Pentru
a adăuga un atribut nou se face clic pe punctul verde asociat atributelor (vezi
figura 16). După ce a fost adăugat atributul, se face dublu clic pe noul
atribut creat și va apărea o fereastră asemănătoare celei din figura 17. Cu
ajutorul ferestrei, se poate completa vizibilitatea (publică, privată,
protejată), numele, tipul acestuia, valoarea
inițială și valoarea/valorile pe care nu le poate avea atributul selectat.
Fig.17. Proprietățile unei atribut al unei clase.
6.
Se adaugă încă
două clase: Monitor și Tastatură. Clasa Monitor va avea două atribute
publice: Rezoluție și Contrast, iar clasa Tastatură, doar un singur atribut
privat: NumărTaste.
7.
Se creează clasa
Calculator, care va avea 3 atribute derivate: PlacaDeBază, Tastatură și
Monitor, precum și două metode publice: Pornește și Oprește.
8.
Clasele
PlacaDeBază și Tastatură vor fi conectate de clasa Calculator folosind
elementul Generalizare, iar pentru a conecta clasa Monitor de clasa
Calculator se va folosi elementul Agregare. Se vor completa câmpurile acestui
element ca în figura 18.
.
Fig. 18. Câmpurile ce descriu un element de agregare.
Completând elementul de agregare cu valorile
din figura 18, se spune că un calculator poate conține cel puțin un monitor.
9.
Se salvează
diagrama UML cu un nume de forma nume_student-tip_diagrama-data.
La sfârșit ar trebui să apară o diagramă ca
în figura 19.
Fig. 19. Diagrama rezultată după urmarea pașilor de mai sus.
10. Procedând într-un mod similar, creați diagramele din
figurile 20 și 21.
Fig. 20. Diagramă de tip caz de utilizare exemplu.
Fig. 21. Diagramă de stare exemplu.
5. Întrebări
1.
Ce este o
diagramă UML și care este rolul acesteia?
2.
Ce este o
diagramă UML de tip clasă? Dar o diagramă UML de tip stare?
3.
Care este
elementul principal dintr-o diagramă de tip cazuri de utilizare?
4.
Care sunt
elementele principale ale diagramei de stare?
5.
Ce reprezintă
funcția de agregare? Dar funcția de generalizare?
6.
Diagrama de la
punctul 9 din desfășurarea lucrării este o diagramă UML corectă? Dacă nu, ce ar
trebui făcut pentru a o corecta?
7.
Care sunt pașii
necesari pentru ștergerea unui element din zona de lucru?
8.
Creați o
diagramă UML care să conțină cel puțin o clasă, o interfață și un pachet, pe
care să le definiți corespunzător.
9.
Ce elemente au
fost utilizare pentru construcția ultimei diagrame prezentate în desfășurarea
lucrării?
10.
Care sunt pașii
necesari pentru a salva o diagramă UML? Dar pentru salvarea unei zone de lucru?
11.
Care sunt
elementele de legătură pentru diagrama de tip clasă, așa cum rezultă din
rularea aplicației?
12.
Cum se adaugă
mai multe atribute într-o clasă?
13.
Cum se face
legătura dintre o clasă și o interfață?
14.
Detaliați modul în care ați creat sistemul din diagrama prezentată în
figura 20.
15.
Ce considerați
că ar trebui modificat sau adăugat la prezenta aplicație? Propuneți soluții de
optimizare a acesteia.