# Diagrama de classes

En el món de l'enginyeria de programari un diagrama de classes en UML (Unified Modeling Lenguage) és un tipus de diagrama estàtic que descriu l'estructura d'un sistema mostrant les seves classes, atributs i les relacions entre ells. Els diagrames de classes són utilitzats durant el procés d'anàlisi i disseny dels sistemes, a on es crea el disseny conceptual de la informació que utilitzarà el sistema, i els components que s'encarregaran del seu funcionament i de la relació entre l'un i l'altre.

## Introducció

El diagrama de classes és el bloc principal del modelatge orientat a objectes. Es fa servir tant per la traducció de models detallats a codi de programació com pel modelat conceptual general de la sistemàtica de l'aplicació. També es poden usar en el modelatge de dades. Les classes i les interaccions entre elles són els objectes més importants que s'han de representar en un diagrama de classes.
Al diagrama, les diferents classes es representen amb una caixa dividida en tres parts:
* A dalt en negreta i centrat hi tenim el nom de la classe.
* La part del mig conté els atributs de la classe. Es representa de manera que primer posem el nom de la variable seguit del seu tipus, (p. ex.: nom : String).
* A la part baixa hi tenim els mètodes o operacions (públics, protegits o privats) que la classe pot implementar o usar.
En el disseny d'un sistema, el nombre de classes s'identifica i s'agrupa en un diagrama de classes que ajuda a determinar les relacions estàtiques que hi ha entre els objectes. Les classes sovint són separades amb subclasses per fer un disseny conceptual més detallat.
Amb l'objectiu de descriure més detalladament el comportament dels sistemes, aquests diagrames de classes es poden complementar amb un diagrama d'estats o una màquina d'estats d'UML.

## Parts

UML proporciona mecanismes per representar les parts d'una classe, tals com els atributs i els mètodes i informació addicional sobre aquests.

### Visibilitat

Per especificar les visibilitat de la part d'una classe (per exemple qualsevol atribut o mètode) aquestes són les anotacions que s'han de posar just abans del nom:
| + | Pública |
| - | Privada |
| # | Protegida |
| / | Derivada (es pot combinar amb una de les altres) |
| ~ | Paquet |
* La visibilitat pública permet que qualsevol objecte d'aquesta classe pugui accedir al mètode o atribut.
* La visibilitat privada limita l'accés al mètode o l'atribut de manera que només hi pugui accedir l'objecte de la mateixa classe.
* La visibilitat protegida permet que només accedeixi a l'atribut o mètode l'objecte de la mateixa classe i algun objecte d'una classe que hereti a partir d'aquesta.
* Les classes es poden organitzar en paquets. Això s'acostuma a utilitzar quan tenim un conjunt de classes relacionades entre elles. Totes les classes no incloses explícitament en cap paquet i que estan situades en un mateix directori es consideren d'un mateix paquet.

### Camps

L'UML proporciona dos tipus de camps per les nostres parts: instància i classificador.
* Les parts classificadores són conegudes comunament com a estàtiques en diversos llenguatges de programació. El camp és la classe en si mateixa.
** Els valors dels atributs són iguals per a totes les instàncies
** La crida del mètode no afecta l'estat de la instància.
* Les parts instància són camps per a instàncies específiques.
** El valors dels atributs pot variar entre instàncies.
** La crida del mètode pot afectar l'estat de la instància.
Per indicar un camp classificador per una part subratllem el nom. En canvi, les parts instància, s'assumeixen per defecte.

## Relacions

Les relacions són el terme general que cobreix els diferents tipus de connexions lògiques entre els objectes del diagrama. En UML podem veure les següents relacions:

## Enllaços externs

Els enllaços són les relacions bàsiques entre dos objectes. En UML es representen amb línes rectes entre els objectes.

### Associació

El diagrama de classes és un exemple d'associació entre dues classes. Una associació presenta un grup d'enllaços. Les associacions binàries solen ser representades com una línia. Una associació pot tenir qualsevol nombre d'enllaços cap a una classe. Si hi ha 3 enllaços llavors la podem denominar associació ternària. Una associació pot ser anomenada: als seus extrems es poden etiquetar amb els noms en funció del seu rol, indicadors de propietat, multiplicitat, visibilitat i altres propietats.
Hi ha quatre tipus diferents d'associacions:
* Bidireccional
* Unidireccional
* Agregació (incloent-hi composició d'agregacions)
* Reflexives
Les dues primeres són les més comunes. Per exemple: una classe vol es relacionaria amb la classe avió bidireccionalment. L'associació representa la relació estàtica entre els objectes de les classes. Per exemple: "El departament ofereix cursos", és una relació d'associació.

### Agregació

El diagrama de classes mostra l'agregació entre dues classes. L'agregació és una variant dels objectes que tenen una relació d'associació; l'agregació és més específica que l'associació. És una associació que representa una part de la relació o la seva totalitat. Com a tipus d'associació, l'agregació pot ser anomenada i tenir les mateixes etiquetes que l'associació. Tot i això, l'agregació no pot incloure més de dues classes, per tant ha de ser una associació binaria.
L'agregació pot tenir lloc quan la classe és una col·lecció o un contenidor d'altres classes, però quan una classe continguda no té un cicle de vida fortament lligat amb la classe contenidora, si el contenidor és destruït el seu contingut no. A l'UML es representa gràficament com un rombe buit al costat de la classe contenidora en la línia que uneix les dues classes (contenidora i continguda). L'agregat és semànticament un objecte estès que es tracta com una unitat en moltes operacions, encara que físicament està fet de diversos objectes menors.

### Composició

La composició és una relació més forta que la relació d'associació i també és més específica que l'associació. La composició normalment té una dependència més forta del ‘’cicle de vida’’ entre les instàncies de la classe contenidor i de les instàncies de les classes contingudes: Si el contenidor es destrueix, totes les instàncies que estaven contingudes en el contenidor també es destrueixen. Cal veure que, quan es pugui, una part es pot eliminar del contenidor abans que el contenidor s'elimini i llavors no seria eliminada com a part del contenidor. La representació gràfica en UML de la composició és un rombe opac al costat de la classe contenidora en la línia que uneix la classe contenidora i la continguda.

### Diferències entre composició i agregació

Quan intentem representar relacions senceres reals; per exemple: un engranatge és una part d'un cotxe, llavors una relació de composició és més apropiada. En canvi, quan es representa un software o una relació en una base de dades; per exemple: L'engranatge amb el model ‘’ENG01’’ és una part del cotxe amb el model CM01, el millor és utilitzar una relació d'agregació, ja que l'engranatge ENG01 també podria ser part d'un altre cotxe a part del cotxe amb model ‘’CM01’’. És per això que sovint la relació d'agregació s'anomena contenidor “catàleg” per diferenciar-la dels contenidors “físics” de les composicions.

## Definicions

* Propietats també anomenades atributs o característiques, són valors que corresponen a un objecte. És la informació que ens detallada com és l'objecte. Per exemple, si tractem un objecte cotxe, podem tenir com atributs la marca, el model, el color, els quilòmetres, etc.
* Operacions habitualment anomenades mètodes, són aquelles activitats que es poden realitzar amb o a sobre aquest objecte de manera que realitzi alguna acció o es modifiqui algun dels seus atributs. De la mateixa manera que el nom d'un atribut, el nom d'una operació s'escriu amb minúscules si consta d'una sola paraula. Si el nom conté més d'una paraula, cada paraula serà unida a l'anterior i començarà amb una lletra majúscula, a excepció de la primera paraula que començarà en minúscula. Per exemple: afegirKm, canviarMotor.
* Interfície és un tipus abstracte que només declara les operacions que ha d'implementar la classe. Aquest tipus de classe només contindrà la signatura d'aquests mètodes i no podrà tenir cap implementació. Defineix els requeriments mínims de l'objecte. Fa referència a polimorfisme.
* Herència es defineix com la reutilització d'un objecte pare ja definit per poder estendre la funcionalitat en un objecte fill. Els objectes fills hereten totes les operacions i/o propietats d'un objecte pare. Per exemple: Una persona pot especialitzar-se en Proveïdors, Creditors, Clients, Accionistes, Empleats; tots comparteixen dades bàsiques com una persona, però a més cadascun tindrà informació addicional que depèn del tipus de persona, com a saldo del client, total d'inversió de l'accionista, salari de l'empleat, etc.
En dissenyar una classe s'ha de pensar en com es pot identificar un objecte real, com una persona, un transport, un document o un paquet. Aquests exemples de classes d'objectes reals, és sobre el que un sistema es dissenya. Durant el procés del disseny de les classes es prenen les propietats que identifiquen com a únic a l'objecte i altres propietats addicionals com a dades que corresponen a l'objecte. Amb els següents exemples es defineixen tres objectes que s'inclouen en un diagrama de classes:
Exemple 1: Una persona té nombre de document d'identificació, noms, cognoms, data de naixement, gènere, adreça postal, possiblement també tingui número de telèfon de casa, del mòbil, FAX i correu electrònic.
Exemple 2: Un sistema informàtic pot permetre administrar el compte bancari d'una persona, per la qual cosa tindrà un número de compte, nombre d'identificació del propietari del compte, saldo actual, moneda en la qual es maneja el compte.
Exemple 3: Un altre objecte pot ser "Maneig de Compte", on les operacions bancàries d'un compte (com en l'exemple 2) es manejaran realitzant diferents operacions que en el diagrama de classes només es representen com a operacions, que poden ser:
* Obrir
* Tancar
* Dipòsit
* Retirar
* Acreditar Interessos
Aquests exemples constitueixen diferents classes d'objectes que tenen propietats i/o operacions que contenen un context i un domini, els primers dos exemples són classes de dades i el tercer classe de lògica de negoci, depenent de qui dissenyi el sistema es poden unir les dades amb les operacions.
El diagrama de classes inclou molta més informació com la relació entre un objecte i un altre, l'herència de propietats d'un altre objecte, conjunts d'operacions/propietats que són implementades per a una interfície.

## Tipus especials de classes
### Classe abstracta

Una classe abstracta és una classe de la qual no se'n poden instanciar directament objectes. Per tant, els objectes lligats a una classe abstracta s'han de crear necessàriament en alguna de les seves subclasses (especialització / generalització).
REPRESENTACIÓ UML: una classe abstracta s'acostuma a posar en itàliques (cursiva).

### Classe associació

Una classe associació és una associació que té el mateix comportament que una classe. L'associació i la classe associació representen un sol element del model i, per tant, els noms de l'associació i de la classe associació han de coincidir.
REPRESENTACIÓ UML: Es representa amb un rectangle de classe que s'uneix per mitjà d'una línia puntejada a la línia que representa l'associació
Algunes eines CASE (i tampoc Java) no permet treballar amb classes associació, per poder-hi treballar cal descompondre les classes associacions en dues associacions i una classe.

### Classe interfície

Una interfície, aproximadament com una classe abstracte, és una classe que dona nom a una llista d'operacions abstractes, sense indicar-ne la implementació. Només defineix la signatura completa de les seves operacions (nom, tipus de paràmetre i tipus de retorn), però no té atributs ni implementa les operacions. És a dir, una interfície no pot ser instanciada.
D'aquesta forma, l'especificació d'una funcionalitat queda separada de la seva implementació.
REPRESENTACIÓ UML: la classe interfície porta l'estereotip «interface» sobre el nom d'aquesta.

#### Interfícies i Associacions

Es pot establir una associació entre una classe C i una interfície I, sempre que la navegabilitat sigui de C cap a I. Tot i que la interfície I no pot ser instanciada, cal interpretar aquesta associació en sentit que un objecte de la classe C té referències a objectes de classes que implementen la interfície I i, per tant, pot rebre missatges de C.

## Relacions
### Relacions a Nivell de Classe
#### Generalització/Especialització

És una relació d'herència entre dos classes, una de les quals és superclasse de l'altra (subclasse).
La subclasse és considerada una forma "d'especialització", subtipus, de la superclasse i la superclasse una "generalització", supertipus, de la subclasse.
A la pràctica, això significa que qualsevol instància de la subclasse és també una instància de la superclasse. La superclasse també és coneguda com: classe "pare", classe base o tipus base; i la subclasse com: classe "filla", classe derivada, tipus derivat o tipus heretat.
Una interfície pot ser una especialització d'una interfície de més alt nivell.
REPRESENTACIÓ UML: una generalització/especialització es representa per un segment amb un extrem triangular apuntant cap a la superclasse.

#### Realització

La implementació d'una interfície per una classe concreta s'anomena realització. Dit de forma general, una realització és una relació entre dos elements del model UML, en què un d'aquests elements implementa el comportament que l'altre especifica.
Una classe pot implementar diverses interfícies i una interfície pot ser implementada per més d'una classe.
REPRESENTACIÓ UML: una realització es simbolitza per una línia a trossos amb una fletxa, triangle buit, que apunta des de la classe implementadora a la classe interfície.

### Relacions Generals
#### Dependència

Una dependència entre dues classes és una relació entre aquestes, de manera que un canvi a un objecte de la classe proveïdora B pot forçar canvis a un objecte de la classe client A.
Una classe A depèn d'una altra classe B si:
* Un objecte de la classe B es fa servir de paràmetre a una operació de la classe A (visibilitat de paràmetre).
* Una operació de la classe A retorna un objecte de la classe B (visibilitat de paràmetre).
* Una operació de la classe A crea un objecte de la classe B i el fa servir dins d'un mètode, però sense mantenir-ne cap referència (visibilitat local).
* Una operació de la classe A fa servir un mètode estàtic de la classe B (visibilitat global).
REPRESENTACIÓ UML: una dependència d'una classe A respecte de B s'indica amb una fletxa puntejada que va de A fins a B.

### Multiplicitat

La multiplicitat, situada a un extrem d'una associació, indica el nombre de possibles instàncies de la classe d'aquest extrem que es poden associar amb una instància de la classe de l'altre extrem.
REPRESENTACIÓ UML: una associació es representa amb una línia amb una punta de fletxa opcional que indica el paper de l'objecte en la relació, i una notació opcional a cada extrem que indica la multiplicitat de les instàncies de l'entitat, és a dir, el nombre d'objectes que participen en l'associació.

### Restriccions

Una restricció és una condició que tota implementació del disseny ha de satisfer. La restricció limita els valors que les entitats (objectes, classes, atributs, associacions...) poden prendre.
REPRESENTACIÓ UML: En un diagrama de classes les restriccions s'escriuen entre { } i es col·loquen vora l'entitat restringida.

### Estereotips

Un estereotip permet afegir informació extra als elements del model (classes, dependències, color/tipus de rol…).
REPRESENTACIÓ UML: El nom d'un estereotip s'escriu entre << ... >> sobre del nom de l'element.

### Associacions qualificades

Un qualificador és un atribut d'una associació binària que serveix per a determinar unívocament un objecte o conjunt d'objectes d'una de les classes, la classe objectiu, que estan relacionats a través de l'associació.
Les associacions qualificades es fan servir com a identificadors i la seva multiplicitat acostuma a ser: 0..1, 1 i *. (El qualificador es fa servir com a clau de la Map).
REPRESENTACIÓ UML: Es representa per un rectangle que s'adjunta a l'extrem de l'associació situat al costat de la classe font, que és la classe oposada a la classe objectiu.

## Paquets

Un paquet és una col·lecció d'elements del model (classes, altres paquets, casos d'ús…) relacionats lògicament. Permeten organitzar diagrames complexos, agrupant diversos elements. Es representen per rectangles amb petites pestanyes a la part superior. El nom del paquet es posa dins del rectangle o de la pestanya.

### Dependències entre paquets

Un paquet depèn d'un segon paquet, si els canvis fets al segon paquet poden forçar canvis en el primer. Naturalment, la dependència entre classes de diferents paquets implica la dependència entre els corresponents paquets. Els paquets continguts en altres paquets veuen tot allò que el paquet contenidor importa.
REPRESENTACIÓ UML: les dependències entre paquets s'indiquen amb fletxes puntejades.

## Referències

* ↑ Sparks, Geoffrey. «Database Modelling in UML». [Consulta: 8 setembre 2011].
* ↑ Scott W. Ambler (2009) UML 2 Class Diagrams. Webdoc 2003-2009. Accessed Dec 2, 2009
* ↑ «UML Reference Card, Version 2.1.2», 01-08-2007. [Consulta: 12 març 2011].
* ↑ OMG Unified Modeling Language (OMG UML) Superstructure, Version 2.3: May 2010. Retrieved 23 September 2010.
* ↑ «Modelo de Clases» (en castellà). [Consulta: 13 octubre 2014].
* ↑ Fowler, Martin. UML gota a gota (en castellà), p. 104.
* ↑ «Diagrames Estàtics». Arxivat de l'original el 2018-09-10. [Consulta: 13 octubre 2014].
* ↑ «Programación en UML».
* ↑ «Diagrama de clases».
* ↑ Fowler, Martin. UML gota a gota (en castellà), p. 103.
* ↑ «UML Paquetes» (en castellà). [Consulta: 13 octubre 2014].

## Enllaços externs

* Elements UML