Rubriques

IntroductionHaut de la page

Cette recommandation décrit les étapes impliquées dans la génération de code d'une base de données et le mappage des tableaux de modèle de données obtenus aux classes de conception dans le modèle de conception. Ce processus peut être utilisé par le concepteur de base de données pour que le développement des modifications dans la base de données fasse partie intégrante du cycle de développement d'évolution. Le concepteur de la base de données devra gérer le processus de génération de code tout au long du cycle de vie de développement du projet.  Dans bien des cas, le processus de génération de code est effectué tôt dans le cycle de vie du projet, puis les changements de la conception des données sont gérés de façon incrémentielle sans avoir besoin d'effectuer de génération de code ultérieur à la base de données.

Les principales étapes du processus de génération de code d'une base de données et de la transformation des éléments de modèle de données obtenus en éléments de modèle de conception sont les suivantes :

  • Créer un modèle de données physique contenant des tableaux pour représenter la présentation physique des données persistantes dans la base de données. Cette étape peut être effectuée automatiquement en utilisant des outils fournis avec le système de gestion des bases de données relationnelles (SGBDR) ou par le biais des outils de modélisation visuelle les plus modernes.
  • Convertir les tableaux dans le modèle de données physique en classes de conception dans le modèle de conception. Cette étape peut être effectuée par le biais de la prise en charge d'outils automatisée pour la transformation initiale suivie d'ajustements manuels.
  • Définir les associations entre les classes dans le modèle de conception.
  • Définir les opérations appropriées sur les classes dans le modèle de conception selon les actions effectuées sur les éléments de modèle de données correspondants.
  • Regrouper les classes dans le modèle de conception en sous-systèmes et packages selon les besoins.

Génération de codede la base de données de SGBDR ou du script de langage de définition de données pour générer un modèle de données Haut de la page

Le processus de génération de code de base de données ou de script de langage de définition de données (LDD) regroupe généralement un ensemble d'éléments de modèle (tableaux, vues, procédures stockées, etc.) dans un ou plusieurs packages systèmes définis dans le modèle de données. Selon la complexité de la base de données, le concepteur de base de données peut devoir diviser les éléments de modèles ayant subi une génération de code en packages de domaines contenant des ensembles de tableaux possédant des liens logiques.

Convertir le modèle de données en modèle de conception Haut de la page

La procédure suivante peut être utilisée pour produire des classes de conception à partir d'éléments de modèle du modèle de données. Il est relativement simple de reproduire la structure de la base de données dans un modèle de classe. Le processus listé ci-dessous décrit l'algorithme pour la transformation d'éléments de modèles de données en éléments de modèles de conception.

Le tableau ci-dessous montre un résumé du mappage général entre les éléments de modèle de conception et les éléments de modèle de données.

Elément de modèle de données 

Elément correspondant de modèle de conception 

Tableau  Classe 
Colonne  Attribut 

Relation non-identificatoire 

Association 

Tableau d'intersection

 

Classe d'association

Association à origine et à destination multiples

Association conditionnelle 

Identifier la relation 

Agrégation composite 

Cardinalité 

 

Multiplicité 

 
Vérifier la contrainte avec une clause d'énumération  <<Classe>>ENUM 
Schéma  Package 

Certains éléments de modèle du modèle de données n'ont pas de corrélation directe dans le modèle de conception. Ces éléments incluent les tablespaces et la base de données elle-même, qui modélisent les caractéristiques de stockage physique de la base de données et sont représentés en tant que composants. Un autre élément, les vues de base de données, sont des tableaux "virtuels" et n'ont pas de signification dans le modèle de conception.  Pour finir, les index des clés primaires des tableaux et de la base de données déclenchent des fonctions qui sont utilisées pour optimiser le fonctionnement de la base de données ont seulement un sens dans le contexte de la base de données et du modèle de données.

Convertir un tableau en classe Haut de la page

Pour chaque tableau que vous souhaitez convertir, créez une classe pour représenter le tableau. Pour chaque colonne, créez un attribut sur la classe avec le type de données approprié. Essayez de faire correspondre le plus étroitement possible le type de données de l'attribut avec le type de données de la colonne associée.

Exemple

Examinez le tableau de base de données client, avec la structure suivante, montré dans la figure ci-dessous :

Nom de colonne Type de données
Code client Numéro
Nom Varchar
Rue Varchar
Ville Varchar
Etat/ province Char(2)
Code postal Varchar
Pays Varchar

Définition de tableau pour le tableau client

A partir de là, nous créons une classe client, avec la structure montrée dans la figure suivante :

Définition de classe client

Classe client initiale

Dans cette classe client initiale, il y a un attribut pour chaque colonne du tableau client. Chaque attribut a une visibilité publique, dans la mesure où toutes les colonnes de la table d'origine peuvent être interrogées.

Notez que l'"+" icône listée à la gauche de l'attribut indique que l'attribut est "public" ; par défaut, tous les attributs extraits des tableaux SGBDR doivent être publics, car le SGBDR permet généralement à toutes les colonnes d'être interrogées sans restriction.

Identifier les classes incorporées ou implicites Haut de la page

La classe qui est obtenue à partir du mappage direct tableau-classe contiendra souvent des attributs pouvant être séparés dans une classe indépendante, en particulier dans les cas où les attributs se traduisent dans un certain nombre de classes. Ces "attributs répétés" peuvent résulter de la dénormalisation des tableaux pour les raisons de performance, ou peuvent venir d'un modèle de données excessivement simple. Dans ces cas, séparez la classe correspondante en deux classes ou plus pour représenter une vue normalisée des tableaux.

Exemple

Après avoir défini la classe client ci-dessus, nous pouvons définir une classe adresse contenant toutes les informations sur les adresses (en supposant que notre système contiendra autre chose que des adresses), ce qui donne les classes suivantes :

Diagramme décrit dans le texte d'accompagnement.

classe client révisée, avec la classe adresse extraite

L'association obtenue entre ces deux classes est une agrégation, dans la mesure où l'adresse du client peut être considérée comme une partie du client.

Traiter les relations de clé étrangère Haut de la page

Pour chaque relation de clé étrangère dans le tableau, créer une association entre les classes associées, en supprimant l'attribut de la classe mappée à la colonne clé étrangère. Si la colonne clé étrangère a été initialement présentée comme un attribut, supprimez-la de la classe.

Exemple

Présumez la structure pour le tableau commande listé ci-dessous :

Nom de colonne  Type de données 
Numéro  Numéro 
Code client  Varchar 

Structure du tableau commande

Dans le tableau commande listé ci-dessus, la colonne code client est une référence de clé étrangère ; cette colonne contient la valeur clé primaire du client associé à la commande. Nous représentons cela dans le modèle de conception comme montré ci-dessous :

Diagramme UML décrit ci-dessous.

Représentation des relations de clé étrangère dans le modèle de conception

La clé étrangère est représentée en tant qu'association entre les classes commande et élément.

Traiter les relations à origine et destination multiples Haut de la page

Les modèles de données SGBDR représentent des relations à origine et destination multiples avec ce qui a été appelé un tableau de jointure, ou un tableau d'association. Ces tableaux permettent de représenter des relations à origine et destination multiples en utilisant un tableau intermédiaire contenant les clés primaires de deux tableaux différents qui peuvent être reliés l'un à l'autre. Les tableaux de jointure sont requis car une référence de clé étrangère peut uniquement contenir une référence à une seule valeur de clé étrangère ; lorsqu'une seule ligne peut être liée à plusieurs autres lignes d'un autre tableau, un tableau de jointure est requis pour les associer.

Exemple

Examiner le cas où des produits, peuvent être fournis par de nombreux fournisseurs, et où un fournisseur peut fournir un certain nombre de produits. Les tableaux produit et fournisseur ont la structure définie ci-dessous :

Tableau produit
Nom de colonne Type de données
Code produit Numéro
Nom Varchar
Description Varchar
Prix Numéro
Tableau fournisseur
Nom de colonne Type de données
Code fournisseur Numéro
Nom Varchar
Rue Varchar
Ville Varchar
Etat/ province Char(2)
Code postal Varchar
Pays Varchar

Définition des tableaux produit et fournisseur

Pour relier ces deux tableaux l'un à l'autre afin de trouver les produits proposés par un fournisseur donné, nous avons besoin d'un tableau produit-fournisseur défini dans le tableau ci-dessous.

Tableau produit-fournisseur
Nom de colonne  Type de données 
Code produit  Numéro 
Code fournisseur . Numéro 

Définition tableau produit-fournisseur

Ce tableau de jointure contient les clés primaires des produits et des fournisseurs, et les relie. Une ligne du tableau indique qu'un fournisseur spécifique propose un produit spécifique. Toutes les lignes dans lesquelles une colonne Code fournisseur correspond à un code fournisseur spécifique fourniront une liste de tous les produits proposés par ce fournisseur.

Dans le modèle de conception, cette table intermédiaire est redondante, car un modèle d'objet peut représenter directement des associations à origine et à destination multiples. Les classes fournisseur et produit et leurs relations sont montrées dans la figure ci-dessous, ainsi que la classe adresse qui est extraite du tableau fournisseur, selon la discussion précédente.

Diagramme UML décrit dans le libellé.

Représentation de la classe produit et fournisseur

Présenter la généralisation Haut de la page

Vous trouverez souvent des tableaux qui possèdent une structure similaire. Dans le modèle de données, le concept de généralisation n'existe pas, il n'y a donc pas de manière de représenter le fait que deux tableaux ou plus ont une structure commune. Parfois la structure commune résulte de la dénormalisation pour la performance, comme c'était le cas ci-dessous avec le tableau adresse "implicite" que nous avons extrait dans une classe séparée. Dans d'autres cas, les tableaux partagent des caractéristiques plus fondamentales que nous pouvons extraire dans une classe parente généralisée avec deux sous-classes ou plus. Pour trouver des possibilités de généralisation, cherchez des colonnes répétées dans plusieurs tableaux, où les tableaux sont plus similaires qu'ils ne sont différents.

Exemple

Examinez les tableaux suivants, produit logiciel et produit matériel, comme indiqués ci-dessous :

Tableau de produit logiciel
Nom de colonne  Type de données 
Code produit  Numéro 
Nom  Varchar 
Description  Varchar 
Prix  Numéro 
Version  Numéro 
Tableau de produit matériel
Nom de colonne  Type de données 
Code produit  Numéro 
Nom  Varchar 
Description  Varchar 
Prix  Numéro 
Version  Numéro 


Tableaux produit logiciel et produit matériel

Vous remarquerez que les colonnes surlignées en bleu sont identiques ; ces deux tableaux possèdent sensiblement la même définition, et ne diffèrent que très peu. Nous pouvons représenter ce fait en extrayant une classe produit commune, produit logiciel et produit matériel étant des sous-classes du produit, comme indiqué dans la figure suivante :

Diagramme décrit dans le texte d'accompagnement.

Classes produit logiciel et produit matériel, montrant la généralisation de la classe produit

La figure ci-dessous regroupe toutes les définitions de classe et montre un diagramme de classe récapitulatif du système de saisie des commandes (uniquement les principales classes).

Diagramme UML complexe décrit dans le texte d'accompagnement.

Diagramme de classe récapitulatif pour le système de saisie des commandes

Reproduire le comportement du système de gestion de base de données relationnelle dans le modèle de conception Haut de la page

Il est plus difficile de reproduire le comportement dans la mesure où les bases de données relationnelles ne sont généralement pas orientées objet et n'ont en apparence rien de commun avec les opérations d'une classe dans le modèle d'objet. Les étapes suivantes peuvent aider à reconstruire le comportement des classes identifiées ci-dessus :

  1. Créer des opérations pour atteindre et définir chaque attribut. Il doit exister une manière de définir, changer et interroger les valeurs des attributs des objets. Dans la mesure où la seule façon d'accéder aux attributs d'un objet est par le biais d'opérations que la classe fournit, de telles opérations doivent être définies dans la classe. En créant les opérations qui définissent la valeur d'un attribut, assurez-vous d'intégrer toutes les contraintes en terme de validation qui peuvent agir sur la colonne associée. S'il n'y a pas de contraintes de validation, on peut choisir de simplement représenter le fait que les attributs peuvent être atteints et définis en les définissant comme possédant une visibilité "publique" comme cela a été fait dans les diagrammes ci-dessus (avec l'icône à la gauche du nom d'attribut).
  2. Créer une opération sur la classe pour chaque procédure stockée qui agit sur le tableau associé. Les procédures stockées sont des sous-routines exécutables qui s'exécutent au sein du SGBD. Cette logique doit se traduire dans le modèle de conception. Si une procédure stockée n'agit que sur une classe, créez une opération sur la classe avec les mêmes paramètres et le même type de retour que la procédure stockée. Documentez le comportement de la procédure stockée dans l'opération, en vous assurant de noter dans la description de la méthode que l'opération est implémentée par la procédure stockée.
  3. Créer des opérations pour gérer les associations entre les classes. Lorsqu'il y a une association entre deux classes, il doit y avoir une manière de créer, gérer et supprimer les associations. Les associations entre les objets sont gérées par le biais de références d'objet, ainsi, pour créer une association entre une commande et une ligne article (c'est-à-dire ajouter la ligne article à la commande), une opération sur une commande doit être appelée, en faisant passer la ligne article comme un argument (c'est-à-dire Commander.ajouter(unelignearticle)). Il doit également exister des manières de supprimer et de mettre à jour l'association (c'est-à-dire Commande.supprimer(unelignearticle) et Commande.changer(unelignearticle, unenouvellelignearticle)).
  4. Traiter la suppression d'objet. Si la langue cible prend en charge la suppression explicite, ajoutez au destructeur de classe un comportement implémentant une vérification de l'intégrité référentielle. Dans les cas où la base de données possède des contraintes d'intégrité référentielle, comme la suppression en cascade, le comportement doit être reproduit dans les classes appropriées. Par exemple, la base de données peut définir une contrainte exigeant que lorsqu'une commande est supprimée, toutes les lignes articles associées soient également supprimées. Si la langue cible prend en charge la récupération de place, créez un mécanisme par lequel les lignes peuvent être supprimées des tableaux lorsque l'objet associé est supprimé. Notez que c'est plus complexe qu'il n'y paraît (et cela paraît pourtant complexe) car vous devrez implémenter un mécanisme pour vous assurer qu'aucun client de la base de données ne possède de référence à l'objet qui doit être supprimé pour récupérer de la place ; il ne suffit pas de se fier aux capacités de récupération de place de l'environnement d'exécution/ machine virtuelle car il ne s'agit que de la vue du monde d'un client.
  5. Traiter le comportement entraîné par les requêtes. Examiner les instructions de sélection accédant à la table afin de voir comment l'information et récupérée et manipulée. Pour chaque colonne directement renvoyée par une instruction de sélection, définissez la propriété publique de l'attribut associé comme vrai ; tous les autres attributs doivent être privés. Pour chaque colonne traitée d'une instruction de sélection, créez une opération sur la classe associée pour traiter et renvoyer la valeur. En examinant les instructions de sélection, incluez également les instructions de sélection incorporées dans les définitions de vue.

Organiser les éléments dans le modèle de conception Haut de la page

Les classes de conception créées à partir des transformations tableaux-à-classe doivent être organisées en packages de conception et/ou en sous-systèmes de conception adaptés dans le modèle de conception, selon les besoins, en se basant sur la structure architecturale globale de l'application. Référez-vous à Concepts : Organisation en couches et Concepts : Architecture logicielle pour une présentation de l'architecture d'application.



RUP (Rational Unified Process)   2003.06.15