Identificarea Claselor
Activitatea de identificare a claselor si obiectelor este una prin excelenta
creativa, pentru care nu exista retete fixe, si in legatura cu care Booch
face o afirmatie cam descurajanta, anume: "This is hard!".
Experienta castigata in aplicarea procesului de dezvoltare Rational
Objectory a condus insa la formularea unor recomadari-cadru, printre care
si aceea ca identificarea claselor pentru un sistem se incepe cu cautarea
a 3 categorii de clase:
Boundary Classes
Reprezinta suportul pentru comunicarea intre sistem si mediul extern.
Ele modeleaza interfata cu utilizatorul sau cu un alt sistem, pe scurt
interfata cu actorii. Clasele limitrofe sunt dependente de mediul extern
al sistemului.
Pentru a descoperi clasele limitrofe se examineaza fiecare pereche
<actor, caz de utilizare>.
Considerand problema prezentata
in lucrarile precedente vom exemplifica identificarea claselor abordand
subfluxul "Adauga oferta de cursuri"
(S-1)
al cazului de utilizare "Selectia cursurilor de predat".
Acest caz interactioneaza doar cu actorul Profesor.
Subfluxul considerat specifica una dintre capabilitatile pe care cazul
de utilizare trebuie sa le ofere Profesorului. In aceasta situatie avem
nevoie in primul rand de o clasa care sa gestioneze lista optiunilor disponibile
pentru Profesor, pe care
o vom numi OptiuniProfesor.
In al doilea rand mai avem nevoie de o clasa care sa se "ocupe" special
de optiunea de adaugare, pe care o vom numi AdaugaOfertaCurs.
Entity Classes
Se mai numesc si clase de domeniu
si modeleaza informatii care au o durata lunga de existenta in cadrul sistemului.
Ele pot corespunde unor entitati din lumea reala sau pot indeplini sarcini
interne in sistem. De regula, ele sunt independente de mediul lor inconjurator
si chiar de aplicatie, putand fi utilizate in mai multe aplicatii.
Identificarea lor incepe prin studiul fluxurilor de evenimente, luandu-se
ca punct de plecare o lista de substantive care descriu responsabilitatile
sistemului.
In exemplul nostru putem identifica drept entitati care intervin in
subfluxul analizat urmatoarele: Curs,
OfertaCurs
si
InformatiiProfesor
(informatiile
de identificare ale profesorului). Se poate observa ca aceste clase pot
fi utilizate si in alte aplicatii cu specific universitar.
Control Classes
Modeleaza inlantuirea operatiilor specifice cazurilor de utilizare.
Ele coordoneaza evenimentele necesare pentru a realiza comportamentul specificat
de cazurile de utilizare. Aceste clase pot fi gandite ca un fel de suport
de executie al cazurilor de utilizare ce modeleaza dinamica acestora. De
regula, clasele de control sunt dependente de aplicatie.
La inceputul fazei de Elaborare se prevede cate o clasa de control
pentru fiecare pereche <actor, caz de utilizare>. Ulterior, pe masura
ce se avanseaza cu analiza si proiectarea, este posibil sa se mai elimine
unele clase de control, respectiv clasele existente sa fie comasate sau
divizate.
O clasa de control care realizeaza mai mult decat secventializarea
evenimentelor unui caz de utilizare nu este bine proiectata. O asemenea
clasa trebuie sa "stie" doar cand sa
se execute o anumita operatie, NU si cum sa
se execute. Astfel, pentru exemplul considerat mai sus, vom prevedea
o clasa care sa gestioneze fluxul evenimentelor pentru cazul "Selectia
cursurilor de predat", pe care o vom numi ManagerCursuriProfesor.
Aceasta clasa va sti cand trebuie efectuata operatia de adaugare a unei
oferte, de exemplu, dar nu ea va realiza operatia respectiva, ci clasa
OfertaCurs.
Stereotipuri (in contextul claselor)
Stereotipurile utilizate impreuna cu clasele permit definirea unor multimi (categorii) de clase. Exemple tipice de stereotipuri pentru clase: Entity, Boundary, Control, Utility, Exception.
Stereotipul se plaseaza deasupra numelui clasei, in interiorul dreptunghiului
folosit pentru reprezentarea clasei:

Exista posibilitatea de a atasa o anumita culoare unui stereotip, pentru a reprezenta clasele respective in diverse diagrame. Astfel, se poate decide ca toate clasele cu stereotipul Exception sa fie desenate cu rosu.
Pachete
Daca numarul claselor identificate pentru un sistem este mic, gestionarea
lor este relativ simpla.
Daca sistemul cuprinde multe clase, apare necesitatea unui mecanism de grupare a lor. In cadrul notatiei UML mecanismul de grupare este reprezentat de pachete.
La nivelul planului logic al arhitecturii (logical view) un pachet este o colectie formata din:
Pentru un sistem complex organizarea claselor in pachete se incepe chiar in faza de Elaborare. Pentru sisteme mai simple clasele identificate la inceputul analizei pot constitui un timp un pachet unic - sistemul insusi. Pe masura ce analiza avanseaza urmeaza sa se reorganizeze clasele pe mai multe pachete.
Pentru exemplul analizat pana acum se poate observa ca cele 6 clase identificate pot fi grupate in 3 categorii:

Cand se modeleaza un sistem este necesara nu doar identificarea entitatilor ce formeaza vocabularul aplicatiei, ci si evidentierea relatiilor care se stabilesc intre aceste entitati.
O relatie este o conexiune intre entitati.
In cadrul modelarii orientate pe obiecte 3 tipuri de relatii sunt mai importante:
Tipuri de Relatii Structurale
Relatia de Asociere
Asocierile sunt relatii structurale reprezentand conexiuni semantice bidirectionale intre clase. Daca 2 clase C1 si C2 sunt asociate, aceasta inseamna ca exista legaturi intre obiectele din C1 si respectiv C2. Se mai spune ca o legatura este o instanta a unei asocieri.
O relatie de asociere poate fi "navigata" in ambele sensuri.
Simbolul grafic utilizat pentru reprezentarea unei asocieri este o linie continua care leaga clasele asociate:

Reprezentarea Relatiilor Reflexive
Este posibil ca o clasa sa fie asociata cu ea insasi. O asemenea asociere
se numeste asociere reflexiva.
(fig. 13.1)
Simbolul de baza care reprezinta o relatie de asociere poate fi insotit de 4 elemente descriptive suplimantare care dau informatii cu privire la asocierea respectiva, si anume:
O asociere poate avea un nume care sa descrie natura ei si sa o identifice
in cadrul unei multimi de asocieri. Numele poate fi insotit de un triunghi
cu un varf indreptat spre unul din capetele relatiei, care reprezinta sensul
numelui. Sensul numelui nu are legatura cu posibilitatile de navigare a
relatiei, el serveste doar la eliminarea eventualelor ambiguitati ale numelui
. De exemplu in fig.13.1 obiectele clasei ManagerCursuriProfesor "controleaza" obiectele clasei Curs. La randul lor, obiectele clasei Curs "se bazeaza" pe alte obiecte ale aceleiasi clase (pentru a putea urma un curs uneori sunt necesare cunostinte de la cursuri urmate anterior).
In general, numele asocierii poate lipsi, mai ales daca sunt specificate
rolurile claselor implicate.
Roluri. Denumirea Rolurilor
O clasa participanta la o relatie de asociere joaca un anumit rol in
relatia respectiva. Rolul este "fata" pa care o clasa o arata spre clasa
asociata. Aceeasi clasa poate juca roluri diferite in asocieri diferite,
dar si roluri identice.
Denumirea unui rol este un substantiv care desemneaza scopul in care
o clasa se asociaza cu alta. Numele rolului insoteste segmentul ce reprezinta
relatia, fiind plasat langa clasa care joaca rolul respectiv.

Indicatori de
multiplicitate
Un indicator de multiplicitate specifica numarul de obiecte care participa
la un capat al unei asocieri. Multiplicitatea se reprezinta ca un numar
sau ca un interval numeric si se interpreteaza astfel: valoarea inscrisa
la un capat al asocierii este numarul de obiecte care pot fi legate cu
un singur obiect de la celalalt capat al asocierii (fig.13.1). Multiplicitatea
se refera deci la obiecte, nu la clase, desi in reprezentarea grafica apar
clasele.
Indicatorii de multiplicitate se plaseaza la ambele capete ale unei
asocieri.
Forme tipice de prezentare a indicatorilor de multiplicitate sunt:


Asociere vs. Agregare
Nu intotdeauna este evident faptul ca o relatie de asociere este de
fapt o agregare. Pentru a decide asupra acestui lucru, urmatoarele intrebari
pot fi utile:
Cum stabilim relatiile de asociere?
Pentru aceasta se studiaza scenariile. Acolo unde exista schimburi
de mesaje inseamna ca obiectele implicate trebuie sa comunice intre ele.
Asocierile si/sau agregarile reprezinta suportul necesar comunicarii.
Relatiile mai pot fi identificate si prin examinarea semnaturilor operatiilor.
Relatia de Dependenta
Este o relatie semantica intre 2 entitati al carei sens este urmatorul:
o modificare adusa uneia dintre entitati (cea independenta) poate afecta
semantica celeilalte entitati (cea dependenta), reciproca nefiind intotdeauna
adevarata. Simbolul grafic utilizat pentru reprezentarea unei dependente
este:
- - - - - - - - - - - - - - - - >
Relatii intre Pachete
La nivelul pachetelor de clase se stabilesc de regula relatii de dependenta.
Un pachet A depinde de un alt pachet B daca cel putin o clasa din A initiaza
comunicari cu clase publice din B. Pachetul A este in acest caz clientul,
iar pachetul B serverul (furnizorul).
Relatiile intre pachete se identifica pe baza scenariilor si a relatiilor
deja identificate pentru clase.
In figura de mai jos pachetul UniversityArtifacts
este clientul, iar Interfaces este serverul.

Relatia de Mostenire
Este de fapt o relatie de generalizare. Ea apare intre o entitate generala
(parinte) si o varianta specifica a entitatii generale (fiu). Relatia de
generalizare se mai numeste relatie de tip "is-a-kind-of" ("este un fel de").
In contextul claselor entitatea parinte se mai numeste superclasa,
iar fiul - subclasa, iar relatia de generalizare este o relatie de mostenire.
Daca doua clase sunt conectate prin relatie de generalizare, atunci
instantele subclasei pot fi utilizate in orice loc in care pot sa apara
instante ale superclasei, dar nu si invers. Pe scurt, fiul poate substitui
parintele.
In cadrul unei relatii de mostenire fiul mosteneste de la parinte structura,
comportamentul si relatiile cu alte clase. Pe langa elementele mostenite,
o subclasa poate sa adauge atribute si operatii proprii.
O operatie a subclasei se spune ca redefineste o operatie din superclasa
daca cele doua au semnaturile identice. Aceasta capabilitate, impreuna
cu posibilitatea de a lucra cu instante ale subclaselor prin intermediul
unei superclase comune formeaza baza conceptului de polimorfism.
O clasa poate avea 0, 1 sau mai multi parinti.
O clasa care nu are parinti, dar are cel putin un fiu, se numeste clasa de baza sau radacina.
O clasa care nu are nici un fiu se mai numeste clasa frunza.
O clasa cu un singur parinte se spune ca este implicata intr-o relatie
de mostenire simpla.
O clasa cu mai multi parinti este implicata intr-o relatie de mostenire multipla.
Pentru reprezentarea relatiei de mostenire se utilizeaza simbolul:

Deoarece mostenirea nu este o relatie intre diferite obiecte, ea nu
se caracterizeaza prin nume, roluri si multiplicitate.
Mostenirea este un mecanism de baza care se aplica in scopul reutilizarii.
O clasa creata pentru o aplicatie poate fi extinsa prin crearea unei subclase
care sa fie utilizata in alta aplicatie.
Exista 2 cai pentru a crea relatii de mostenire:

Specializarea
Este un proces invers generalizarii, care presupune crearea de subclase
care sa reprezinte detalieri ale unei superclase, de regula prin adaugarea
de structura si comportament specifice si/sau prin redefinirea unor operatii
ale superclasei.
Elementul folosit ca baza in operatia de specializare se numeste discriminant.
Discriminantul reprezinta o multime finita de valori, pentru fiecare valoare
putand fi creata o subclasa.
De exemplu, pentru clasa Curs un discriminant poate fi constituit de
locul unde se desfasoara cursurile. Corespunzator acestui discriminant
putem crea 2 subclase: CursInCampus si CursInExterior.
Unei superclase ii pot corespunde mai multi discriminanti. Astfel,
pentru clasa Curs un alt discriminat poate fi referitor la obligativitatea
cursurilor, subclasele aferente putand fi: CursObligatoriu si CursFacultativ.
O relatie de mostenire poate fi reprezentata sub forma unui arbore
in care apar toate subclasele create pentru un discriminant, impreuna cu
superclasa comuna. Considerand exemplul de mai sus, corespunzator celor
2 discriminanti avem 2 arbori:

Mostenire vs. Agregare
Ca regula de baza, mostenirea trebuie folosita pentru a separa aspectele
comune de cele specifice, in timp ce agregarea trebuie folosita pentru
a modela relatii de compozitie.
Probleme
Considerand problema prezentata
in lucrarile precedente, se cere sa se imagineze fluxul evenimentelor pentru cazul inscrierii la curs a unui student. Pe baza acestui flux se vor efectua urmatoarele:
Bibliografie
[BoRuJa99] Grady Booch,
James Rumbaugh,
Ivar Jacobson - "The Unified Modeling Language User Guide", Addison-Wesley,
1999
[Qua98] Terry Quatrani - "Visual Modeling
with Rational Rose and UML", Addison-Wesley, 1998