Anàlisi UML: Errors més freqüents

Aquest document conté un compendi de les errades més freqüents a l’hora d’utilitzar UML per a fer l’anàlisi d’un sistema d’informació Orientat a Objectes. S’ha considerat que la metodologia d’analisi utilitzada és la metodologia simplificada que es pot trobar a [EPOO].

Diagrama de casos d’ús

Concepte de cas d’ús

Dels apunts d’EP de la UOC: Un cas d’ús documenta una interacció entre el programari i un actor o més. La interacció en qüestió ha de ser en principi una funció autònoma dins el programari.

L’errada més freqüent en el diagrama de casos d’ús és, en aquest concepte. Un cas d’ús no és part d’una funcionalitat ni un pas d’un algorisme.

Un cas d’ús ha de ser tal que tingui sentit que un actor accedeixi al sistema, realitzi aquell cas d’ús i deixi de treballar al sistema; és a dir, per definició, ha de ser un possible cas d’ús del sistema per part de l’usuari. Si una funcionalitat no es pot aïllar d’aquesta manera, segurament no és un cas d’ús.

Un bon indicador que estem confonent el concepte de cas d’ús són diagrames de casos d’ús amb un nombre excessiu de casos d’ús.

Excepcionalment, podem modelar casos d’ús que agrupen un conjunt de funcionalitats d’aquest tipus. Podríem, per exemple, modelar un cas d’ús “Gestió de departaments” que representés l’alta, la baixa, la modificació, la consulta i el llistat de departaments. En tal cas, però, cal no barrejar graus de granularitat: O bé parlem del cas d’ús “Gestió de departaments” o bé parlem dels casos d’ús “Alta de departament”, “Llistat de departaments”, etc. però no de totes dues coses.

Relacions entre casos d’ús

include

El cas d’ús A està inclòs en el cas d’ús B (B inclou A) si A és un conjunt d’interaccions entre l’usuari i el sistema que forma part del cas d’ús B. En tal cas, el cas d’ús A no és necessàriament un cas d’ús complet segons la definició donada abans: Pot ser un fragment d’un altre cas d’ús.

En general, no té sentit que indiquem que un cas d’ús A està inclòs dins un cas d’ús B si el cas d’ús A no és inclòs, alhora, en altres casos d’ús, ja que si només està inclòs dins un únic cas d’ús i en forma part, no cal que el modelem com a cas d’ús.

Una relació d’inclusió s’indica amb una línia discontínua, amb punta de fletxa oberta que va del cas d’ús general al cas d’ús inclòs i que porta l’etiqueta <<include>>.

Un cas d’ús inclòs en algun altre hauria d’estar inclòs en dos o més casos d’ús. Molt excepcionalment, i mai com a regla general, podem indicar un cas d’ús només inclòs en un altre; i, en tal cas, ha de ser degut a una gran complexitat.

extends

Una extensió d’un cas d’ús és un conjunt d’interaccions entre l’actor i el sistema que es pot produir en algun moment del cas d’ús, normalment en una situació fora del flux principal d’esdeveniments.

Un cas d’ús A extén un cas d’ús B si A és una extensió del cas d’ús B que, a més, té sentit com a cas d’ús independent.

Una relació d’extensió s’indica amb una línia discontínua, amb punta de fletxa oberta que va del cas extensió al cas d’ús general (extès) i que porta l’etiqueta <<extend>>.

Un cas d’ús que n’extén un altre ha de tenir sentit com a cas d’ús independent. Per tant, ha de passar les validacions pròpies d’aquests.

General

Un bon indicador que estem sobre-utilitzant les relacions entre casos d’ús és la seva presència en excessiu nombre. No és habitual que la majoria de casos d’ús participin en una o més relacions, excepte escenaris de reutilització massiva de fragments de cas d’ús (per exemple, quan pràcticament tots els casos d’ús del sistema inclouen una sèrie de passos d’interacció per a que l’usuari s’autentiqui al sistema, conegut com a procés de login); en tal cas, la majoria de relacions seran d’inclusió cap al cas d’ús reutilitzat.

Actors

Dels apunts d’EP de la UOC: “La finalitat del programari és proporcionar informació a persones, màquines i dispositius o programaris de l’exterior, el conjunt de tots els quals anomenarem entitats exteriors; també hi ha entitats exteriors - les mateixes o d’altres - que demanen funcions al programari o bé li subministren informació per a tractar. Un actor és un conjunt de papers d’una entitat exterior en relació amb el sistema de programari considerat.”

Per tant, considerem actors els diferents papers (o conjunts de papers) que poden prendre les persones o sistemes externs que interactuïn amb el sistema que analitzem.

En un determinat cas d’ús, un actor en pot ser iniciador (el qui ha iniciat el cas d’ús activament) o pot ser-hi participant (sense haver iniciat el cas d’ús).

La relació entre un actor i un cas d’ús s’indica mitjançant una línia contínua sense etiquetes ni puntes de fletxa de cap mena.

Cada actor ha de participar, com a mínim en un cas d’ús.

Cada cas d’ús ha de tenir, com a mínim, un actor iniciador, tot i que pot tenir altres actors (iniciadors o no). Excepció: Els casos d’ús inclosos no tenen sentit per si mateixos i, per tant, no tindran actors iniciadors (tot i que en poden tenir de participants sense ser iniciadors).

Especificació textual de casos d’ús

Un diagrama de casos d’ús només és una forma gràfica de mostrar un índex dels casos d’ús i actors del nostre sistema i les relacions entre ells. Però en cap cas, els requisits funcionals d’un sistema queden prou documentats amb un diagrama de casos d’ús. Cal, per a cada cas d’ús, donar-ne l’especificació textual.

Existeixen diversos formats per a l’especificació textual de casos d’ús; alguns són més breus i d’altres més complets. Si no es diu el contrari es considerarà que es vol una especificació completa del cas d’ús.

Cal fer servir un format consensuat a l’organització on es treballi. N’hi ha un exemple al mòdul 3, apartat 1.2.1 dels materials d’EPOO de la UOC.

Nom

El nom d’un cas d’ús que especifiquem textualment ha de coincidir necessàriament amb algun dels casos d’ús indicats al diagrama de casos d’ús!!

Flux d’esdeveniments principal

Un cas d’ús ha de tenir clarament associat un objectiu que l’actor principal del cas d’ús vol assolir, com per exemple, donar d’alta un nou empleat o llistar els empleats d’un departament. Per a cada cas d’ús, triarem un flux d’esdeveniments principal que és aquell a través del qual l’usuari obté el seu objectiu de la forma més directa o habitual.

En el flux d’esdeveniments principal cal indicar la sèrie de passos que formen la interacció entre el sistema i els actors implicats. Cada pas ha de ser una acció simple que fa UN actor o el sistema i ha d’anar numerat per a poder-hi fer referència més endavant.

En el cas que el cas d’ús n’inclogui un altre, tot el cas d’ús inclòs es considerarà un únic pas i no s’indicarà els diferents passos que el formen, ja que per això s’ha utilitzat la relació d’inclusió: Per a no haver de documentar cada cop els diversos passos que formen el cas d’ús inclòs.

Ha d’estar format per una sèrie de passos numerats

Cada pas hauria de ser quelcom que fa el sistema o quelcom que fa un actor

El flux d’esdeveniments principal hauria de documentar un diàleg entre diverses parts i, per tant, el més normal és que tingui forma d’una sèrie de passos que alternen peticions dels actors amb respostes del sistema.

Cada pas del sistema ha de deixar clar quines dades mostra el sistema com a resultat; normalment n’hi ha prou amb indicar clarament la pantalla mostrada.

Cada pas d’un actor ha de deixar clar quines dades proporciona al sistema; normalment n’hi ha prou indicant clarament la pantalla on s’introdueixen i quines dades d’aquesta s’introdueixen (típicament totes)

Flux d’esdeveniments alternatius

El flux d’esdeveniments principal ha de ser un escenari d’ús del cas d’ús a través del qual tot funciona correctament i que es consideri l’escenari més habitual. Qualsevol flux alternatiu (errades de l’actor, opcions que no siguin la principal, etc.) s’ha de documentar en un flux d’esdeveniments alternatiu.

Cada flux d’esdeveniments alternatiu ha d’indicar en quin pas de l’escenari principal es produeix i sota quina condició. Aleshores ha d’incloure els passos numerats que es segueixen (amb les mateixes regles que el flux d’esdeveniments principal).

Moltes vegades, un flux d’esdeveniments alternatiu finalitza retornant a algun pas del flux d’esdeveniments principal.

Cada flux d’esdeveniments alternatiu ha d’indicar en quin punt es produeix (un número), s’ha d’identificar dins aquest punt (típicament amb una lletra) i ha de descriure quan es produeix (una frase explicant l’alternativa triada o l’error comès).

Model conceptual de dades

El Model Conceptual de Dades modela les dades que el sistema gestiona classificant-les en classes, que tenen atributs i associacions entre elles. Algunes classes, a més, poden mantenir una relació d’especialització/generalització que té un tractament especial.

Classes

Cada classe ha de tenir un nom que sigui descriptiu del que representa i, normalment, n’han de poder existir diverses instàncies al sistema. Cada instància tindrà certs valors als atributs de la classe i certes altres instàncies associades a través de les associacions.

Els noms de classe han de ser únics

Una classe de la qual no en puguem imaginar més d’una instància al sistema sol ser una classe innecessària.

En el cas excepcional que d’una classe només en pugui existir una instància, cal marcar la classe com a singleton fent servir l’indicador de cardinalitat de classe propi d’UML.

Una classe que no tingui atributs és molt poc habitual i, gairebé sempre, indicadora d’alguna errada de modelat. Les instàncies d’una classe així només es podrien distingir les unes de les altres per les instàncies que tinguin associades.

Una classe sense atributs ni associacions és un error, ja que les seves instàncies no es podrien distingir les unes de les altres i no tindrien cap informació útil.

Les classes d’un model conceptual de dades no han de tenir operacions.

Atributs

Els atributs indiquen el tipus d’informació que coneixem de cada instància d’una classe. Cada atribut ha de tenir un nom identificatiu i autoexplicatiu i un tipus, que ha de ser un “tipus primitiu”.

Un atribut no pot ser del tipus d’una classe del model conceptual de dades. En tal cas, cal substituir-lo per una associació.

Un atribut no pot ser de tipus llista, col·lecció, array, etc. En tal cas cal fer servir atributs multiavaluats.

Els atributs multiavaluats no són freqüents i, molts cops, indiquen que estem modelant incorrectament una associació com a atribut.

Si no s’indica el contrari, un atribut és obligatori. Per a indicar que un atribut és opcional (pot no prendre valor per a algunes instàncies del sistema), cal indicar-ne la cardinalitat [0..1].

Un atribut no pot funcionar com una clau forana del model relacional: Un atribut no pot contenir un valor que identifiqui una altra instància d’alguna classe del model conceptual; en tal cas, cal substituir-lo per una associació.

Suposem que tenim una classe Departament i una classe Empleat amb un atribut dni que n’identifica les instàncies. Per indicar que de cada departament en sabem el cap, que és un empleat, cal fer servir una associació entre les dues classes, mai un atribut dniCap a la classe Departament.

Associacions

Cada associació associa dues (en alguns casos més) classes.

A cada extrem d’una associació cal indicar-hi la cardinalitat.

Les associacions ternàries, quaternàries, etc. (N-àries on N>2) són poc habituals i és possible fer models correctes sense utilitzar-les. En cas de dubte o si no se’n coneix molt bé el funcionament, és millor no fer-les servir.

Quan una associació indica una certa relació de tot-part, es considera que és una agregació (i es dibuixa un rombe a l’extrem del tot). Si aquesta relació és especialment forta (i segueix certes restriccions semàntiques) aleshores l’agregació és una composició (i el rombe es dibuixa ple).

No és habitual que la majoria d’associacions siguin agregacions o composicions. La majoria haurien de ser associacions simples.

Si no es coneix molt bé la diferència que hi ha entre una composició i una agregació, és millor no fer servir composicions.

En una agregació, la cardinalitat a la part del tot sol ser 1 o 0..1.

En una composició, la cardinalitat a la part del tot sempre ha de ser 1.

Generalització / Especialització

Quan modelem una classe A1 com una especialització d’una classe A, indiquem que tota instància d’A1 és, també de tipus A. Per tant, tot allò que sigui cert sobre les instàncies d’A, ho serà també per a les instàncies d’A1, però no a l’inrevés. En particular, tota instància de la classe A1 tindrà les mateixes associacions i atributs que les instàncies de la classe A, però tindrà associacions i atributs propis.

Un atribut d’una classe (A1) no pot tenir el mateix nom que un atribut de la seva superclasse (A)

Restriccions d’integritat

En tot sistema hi ha certes restriccions d’integritat que s’han de complir en tot moment (no entrem en la definició formal de què vol dir en tot moment). Algunes restriccions d’integritat es poden representar amb UML, però d’altres s’han de representar com a notes del diagrama (entre { i }) o com a restriccions textuals al peu del diagrama.

Si no pot haver-hi, en cap moment, dues persones amb el mateix dni, direm que aquesta és una restricció d’integritat.

Un cas especial de restricció és la de clau. Quan una classe té un atribut o conjunt d’atributs que identifica les instàncies d’aquella classe (i que, per tant, no puguin prendre valors repetits), direm que aquest atribut o conjunt d’atributs formen la clau externa d’aquella classe.

Seguint l’exemple anterior, direm que dni és clau externa de la classe Persona.

Normalment la majoria de classes del sistema haurien de tenir una clau externa. És convenient indicar-la explícitament.

Disseny extern del sistema

El disseny extern del sistema consisteix a dissenyar l’aspecte que ofereix el sistema als seus usuaris. En una primera fase, es sol dissenyar només els aspectes més rellevants d’aquest disseny extern sense entrar en detalls.

És important dissenyar quins tipus d’entrades i sortides permet fer el nostre disseny extern i quins fluxos de navegació entre pantalles permet, però podem deixar per a més endavant qüestions com el color de les pantalles o el tipus de lletra qui hi farem servir.

Per a fer un disseny extern del sistema n’analitzarem l’aspecte estàtic (fent esboços de les pantalles que formen la interfície gràfica d’usuari) i de l’aspecte dinàmic (indicant en un diagrama d’estats els fluxos navegacionals entre pantalles del sistema).

Disseny extern: Aspecte dinàmic (diagrama de la interfície gràfica)

Un diagrama d’estats de la interfície gràfica ha de mostrar, per a un cas d’ús (o més d’un), els diversos estats pels quals passa la interfície mostrada a l’usuari. Cada estat es correspondrà (informalment) amb una pantalla i permetrà diverses transicions cap a altres estats.

Tot estat ha de tenir un nom identificatiu i autoexplicatiu

Cada transició és originada per un esdeveniment (normalment ocasionat per l’usuari) i pot tenir una condició (indicada entre [ i ]). L’esdeveniment d’una transició ha de tenir un nom identificatiu i autoexplicatiu i pot tenir paràmetres.

Tota transició ha de tenir associat un esdeveniment.

Un esdeveniment s’ha de correspondre amb un esdeveniment d’alt nivell. No cal tenir en compte, doncs, esdeveniments que no afecten l’estat del sistema com ara omplir un camp de text, minimitzar, fer servir l’scroll…

Si, en un formulari d’alta d’empleat, un usuari indica un nom en un camp, un dni en un altre, una data de naixement en un tercer i, a continuació, prem el botó ok, podem considerar que altaUsuari(nom,dni,dataNaixement) és un bon nom d’esdeveniment amb els seus paràmetres. En canvi, omplirNom, omplirDni, premerOk, etc, són noms d’esdevniment a massa baix nivell d’abstracció.

Des d’un mateix estat, no en poden sortir dues transicions amb el mateix esdeveniment, a menys que tinguin una condició excloent, és a dir, que les distingeixi.

Si entre dos estats hem modelat una transició (incorrecta) sense esdeveniment, probablement l’estat origen de la transició no és un estat, ja que el sistema no s’hi està fins que es produeixi un esdeveniment.

Un diagrama d’interfície gràfica té com a únic objectiu mostrar els estats (pantalles) pels que navega l’usuari. No cal que hi aparegui informació sobre altres tasques realitzades pel sistema, que molts cops es modelen incorrectament com a estats amb transicions sense esdeveniments.

El diagrama ha de tenir un únic estat incial que és la primera pantalla que l’usuari veu (del cas d’ús o del conjunt de casos d’ús).

Aquell estat (pantalla) en el qual es doni per finalitzat el cas d’ús modelat (a partir del qual ja no s’admetin transicions), ha de ser marcat com a estat final.

Tot diagrama ha de tenir, com a mínim, un estat final.

Normalment no és necessari fer servir altres característiques avançades dels diagrames d’estat UML. En particular, si es modela un diagrama per cas d’ús no és necessari fer servir subestats, estats històrics, estats paral·leles, etc. Si ens trobem amb lògiques complexes, val la pena fer un diagrama simple i anotar-lo per a complementar-lo amb un comentari UML o al peu del diagrama.

Tota transició que, en fer-se, reculli dades introduïdes per l’usuari, ha de tenir paràmetres que representin aquelles dades. Només el fet de prémer un botó, una opció de menú o esdeveniments així de senzills corresponen a transicions sense paràmetres.

Disseny extern: Aspecte estàtic (esboç de les pantalles)

Per a cada possible estat de la interfície d’usuari (pantalla) el diagrama de l’aspecte dinàmic del disseny extern ens mostra les possibles transicions que es poden produir, però no els tipus d’elements d’interfície gràfica que es faran servir i com s’organitzaran. Per a cada estat, doncs, cal fer un esboç on es mostri quins elements es faran servir.

Cada esboç s’ha de correspondre amb un estat del diagrama d’estats i cal identificar-lo clarament.

Normalment cada pantalla tindrà un títol visible al seu disseny extern que hauria de coincidir amb el nom de l’estat del diagrama d’estats.

A cada esboç de pantalla cal identificar la forma de fer cada una de les transicions del diagrama d’estats (no menys).

Si el diagrama d’estats indica que hi ha una transició altaEmpleat(nom, dni, dataNaixement), l’esboç de la pantalla ha d’incloure elements que ens permetin introduir un nom, un dni, una data de naixement i, finalment, confirmar l’entrada (per exemple, amb un botó amb l’etiqueta “D’acord”).

En un esboç de pantalla només han de ser possibles les transicions definides al diagrama d’estats (no més).

Si, des d’un determinat estat, no hi ha cap transició cancel·lar, no hauria d’haver-hi cap botó etiquetat “Cancel·lar” (que no es correspongui a alguna altra transició vàlida des d’aquell estat).

Quan no sigui obvi, cal indicar en un comentari al peu de cada esboç, la correspondència entre els elements d’IGU dibuixats i els esdeveniments identificats al diagrama d’estats.

Si es fa servir dos components de llistes i volem que, en arrossegar un element d’una llista a una altra es produeixi un des esdeveniments identificats al diagrama, aquest comportament no serà obvi a l’esbós de la pantalla. En tal cas, cal afegir un comentari explicant-lo.


Símbols utilitzats:

Validació: Característica que sempre cal comprovar

Indicador: Característica que sol ser indicadora d’algun problema, però que no és precisa com una validació.

Exemple: Exemple concret d’algun dels aspectes mencionats

Referències:

  • [EPOO]: Jordi Fernández Gonzalez, Jordi Pradel i Miquel i Jose Antonio Raya Martos, Enginyeria del programari orientat a l’objecte. UOC, 2005
blog comments powered by Disqus