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.

3.1. Diagramele de tip clasă

Î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.