UML (Unified Modeling Language) és el llenguatge unificat de modelatge.
Es tracta d'un conjunt de notacions gràfiques que serveixen per especificar, dissenyar, elaborar
i documentar models de sistemes i, en particular, d'aplicacions informàtiques.
A partir d'aquestes notacions gràfiques o diagrames, les persones responsables de l'anàlisi i del disseny
poden descriure les característiques que haurà de tindre l'aplicació que l'equip de desenvolupament
crearà posteriorment.
En l'actualitat, és el llenguatge de modelatge de sistemes més conegut i utilitzat.
Gaudeix d'una acceptació pràcticament universal i, entre altres beneficis, ha impulsat el desenvolupament
de ferramentes de modelatge gràfic del programari orientat a objectes.
La notació UML té els avantatges següents:
Notació gràfica: es basa en una notació gràfica concreta i fàcil d'interpretar,
que es completa amb explicacions escrites.
Flexibilitat: permet utilitzar només els diagrames que es consideren oportuns, i amb el grau
de detall adequat a les característiques del sistema.
Visió global: permet tindre una visió global del sistema que s'ha d'implementar.
Reutilització: promou la reutilització.
No obstant això, cal tindre en compte que:
UML no és una metodologia, sinó una notació.
UML no és un llenguatge de programació.
Pot resultar complex conéixer totes les possibilitats del llenguatge.
UML inclou una gran varietat de diagrames, que es classifiquen en estàtics
(Figura 1) i dinàmics (Figura 2).
Institut Obert de Catalunya
Figura 1. Diagrames estàtics.
Institut Obert de Catalunya
Figura 2. Diagrames dinàmics.
Aquesta unitat didàctica se centra en un dels diagrames estàtics: el diagrama de classes.
Un diagrama de classes és un diagrama estàtic que representa les classes que s'utilitzaran
dins del sistema i les relacions que hi ha entre elles. És un dels diagrames més utilitzats
en les fases d'anàlisi i de disseny basades en UML.
En aquestes fases es comença a crear el model conceptual de les dades que utilitzarà el sistema.
Per això, s'identifiquen els components (amb els seus atributs i funcionalitats) que prendran part
en els processos i es defineixen les relacions que hi haurà entre ells.
Un diagrama de classes inclou alguns conceptes que ajuden a entendre'n la creació i el funcionament
(Figura 3):
Classe, atribut i mètode (operacions o accions).
Visibilitat.
Objecte i instanciació.
Relacions: associació, herència, composició i agregació.
Classe associativa.
Interfícies.
Institut Obert de Catalunya
Figura 3. Resum dels elements d'un diagrama de classes.
Una classe és una representació d'un objecte del món real o abstracte, compost d'atributs,
que representen les característiques de l'objecte, i de mètodes, que en representen les accions.
El nom de les classes s'escriu amb la notació UpperCamelCase, és a dir, comença en majúscula
i cada paraula comença també en majúscula (CicleFormatiu).
Els atributs (també anomenats propietats o característiques) són les dades que contenen
els objectes. Els valors dels atributs corresponen a cada objecte que instancia la classe
i fan que tots els objectes siguen diferents entre si.
Cada atribut té assignat un tipus i una multiplicitat. El nom dels atributs s'escriu amb la notació
lowerCamelCase, és a dir, comença en minúscula i cada paraula següent comença en majúscula
(dataNaixement).
El tipus indica la naturalesa de les dades (numèriques, alfanumèriques, booleanes...).
Els tipus poden ser:
Tipus primitius: tipus de dades bàsiques que proporciona el llenguatge de programació,
com int, char, boolean o float.
Tipus derivats: tipus de dades que es creen a partir de tipus primitius, com String o Date.
Els mètodes implementen les accions que es poden dur a terme sobre els atributs.
Permeten aplicar canvis sobre els atributs, però també moltes altres accions relacionades
amb l'objecte, com obrir-lo, tancar-lo, carregar-lo o fer càlculs.
Cada mètode es defineix amb un nom, els paràmetres que rep i el valor que retorna:
Paràmetres: tenen nom, tipus i multiplicitat.
Valor de retorn: si n'hi ha, només té tipus i multiplicitat.
A més, els mètodes poden llançar excepcions, que són errors que poden ocórrer durant l'execució
del codi. Si un mètode pot llançar alguna excepció concreta, cal indicar-ho.
Les classes es representen amb un rectangle dividit en tres apartats (Figura 4):
Nom: el nom de la classe.
Atributs: els atributs de la classe, amb la seua visibilitat i el seu tipus.
Mètodes: els mètodes de la classe, amb la seua visibilitat, els paràmetres i el tipus del valor de retorn.
classDiagram
class Persona{
-DNI: String
-nom: String
-adreça: String
-telefon [0..*]: String
-dataNaixement: Date
+edat() int
+afegirTelefon(telefon : String) void
}
Figura 4. Representació de la classe Persona.
L'objectiu d'aquesta unitat és entendre els conceptes de la programació orientada a objectes.
No cal fer la transformació a codi Java. S'inclou en el material per mostrar un exemple concret
d'implementació d'aquesta estructura.
Exemple: Transformació a codi Java
La classe Persona es podria traduir amb el codi següent. És important entendre que el diagrama
només defineix l'estructura, però no la implementació concreta.
Un objecte és una instància d'una classe. La instanciació és l'acció de crear una instància
d'una classe, i es realitza en temps d'execució mitjançant una crida al mètode constructor de la classe.
És a dir, mentre que una classe defineix el disseny conceptual, un objecte és un element
concret d'aquesta classe.
Exemple: Instanciació de la classe Persona
A partir de la classe Persona, es poden crear diferents objectes amb aquesta estructura,
amb valors diferents i independents entre ells (Figura 5).
Figura 5. Instància de la classe Persona.
En Java, els objectes es creen amb l'operador new:
CrearPersones.java
packageud3.examples.persones;publicclassCrearPersones{publicstaticvoidmain(String[]args){Personap1=newPersona("12345678S","Joan","C/Còrsega","25/07/1988");Personap2=newPersona("87654321T","Marta","Av. Cardenal Benlloch","01/04/1995");p1.afegirTelefon("+34 654876195");System.out.printf("Edat de Joan: %d\n",p1.edat());System.out.printf("Edat de Marta: %d\n",p2.edat());}}
La visibilitat d'un atribut o d'un mètode defineix l'àmbit des del qual es pot utilitzar.
Aquesta característica està directament relacionada amb l'encapsulació, un concepte de l'orientació
a objectes que permet a cada objecte decidir quina part de la seua informació és pública per a la resta.
Les possibilitats per a la visibilitat, tant d'atributs com de mètodes, són:
+ o public: l'element és accessible des de tots els altres elements del sistema.
- o private: l'element només és accessible des dels elements del mateix objecte.
# o protected: l'element només és visible per als elements del mateix objecte i per als
objectes que en són especialitzacions (herència).
~ o package: l'element només és visible per als elements del mateix paquet.
En Java, es considera una bona pràctica no definir atributs com a public.
Si cal accedir a un atribut o modificar-lo des d'una altra classe, es defineixen els mètodes
get (getter) i set (setter).
Els mètodes get i set es poden indicar en el diagrama (Figura 6),
tot i que aquesta notació no està definida en l'estàndard UML1.
classDiagram
class Persona{
-DNI: String
«get» -nom: String
«get/set» -adreça: String
-telefon [0..*]: String
-dataNaixement: Date
+edat() int
}
Figura 6. Representació de la classe Persona amb getters i setters.
Exemple: Getters i setters en Java
La classe anterior es tradueix amb el codi següent:
publicclassPersona{// AtributsprivateStringdni;privateStringnom;privateStringadreça;privateList<String>telefons;privateLocalDatedataNaixement;// ConstructorpublicPersona(Stringdni,Stringnom,Stringadreça,List<String>telefons,StringdataNaixement){...}// Mètodespublicintedat(){...}// Getters i setterspublicStringgetNom(){returnthis.nom;}publicStringgetAdreça(){returnthis.adreça;}publicvoidsetAdreça(Stringadreça){this.adreça=adreça;}}
S'observa que l'atribut nom només té getter, mentre que adreça té getter i setter.
Les relacions d'un diagrama de classes especifiquen quines classes estan relacionades.
Per relació s'entén que un objecte interactua d'alguna manera amb un altre objecte.
Si una classe té una altra classe com a atribut, totes dues estan relacionades, i aquest atribut
es defineix en l'associació entre elles.
Exemple: Relació entre classes
La classe Habitació està relacionada amb la classe Persona, ja que Habitació conté
un objecte Persona com a atribut (Figura 8).
Figura 8. Associació entre les classes Habitació i Persona.
Les relacions també tenen una multiplicitat, que especifica amb quants objectes d'una classe
es relaciona cada objecte de l'altra classe. Les multiplicitats s'especifiquen de la mateixa manera
que la multiplicitat dels atributs (vegeu Atributs).
Exemple: Relació amb multiplicitat
En l'exemple anterior, s'observa que una Habitació està relacionada amb una Persona
amb una multiplicitat 1 a 1..*. És a dir:
Una Habitació està relacionada amb una única Persona, que s'emmagatzema en l'atribut client.
Una Persona pot estar relacionada amb més d'una Habitació.
Les relacions entre classes, en general, s'anomenen associacions. Una associació és una relació
estructural que defineix les connexions entre dos o més objectes, i es representa amb una línia contínua,
sense fletxes ni cap altre símbol en els extrems.
Una associació amb dos extrems és binària, com en el cas d'un client que reserva una habitació d'hotel.
Una associació amb tres extrems és ternària (Figura 9).
Una associació reflexiva és una associació d'una classe amb ella mateixa.
Aquest tipus d'associació és útil per modelar relacions jeràrquiques o recursives.
Exemple: Associació reflexiva
La classe Categoria pot contindre subcategories, que també són de la classe Categoria
(Figura 10).
Figura 10. Exemple d'associació reflexiva Categoria.
La navegabilitat especifica si una instància d'una classe pot accedir eficientment als objectes
de l'altra classe de la relació. Pot ser de tres tipus:
No especificada: no s'indica si es pot navegar d'un objecte a l'altre. És el valor per defecte.
Navegable: sí que es pot navegar d'un objecte a l'altre.
S'indica amb una fletxa oberta en l'extrem de l'associació.
No navegable: no es pot navegar d'un objecte a l'altre.
S'indica amb una X en l'extrem de l'associació.
Institut Obert de Catalunya
Figura 11. Exemple de navegabilitat en una associació.
En la Figura 11, per exemple, s'indica que A4 pot accedir a B4,
però que B4 no pot accedir a A4.
Una agregació és un cas especial d'associació entre dos o més objectes, del tipus
tot-part. Hi intervenen dos tipus d'objectes: l'objecte base i els objectes que hi estan inclosos.
Si l'objecte base desapareix, els objectes inclosos no desapareixen i continuen existint
amb les seues funcionalitats pròpies. L'agregació es representa amb una línia contínua que acaba
amb un rombe buit en l'extrem de l'objecte base.
Institut Obert de Catalunya
Figura 12. Exemple d'agregació.
En la Figura 12, l'objecte base és Fruiteria, que inclou els objectes Pomes,
Taronges, Peres i Maduixes. Entre aquestes classes hi ha una relació tot-part, on les fruites són
part de la fruiteria. No obstant això, si la fruiteria deixa d'existir, les fruites continuen existint.
Una composició és també una associació del tipus tot-part, molt semblant a l'agregació.
La diferència és que hi ha una dependència d'existència entre l'objecte base i els objectes inclosos.
És a dir, si l'objecte base deixa d'existir, els objectes inclosos també deixen d'existir: el temps de vida
de l'objecte inclòs depén del temps de vida de l'objecte base. La composició es representa amb una línia
contínua que acaba amb un rombe ple.
Figura 13. Exemple de composició.
En la Figura 13, l'objecte base Cotxe es compon dels objectes Volant, Roda,
Fre i Deposit. Sense l'objecte Cotxe, la resta d'objectes deixen d'existir.
Una dependència és una relació semàntica entre dues classes: si hi ha un canvi en l'objecte
independent, l'objecte dependent es veu afectat.
Es representa amb una fletxa discontínua entre els dos elements. L'objecte del qual ix la fletxa és
el dependent, i l'objecte al qual arriba és l'independent.
Figura 14. Exemple de dependència.
En la Figura 14, l'objecte Grup depén de l'objecte CicleFormatiu.
Per exemple, el GrupDAW1 depén del CicleFormatiuDAW: si canvia la denominació
o els continguts del cicle DAW, el grup DAW1 es veu afectat.
La generalització és una relació d'herència entre classes. Una de les classes és la classe
mare o superclasse, i les altres són les classes filles, subclasses o especialitzacions,
que hereten els atributs, els mètodes i el comportament de la classe mare.
Aquesta relació es representa amb una fletxa que ix de la classe filla i acaba en la classe mare.
Figura 15. Exemple de relació de generalització.
En la Figura 15, la classe Animal és la classe mare, i les classes Gos i Gat
en són especialitzacions. Les subclasses contenen els atributs i mètodes de la classe Animal,
però cadascuna pot implementar mètodes nous o tindre atributs nous.
Quan una associació té atributs o mètodes propis, es representa com una classe associativa,
unida a la línia de l'associació mitjançant una línia discontínua. Tant la línia com el rectangle
de la classe representen el mateix element conceptual: l'associació.
Institut Obert de Catalunya
Figura 16. Exemple de classe associativa.
En la Figura 16, la classe Estudiant està relacionada amb la classe
Assignatura: cada estudiant pot cursar diverses assignatures, i cada assignatura pot tindre molts estudiants.
A més, cada estudiant té una nota determinada en cada assignatura. Aquesta situació es pot modelar
amb una classe associativa.