<div class="page">
<div class="cover text-center">
<img class="mx-auto" src=/itb/images/logo_mislata.png alt="logo">
# Diagrames de classes UML
<div class="text-end fit-content ms-auto my-3 mt-auto pt-3">
<p><strong>Autor:</strong> Joan Puigcerver Ibáñez</p>
<p><strong>Correu electrònic:</strong> j.puigcerveribanez@edu.gva.es</p>
<p><strong>Curs:</strong> 2024/2025</p>
</div>
<div>
<p class="fw-bold mb-0">Llicència: BY-NC-SA</p>
<p class="d-none d-md-block">(Reconeixement - No Comercial - Compartir Igual)</p>
<a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.ca" target="_blank">
<img class="mx-auto" src="/itb/images/license.png" alt="Licence"/>
</a>
</div><!--license-->
</div><!--cover-->
</div><!--page-->
{:toc}
##### Observacions
En aquest material, s'inclouran fragments de codi Java. L'objectiu d'aquest material NO
és apendre a desenvolupar el codi Java, sino entendre els conceptes del diagrama de classes
i la programació orientada a objectes.
## UML
__UML__ és l’acrònim, en anglès, de _Unified Modeling Language_, és a dir, __Llenguatge unificat de modelització__.
UML són 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, l’analista i el dissenyador
podran recrear les característiques que caldrà que tingui l’aplicació informàtica que els desenvolupadors hauran de crear posteriorment.
En l’actualitat és el llenguatge de modelització de sistemes més conegut i utilitzat.
Gaudeix d’una acceptació practicament universal i, entre altres beneficis,
ha tingut l’efecte d’impulsar el desenvolupament d’eines de modelització gràfica del programari orientat a l’objectes.
Els avantatges de la notació UML són els següents:
- Es basa en una notació gràfica concreta i fàcil d’interpretar, sent completada amb explicacions escrites.
- A l’analista i/o al dissenyador els permet fer ús dels diagrames que consideren oportuns i amb el grau de detall
que consideren, en funció de les característiques del sistema.
- Permet tindre una visió global del sistema a implementar.
- Promou la reutilització.
Cal tindre en compte que:
- UML no és una metodologia, és una notació.
- UML no és un llenguatge de programació.
- Pot resultar complex obtenir un coneixement complet de les possibilitats del llenguatge.
UML incorpora una gran varietat de diagràmes:
##### Diagrames estàtics
{height=500}{.center}
##### Diagrames dinàmics
{height=600}{.center}
En aquesta unitat didàctica ens centrarem en els estàtics __Diagrames de classes__.
## Diagrames de classes
Els diagrames de classes són uns diagrames de UML, classificat dins els diagrames de tipus estàtic.
És un dels diagrames més utilitzats a les metodologies d’anàlisi i de disseny que es basen en UML.
Un __diagrama de classes__ representa les classes que seran utilitzades dins el sistema i les relacions que existeixen entre elles.{.box}
Aquest tipus de diagrames són utilitzats durant les fases d’anàlisi i de disseny dels
projectes de desenvolupament de programari. És en aquest moment en què es comença a crear
el model conceptual de les dades que farà servir 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 porta vinculats alguns conceptes que ajudaran a entendre'n la creació
i el funcionament en la seua totalitat. Aquests conceptes són:
- Classe, atribut i mètode (operacions o accions).
- Visibilitat.
- Objecte. Instanciació.
- Relacions. Herència, composició i agregació.
- Classe associativa.
- Interfícies.
{.center}{height=600}
### Classes. Atributs i mètodes
Una __classe__ és una representació d'un objecte del món real o abstracte, el qual està composat d'__atributs__,
que representen característiques de l'objecte, i els __mètodes__, que representen les accions de l'objecte.{.box}
Es representen amb la notació __UpperCamelCase__, és a dir,
comencen en majúscula i cada paraula comença en majúscula.
#### Atributs
Els __atributs__ (també anomenats propietats o característiques) són les dades detallades
que contenen els objectes. Aquests valors corresponen a l’objecte que instancia la classe i
fa que tots els objectes siguen diferents entre si.{.box}
Cada atribut té assignat un tipus i una mutiliplicitat. Es representen amb la notació __lowerCamelCase__, és a dir,
comencen en minúscula i cada paraula comença en majúscula.
El __tipus__ indica la naturalesa de les dades (númeriques, alfanumèriques, booleanes, ...). Els tipus poden ser:
- [Tipus primitius](https://www.w3schools.com/java/java_data_types.asp).
- `int`
- `char`
- `boolean`
- `float`
- ...
- [Tipus derivats](https://www.w3schools.com/java/java_data_types_non-prim.asp) (altres classes).
- `String`
- `Date`
- ...
La __multiplicitat__ indica
quants diferents valors poden haver en un atribut:
| Possibles valors | Significat |
| :- | :- |
| `1..1` o `1` | Exactament un valor. Valor per defecte si no s'especifica cap multiplicitat. |
| `0..*` | Multiples valors, on es pot donar el cas que no tinga cap. |
| `1..*` | Multiples valors, però com a mínim un valor. |
| `m..m` o `m` | Exactament `m` valors. _Exemple_: `3..3` seria exactament 3 valors. |
| `m..n` | Interval `m` a `n`. `m` valors com a mínim, però no més de `n`. _Exemple_: `1..3` seria com a mínim 1 i com a màxim 3. |
#### Mètodes
Els __mètodes__ implementen les accions que es podran dur a terme sobre els atributs.
Ofereixen la possibilitat d’aplicar canvis sobre els atributs, però també moltes altres accions
relacionades amb l’objecte, com obrir-lo o tancar-lo, carregar-lo, fer càlculs...{.box}
Cada mètode es defineix amb un nom i cal especificar els paràmetres que reb i el valor que retorna.
- Els paràmetres tenen nom, tipus, multiplicitat.
- El valor de retorn, si n’hi ha, només té tipus i multiplicitat.
Els mètodes poden llançar __Excepcions__, que són errors que poden ocórrer durant l'execució
de codi. Si el mètode pot llançar alguna excepció concreta, cal indicar-ho.
#### Representació
Les classes és representen amb un rectangle dividit en 3 apartats:
- El nom de la classe.
- Els atributs de la classe. S'especifica la _visibilitat_ i el tipus.
- Els mètodes de la classe. S'especifica la _visibilitat_ els paràmetres i el tipus del valor de retorn.
```mermaid
classDiagram
class Persona{
-DNI: String
-nom: String
-adreça: String
-telefon [0..*]: String
-dataNaixement: Date
+edat() int
+afegirTelefon(telefon : String) void
}
```
::: warning
L'objectiu d'aquesta unitat és entendre els conceptes de la Programació Orientada a Objectes.
No heu de realitzar la transformació a codi Java. S'adjunta en el material per veure un exemple concret
d'implementació d'aquesta estructura.
:::
Aquesta classe es podria traduir amb el següent codi:
```java
import java.util.List;
import java.util.ArrayList;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.Duration;
public class Persona {
// Atributs
private String dni;
private String nom;
private String adreça;
private List<String> telefons;
private LocalDate dataNaixement;
// Constructor
public Persona(String dni, String nom, String adreça, String dataNaixement) {
this.dni = dni;
this.nom = nom;
this.adreça = adreça;
this.telefons = new ArrayList<>();
this.dataNaixement = LocalDate.parse(dataNaixement, DateTimeFormatter.ofPattern("dd/MM/yyyy"));
}
// Mètodes
public int edat() {
LocalDate dataActual = LocalDate.now();
int days = (int) Duration.between(dataNaixement.atStartOfDay(), dataActual.atStartOfDay()).toDays();
return days / 365;
}
public void afegirTelefon(String telefon) {
this.telefons.add(telefon);
}
}
```
#### Objectes. Instanciació
Un objecte és una instanciació d’una classe. El concepte
instanciació indica l’acció de crear una instància d’una classe.
La creació d’una instància d’una classe es refereix a fer una crida al
mètode constructor d’una classe en temps d’execució d’un programari.
Mentre que una __classe__ defineix el disseny conceptual, un __objecte__
és la especificació d'un element d'aquesta classe.{.box}
_Exemple_:
{.center}{height=200}
A partir de la classe `Persona`, puc crear diferents objectes utilitzant aquesta
estructura, amb diferents valors i independents entre ells.
```java
public class CrearPersones {
public static void main(String[] args) {
Persona p1 = new Persona("12345678S", "Joan", "C/Còrsega", "25/07/1988");
Persona p2 = new Persona("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());
}
}
```
#### Visibilitat
La __visibilitat__ d’un atribut o d’un mètode definirà l’àmbit des del qual
podran ser utilitzats aquests elements. Aquesta característica està directament
relacionada amb el concepte d’orientació a objectes anomenat _encapsulació_,
mitjançant el qual es permet als objectes decidir quina de la seva informació
serà més o menys pública per a la resta d’objectes.{.box}
Les possibilitats per a la visibilitat, tant d’atributs com de mètodes, són:
- `+` o `public`, que vol dir que l’element és accessible per tots
els altres elements del sistema.
- `-` o `private`, que significa que l’element només és accessible
pels elements continguts dins el mateix objecte.
- `#` o `protected`, que vol dir que l’element només és visible per als elements
del seu mateix objecte i per als elements que pertanyen a objectes que són especialitzacions (_herència_).
- `~` o `package`, que vol dir que l’element només és visible per als elements continguts
ment dins el paquet que on està l’objecte.
En Java es considera una bona pràctica NO definir attributs com a `pubilc`.
Si volem que es puga accedir o modificar algun atributs des d'una altra classe,
cal definir el mètode `get` (getter) i el mètode `set` (setter).
Els mètodes `get` i `set` es poden incloure en el diagrama, però realment
no està definit en el model UML.
```mermaid
classDiagram
class Persona{
-DNI: String
«get» -nom: String
«get/set» -adreça: String
-telefon [0..*]: String
-dataNaixement: Date
+edat() int
}
```
```java
public class Persona {
// Atributs
private String dni;
private String nom;
private String adreça;
private List<String> telefons;
private LocalDate dataNaixement;
// Constructor
public Persona(String dni, String nom, String adreça, List<String> telefons, String dataNaixement) { ... }
// Mètodes
public int edat() { ... }
}
// Getters i Setters
public String getNom(){
return this.nom;
}
public String getAdreça(){
return this.adreça;
}
public void setAdreça(String adreça){
this.adreça = adreça;
}
}
```
### Enumeracions
Les __enumeracions__ son classes representen un tipus de dada que sols permet
un conjunt definit de valors.{.box}
{.center}{height=250}
En l'exemple, tenim l'enumeració `DiaSetmana`, que sols permet els valors: `DILLUNS`, `DIMARTS`,
`DIMECRES`, `DIJOUS`, `DIVENDRES`, `DISSABTE` i `DIUMENGE`. També tenim la classe `Event` que
té lloc en un dia de la setmana determinat.
### Relacions entre classes
Les __relacions__ en un diagrama de classes especifiquen quines classes estan relacionades.
Per relació s'enten que un objecte interactúe d'alguna manera amb un altre objecte.{.box}
En l'exempe, podem veure la classe `Habitació`, que esta relacionada amb la classe `Persona`,
on `Habitació` conté un objecte `Persona` com atribut.
{.center}{height=150}
Les relacions també tenen assignada una __multiplicitat__, que especifica amb quants objectes
d'una classe es relaciona l'altre objecte de l'altra classe. Les multiplicitats s'especifiquen
de la mateixa manera que la multiplicitat dels attributs (consultar [taula](#atributs)).
Si una classe té una altra classe com a atribut i estan relacionades, aquest atribut es defineix en la associació.
En l'exemple anterior, es pot observar que una `Habitació` està relacionada sols amb una `Persona`,
però una `Persona` pot estar relacionada amb més d'una `Habitació`. A més, podem veure que la classe
`Habitació` té un atribut anomenat `client` que és un objecte de la classe `Persona`.
#### Associació
Les relacions entre les diferents classes, generalment, s'anomenen __associacions__.
Aquestes relacions es representen mitjançant una línia contínua, sense fletxes ni cap altre símbol
als extrems. És un tipus de relació estructural que defineix les connexions entre dos o més objectes.
Una associació amb dos extrems es diu que és binària;
seria el cas de l’exemple d’un client que reserva una habitació d’hotel.
Una associació amb tres extrems es diu que és ternària.
{.center}{height=300}
#### Navegabilitat
La __navegabilitat__ especifica si una instància d'una classe pot accedir
eficientment als objectes de l'altra classe de la relació.
- __No especificat__: No s'especifica si es pot navegar d'un objecte a l'altre. Per defecte.
- __Navegable__: Especifica que __sí__ es pot navegar d'un objecte a l'altre.
S'indica amb una fletxa oberta al final de la associació.
- __No navegable__: Especifica que __no__ es pot navegar d'un objecte a l'altre.
S'indica amb una `X` al final de la associació.
{.center}{height=75}
En aquest exemple s'indica que `A4` pot accedir a `B4`, però que `B4` no pot accedir a `A4`.
#### Agragació
Una __relació d’associació d’agregació__ és un cas especial d’associació
entre dos o més objectes. Es tracta d’una relació del tipus tot-part.
Aquest tipus de relació implica dos tipus d’objectes, l’objecte anomenat base
i l’objecte que estarà inclòs a l’objecte base.
Si desapareix l’objecte base, el o els objectes que es troben inclosos
en l’objecte base no desapareixeran i podran continuar existint amb
les seves funcionalitats pròpies. La relació d’associació d’agregació
es representa mitjançant una línia contínua que finalitza en un dels extrems
per un rombe buit, sense omplir. El rombe buit s’ubicarà a la part de l’objecte base.
{.center}{height=300}
L’objecte base és l’objecte anomenat `Fruiteria`.
Els objectes inclosos a la fruiteria són: `Pomes`, `Taronges`, `Peres` i `Maduixes`.
S’estableix una relació entre aquestes classes del tipus tot-part, on les fruites són part de la fruiteria.
Això sí, si la fruiteria deixa d’existir, les fruites continuen existint.
#### Composició
Una __relació de composició__ és un cas especial d’associació entre dos o més objectes.
És una relació del tipus tot-part. És una relació molt semblant a la relació d’agregació,
amb la diferència que hi ha una dependència d’existència entre l’objecte base i l’objecte
(o els objectes) que hi està inclòs.
Si deixa d’existir l’objecte base, deixarà d’existir també el o els objectes inclosos.
El temps de vida de l’objecte inclòs depèn del temps de vida de l’objecte base.
La relació d’associació de composició es representa mitjançant una línia contínua
finalitzada en un dels extrems per un rombe pintat.
{.center}{height=300}
L’objecte base `Cotxe` es compon dels objectes inclosos `Volant`, `Roda`, `Fre` i `Deposit`.
Sense l’objecte `Cotxe` la resta d’objectes deixaran d’existir.
#### Dependència
Un altre tipus de relació entre classes és la __relació de dependència__.
Aquest tipus de relació es representa mitjançant una fletxa discontínua entre dos elements.
L’objecte del qual ix la fletxa es considera un objecte dependent.
L’objecte al qual arriba la fletxa es considera un objecte independent.
Es tracta d’una relació semàntica.
Si hi ha un canvi en l’objecte independent, l’objecte dependent es veurà afectat.
{.center}{height=100}
L’objecte `Grup` es depenent respecte de l'objecte `CicleFormatiu`.
Per exemple, el `Grup` __DAW1__ depén del `CicleFormatiu` __DAW__. Si hi ha canvis
en la denominació o els continguts del `CicleFormatiu` __DAW__, el `Grup` es veurà
afectat.
#### Herència, especializació o generalització
La __relació de generalització__ es dóna entre dues classes
on hi ha un vincle que es pot considerar d’herència.
Una classe és anomenada classe _mare_ o _superclasse_.
L’altra (o les altres) són les anomenades classes _filles_, _subclasses_ o _especialitzacions_,
que hereten els atributs, els mètodes i el comportament de la classe _mare_.
Aquest tipus de relació queda especificat mitjançant una fletxa que ix de la classe
filla i que acaba a la classe mare.
{.center}{height=300}
La classe `Animal` és la classe mare, i les classes `Gos` i `Gat` son especialitzacions.
Les subclasses contenen els mètodes i atributs de la classe `Animal`, però cadascuna
d'elles poden implementar nous mètodes o tindre nous atributs.
#### Classe associativa
Quan una associació té propietats o mètodes propis es representa com una classe unida
a la línia de l’associació per mitjà d’una línia discontínua.
Tant la línia com el rectangle de classe representen el mateix element conceptual: l’associació.
{.center}{height=300}
La classe `Estudiant` està relacionada amb la classe `Assigunatura`. Un estudiant pot
cursar diverses assignatures, i una assignatura pot ser cursada per molts estudiants.
En aquesta associació, cada un dels alumnes té una determinada nota per cada assignatura.
Podem modelitzar aquesta situació utilitzant una __classe associada__.
## Bibliografia i recursos
Aquest material és una obra derivada dels materials:
- Diagrames estàtics. Institut Obert de Catalunya. https://ioc.xtec.cat/materials/FP/Recursos/fp_dam_m05_/web/fp_dam_m05_htmlindex/WebContent/u3/a1/continguts.html
- https://stackoverflow.com/questions/28139621/shortcut-for-denoting-or-implying-getters-and-setters-in-uml-class-diagrams
- https://support.bizzdesign.com/display/knowledge/Setting+the+multiplicity+for+a+UML+attribute%2C+operation+or+association
- https://www.uml-diagrams.org/association.html
##### Recursos
- https://www.youtube.com/watch?v=UI6lqHOVHic