LinuxPedia

Wiki libre et indépendant dédié à GNU-Linux et BSD.

Outils pour utilisateurs

Outils du site


expert:uml

Introduction à UML

Notes
  • Bien que l'utilisation de UML s'étende à bien des domaines, le présent article est dédié au développement. Si vous n'avez pas beaucoup de bases en programmation, vous risquez de trouvez certaines explications absconses.
  • Je donne les exemple de code ici en python, pour la lisibilité extrème de ce langage. Certaines notion gagneraient certainement à être expliquées à l'aide d'autres langage alors n'hésitez pas à contribuer.
  • Les schémas sont faits avec Dia

Explication des termes

UML

Unified Modeling Language: langage de modélisation unifié

  • Langage: C'est un langage visuel à base de pictogrammes mais aussi un langage textuel en XML
  • Modélisation: Modéliser les données est une phase essentielle du processus de developpement
  • Unifié: UML est un standard ouvert défini par le Object Management Groupe (OGM) qui est une association à but non lucratif dont l'objectif est de promouvoir le modèle objet

UML est donc orienté objet. Il va aider à définir le schémas de persistence des données à partir des classes de l'application. Mais aussi à schématiser les différents aspects du logiciel: son utilisation, son imbrication dans le système, les différentes phases d'activité, etc.

La programmation orienté objet

Il existe plusieurs paradigmes de programmation. Les plus courants à l'heure actuelle sont la programmation procédurale et la programmation objet. En objet, on utilise le procédural sous forme de fonctions ou méthodes. Les méthodes font partie des objets. Les objets sont construits à partir des classes.

Une classe est une sorte de modèle sur lequel on peut se baser pour construire les objets. Par exemple, prenons un tableau noir. En objet, je vais définir ce qu'est un tableau noir, ce qui le caractérise, sa taille, etc et comment on l'utilise. Ce sera une classe.

À partir de cette classe, je vais pouvoir créer autant de tableaux noirs que je veux, ce sont des objets.

Le SGBD, le SGBDR

Le Système de Gestion de la Base de Données est un ensemble de programmes qui gère les accès à une base de donnée. Dans le processus de développement moderne, la base de donnée est essentielle. Le données ne sont pas gardées dans le programme lui-même mais confiées au SGDB.

Il y a plusieurs types de SGDB, le plus fréquent est le relationnel, SGBDR. La base de donnée va se composer de tables (un peu à la manière de tableaux à deux dimensions), chaque table se compose de champs et d'entrées (comme un tableau).

En programmation objet, on fait correspondre à chaque classe une table. Les attributs composeront les champs de la table tandis que les objets en seront les entréées.

Les tables peuvent inclure des méthodes dans un langage spécifique au SGBDR.

Enfin, les tables incluent les relations avec les autres tables (héritage, primary key, foreign key, etc).

Les types de diagrammes UML

  • diagramme de classes
  • diagramme de cas d'utilisation
  • diagramme de composants
  • diagrammes de séquences
  • diagrammes de collaboration
  • diagrammes d'état
  • diagrammes d'activités

Méthodologie en UML

UML n'impose pas de méthologie stricte. On peut prendre un problème par n'importe quel bout, selon les besoins. Généralement, on va commencer par les diagrammes de classes et les cas d'utilisation puis afiner au besoin à l'aide des autres types de diagrammes mais ce n'est pas toujours le cas.

Pour décrire un processus industriel de type chaîne de montage, par exemple, on partira plus facilement d'un diagramme d'état ou d'activité. Pour décrire un système de gestion des utilisateurs, on choisira plutôt un diagramme de collaboration. Pour décrire l'imbrication d'un logiciel dans un ensemble de logiciels tiers (un système d'exploitation, par exemple), on prendra un diagramme de composants.

Sans compter que vous pouvez vous servir de UML pour tout autre chose que pour le développement…

Pour la programmation orientée objet, c'est le diagramme de classe qui va être l'élement central, celui qu'on va soigner le plus et auquel on va accorder un maximum de rigeur.

Les outils pour faire de l'UML

Une feuille de papier ou un tableau blanc sont préférés par certains à un logiciel. Essayez pour voire si ça vous convient!

Du côté des logiciels:

  • Dia: dans la philosophie unix, ne fait que des diagrammes mais le fait bien
  • Gaphor: écrit en python, même philosophie
  • argoUML: écrit en java, complet mais un peu lourd à l'utilisation
  • Umbrello: logiciel kde, très complet et visuel mais sensiblement plus lourd et présence de bugs
  • UMLet: écrit en java, orienté texte

Les diagrammes de classe

Notez que l'on peut aussi créer des diagrammes d'objet afin d'établir le comportement des objets dans des situations particulières. Il peut être intelligent de faire un diagramme d'objet pour chaque use case.

Classes

La classe est l'element principal des diagrammes de classe (ça vous étonne?). Elles sont représentées par un rectangle séparé en trois parties: le nom de la classe, les attributs et les opérations.

Exemple:

class individu():
    nom = "default"
    
    def get_nom(self):
        return self.nom
        
    def set_nom(self, new):
        self.nom = new

Attributs

Les différentes variables afférant à la calsse. Selon le langage, les variables peuvent être privées, protégées ou publiques. Dans l'exemple, “nom”.

Clef primaire, clef étrangère

Les clefs primaires et étrangères sont essentielles à l'intégrité de la base de données.

Chaque instance se doit d'avoir (attention, pléonasme:) une clef primaire unique (aucune autre instance de n'importe quelle classe ne peut avoir la même). Il peut donc être judicieux de les ajouter dès l'étape de modèlisation. Toutefois, si vous utilisez un framework, cela est facultatif puisque le framework le fera de lui-même automatiquement.

Chaque fois que deux classes sont liées, une clef étrangère dans l'une ou les deux classes doit renvoyer à la classe liée. Là encore, il peut être judicieux de le spécifier dans le diagramme.

Opérations

Les fonctions (ou méthodes) de la classe. En dehors des constructeurs, des destructeurs et des autres méthodes particulières à la classe en question, il convient d'ajouter des fonctions qui permettent de lire ou de modifier les attributs de l'objet.

Conventionnellement, on les appelle “get*” et “set*”.

Dans la plupart des langages, les classes ont des attributs et des méthodes dits privés, protégés ou public. Un attribut ou une méthode privée n'est visible que par la classe elle-même. Il faut donc créer des méthodes dont le but est de lire ou modifier celles-ci.

À noter que même si certains langages permettent d'accéder directement aux attributs (en python par exemple, il n'y a pas de private, restricted, public), il est toujours conseillé de n'y accéder qu'au travers de fonctions dédiées. La raison en est simple: il est souvent (toujours?) nécéssaire d'effectuer quelques opérations supplémentaires lorsqu'on modifie un attribut. D'autres objets peuvent s'en servir, il faut bien leur signaler qu'il a changé depuis la dernière fois qu'ils sont venus le voire.

Packages

Les packages permettent de mettre de l'ordre dans son programme quand il commence à devenir trop imposant.

Relations, contraintes

Les principales relations entre les classes sont l'agrégation et l'héritage. Ces relations s'appliquent aux objets instanciés à partir des classes.

Agrégations

Décrit la relation entre un tout (l'agrégat) et se parties. Exemple:

Composition

La composition est une forme d'agrégation exclusive. Les parties sont totalement dépendantes du composite.

Ici, la classe bâtiment est composée d'étages et de toits, mais c'est le bâtiment qui doit se charger de l'instanciation des classes “toit” et “etage”. Un étage ou un toît ne peut exister sans bâtiment et un bâtiment se doit d'avoir un toît et un étage.

Concrètement, la composition se distingue de l'agrégation uniquement par la cardinalité (1 du côté du composite et au moins 1 du côté du composant). Son utilité est donc toute relative quand on note bien les cardinalités.

Cardinalités

La cardinalité est un symbole (un chiffre ou une lettre: 1,2,3,n) qui indique combien de parties peuvent appartenir à combien d'agrégats. On se contente généralement de retranscrire les trois cardinalités suivantes:

  • many2many n → n
  • many2one ou one2many n → 1 ou 1 → n
  • one2one 1 → 1

Exemples:

Un bâtiment ne peut avoir qu'un seul toit et un toit ne peut couvrir qu'un seul bâtiment.

Une bâtiment peut avoir plusieurs étages mais un étage ne peut appartenir qu'à un seul bâtiment.

Un bâtiment peut compter plusieurs employés et un employé peut être affecté à plusieurs bâtiments.

On peut cependant affiner son modèle avec des cardinalités plus complexes, par exemple:

0..n → 1..4 : ici, 0 ou plusieurs instances a sont liées à 1, 2, 3 ou 4 instances b

Ceci est très rarement utile, sauf au niveau conceptuel.

Généralisation/spécialisation (héritage)

L'héritage est un type de relation où une classe prend tous les attributs et méthodes d'une autre.

exemple:

class individu():
    nom = "default"
    prenom = "default"
    
    def marcher():
        pass
        
    def courir():
        pass
        
        
class plombier(individu):
    charge_chalumeau = 100
    
    def changer_robinet():
        pass
        
        
class peintre(individu):
    couleur_pot = "blanc"
    
    def peindre_mur():
        pass

Ici, les deux classes “plombier” et “peintre” héritent de la classe “individu” tous ses attributs et ses méthodes. Une instance de la classe plombier comme de la classe peintre aura un nom et pourra marcher et courir. Cependant, chacun se spécialise (poser_robinet, peindre_mur) et a des attributs supplémentaires (la charge du chalumeau et la couleur du pot de peinture).

Pour continuer l'exemple en python, voici une instanciation de la classe peintre, l'objet s'appelle “yves”:

In [9]: yves = peintre()

In [11]: dir(yves)
Out[11]: 
['__doc__',
 '__module__',
 'couleur_pot',
 'courir',
 'marcher',
 'nom',
 'peindre_mur',
 'prenom']

In [12]: help(yves)

Help on instance of peintre in module __main__:

class peintre(individu)
 |  Methods defined here:
 |  
 |  peindre_mur()
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  couleur_pot = 'blanc'
 |  
 |  ----------------------------------------------------------------------
 |  Methods inherited from individu:
 |  
 |  courir()
 |  
 |  marcher()
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes inherited from individu:
 |  
 |  nom = 'default'
 |  
 |  prenom = 'default'

En utilisant l'introspection de python, les fonctions dir() et help(), on voit bien ici que l'objet yves de la classe peintre a hérité des attributs et des méthodes de la classe indivdu.

Classes abstraites

Les classes abtraites sont des classes qui ne peuvent pas être instanciées. Leur utilité est de fournir une base aux classes filles qui en héritent.

Dans l'exemple ci-dessus, la classe “individu” serait une classe abstraite en java. En python, il n'y a pas de classe abstraite.

Interface

Une interface est une classe spéciale qui ne contient que des méthodes.

Les cas d'utilisation (use case)

Avec le diagramme de classe, le diagramme de cas d'utilisations est sans doute le type de diagramme le plus important, son importance n'est pas à négliger, même si le développeur est aussi un des utilisateurs finaux, ce qui est souvent le cas dans les logiciels libres. On prépare les deux types de diagramme en parallèle.

On le met en place en liaison avec l'utilisateur, il est donc essentiel au SaaS (Software as a Service). Typiquement, en MVC (Model-Vue-Controler), les use-cases aident en premier lieu à mettre en place la partie vue mais ils sont également un point de référence pour organiser ses classes et ses méthodes. On peut faire un diagramme d'objet pour chaque cas d'utilisation, ce qui permet de vérifier la cohérence du programme et de voire où doivent être placés les contrôleurs.

Les diagrammes de composants

Le diagramme de composant permet de définir l'interaction entre les différents composants du logiciel mais aussi entre celui-ci, le système d'exploitation, et le réseau.

expert/uml.txt · Dernière modification : 2018/11/17 12:53 de 127.0.0.1