Les paramètres du moteur MDA

Paramètres de transformation de classes

Les paramètres qui influent sur la transformation d'un modèle PIM en modèle PSM sont situés dans la fenêtre des Options accessible depuis le menu Tools (raccourci clavier Ctrl + F9).

Les paramètres qui ont un impact direct dans la transformation en modèle PSM Java sont :

Options - Source Code Engineering

mda source code engineering optionsEcran 1 : Options Source Code Engineering
  • Auto generate roles names when creating code : cette option est nécessaire pour que EA ajoute à la classe traitée un attribut (y compris les accesseurs et modifieurs) correspondant à la classe reliée par une association qui ne dispose pas de nom de rôle explicite.
    Le nom de l'attribut est alors généré en reprenant le nom de la classe distante. Si je me réfère à l'exemple de la classe Contrat présentée dans l'étude de cas, elle est reliée à la classe LigneDetail par une association de type composition ne disposant pas de nom de rôle côté LigneDetail. EA a malgré tout généré un membre nommé m_LigneDetail et les accesseur et modifieur correspondant (également désignés getter et setter si j'utilise les termes anglais).
  • Do not generate members where association direction is 'Unspecified' : comme son intitulé l'indique, cette option lorsqu'elle est activée, exclut de la transformation les associations pour lesquelles la direction n'est pas spécifiée (valeur de la Direction à unspecified dans les propriétés de l'association).
    En revanche lorsqu'elle est désactivée, EA ajoute à la classe source un attribut correspondant à la classe cible lorsqu'elles sont toutes deux reliées par une association dont la direction est à Unspecified.
    Une association doit être représentée par une double flèche (valeur de la Direction à Bi-Direction dans les propriétés de l'association) pour qu'un attribut de la classe distante soit ajouté aux deux classes reliées entre-elles.
  • Remove prefixes when generating Get/Set properties : permet de supprimer les préfixes renseignés dans la liste pour générer les accesseurs et modifieurs dans la classe transformée. Par exemple, pour un attribut nommé m_prenom, l'accesseur se nomme getPrenom() et le modifieur setPrenom().
  • Capitalized Attribute Name for Properties : indique lorsque l'option est cochée que le nom de l'attribut doit commencer par une lettre majuscule pour nommer les accesseurs et mutateurs.
    Ce qui donne pour un attribut nommé nom dans le modèle PIM l'accesseur getNom() et le mutateur setNom() dans le modèle PSM.

Options - Java

mda java optionsEcran 2 : Options Java
  • Get prefix et Set prefix : vous pouvez personnaliser le préfixe des méthodes d'accès aux membres des classes. Les valeurs get et set proposées par défaut conviennent cela dit parfaitement.
  • Default Collection Class : nom de la classe de collection à utiliser par défaut comme type des membres ajoutés aux classes disposant d'associations 1..*.
    En choisissant par exemple la classe de collection java.util.List, la déclaration du membre m_LigneDetail généré pour la classe Contrat (voir l'exemple de la rubrique Le code Java généré) devient :
               private java.util.List m_LigneDetail;
    Les méthodes d'accès quant à elles deviennent :
               public java.util.List getGroupeUtilisateur() {
                       return m_GroupeUtilisateur;
               }
     
               public void setGroupeUtilisateur(java.util.List newVal){
                       m_GroupeUtilisateur = newVal;
               }

Il est possible d'aller encore plus loin dans la définition des classes de collection en cliquant sur le bouton Collection Classes de l'écran 2.

mda collection classes for association rolesEcran 3 : Options Java - Collection Casses

La fenêtre Collection Classes for Association Roles prévoit la saisie d'une classe de collection par défaut pour les associations d'une multiplicité > à 1, mais également une classe de collection en particulier pour les associations dont le rôle cible dispose de l'option ordered ou encore pour les associations disposant d'un ou plusieurs qualificatifs (voir les onglets Source Role ou Target Role dans les propriétés de l'association).

A noter également que EA supporte les collections Java de type Generics. Le mot clé #TYPE# peut être ajouté à la définition de la classe de collection pour préciser le type des objets qu'elle devra contenir. Par exemple :

  • Default Collection Class: java.util.Collection<#TYPE#>
  • Collection Class for Ordered Multiplicity: java.util.List<#TYPE#>
  • Collection Class for Qualified Multiplicity: java.util.Map<KeyType, #TYPE#>

Sachez pour finir que la définition des collections est permise pour une classe en particulier, depuis la fenêtre d'affichage de ses propriétés (menu Element | Properties...) à l'onglet Details en cliquant sur le bouton Collection Classes...

mda class details propertiesEcran 4 : propriétés d'une classe UML, onglet Details

La classe pour laquelle la collection est redéfinie correspond aux objets contenus dans la collection en question.

Paramètres de génération de code

Les paramètres qui interviennent dans la génération de code sont également situés dans la fenêtre des Options accessible depuis le menu Tools (raccourci clavier Ctrl + F9).

Options - Object Lifetime

mda object lifetimes optionsEcran 5 : options Object Lifetime
  • Generate constructor : lorsque cette option est cochée, un constructeur par défaut est ajouté à la classe PSM.
  • Generate destructor : ajoute un finaliseur (méthode finalize()) à la classe dans le cas d'un génération en code Java et un destructeur dans les langages objets tels que le C++. Cette option peut à mon sens être décochée compte-tenu du besoin plutôt rare de nettoyage de l'objet avant sa désallocation par le ramasse-miettes
  • .

Options - Attributes/Operations

mda attributes operations optionsEcran 6 : options Attributes/Operations
  • Default name for associated attrib : indique le format des attributs ajoutés à une classe pour accéder aux objets liés dont la multiplicité est supérieure à 1. Par défaut, le format proposé est m_$LinkClass$LinkClass est le nom de classe de l'objet lié.

Conversion des types de données

La conversion des types de données des attributs de classes PIM lors du processus de transformation est réalisé à partir d'une table de correspondance des types de données de la fenêtre Programming Language Datatypes, accessible à partir du menu Settings | Code Datatypes...

mda programming languages datatypesEcran 7 : conversion des types de données

Dans cette table, le terme Common type désigne le type de données générique utilisé dans le modèle de classes PIM.
Le terme Datatype quant à lui correspond au type de données spécifique au langage de développement cible du modèle PSM.

Par exemple, si je choisis Java dans la liste déroulante Product Name, puis sélectionne dans la liste Defined Datatypes for Programming Languages la première ligne (Datatype est boolean), je constate que le type Boolean (Common type) de la classe PIM est converti en boolean (Datatype) dans la classe PSM.

Pour convertir un type générique qui ne figure pas dans la table de conversion, je peux l'ajouter en cliquant sur le bouton New. Par exemple Text pour Common type et String pour Datatype. Un attribut de type Text de la classe PIM devient alors String dans la classe PSM.

L'autre solution consiste à définir le type String dans la classe PIM. Comme il n'existe pas de Common type à la valeur String, le processus de transformation reporte ce même type pour l'attribut de classe PSM.

Les templates de transformation

Les templates (ou modèles en français) de transformation peuvent être assimilés à des fonctions, appelées successivement par le processus de transformation MDA, et chargées chacunes de réaliser une partie des tâches telles que la transformation des paquetages, des classes, des attributs, associations.

Le code de ces templates peut être personnalisé pour obtenir un modèle PSM adapté aux besoins du projet. Ce code est basé sur un langage de macros spécifique à EA et sur un jeu de fonctions répondant aux besoins particuliers de transformation.

L'éditeur de templates de transformation est affiché dans l'espace de travail en sélectionnant l'élément de menu Settings | Transformation Templates... (raccourci clavier Ctrl + Alt + H).

mda transformation editorEcran 8 : éditeur des templates de transformation

Regardons d'un peu plus près les templates de transformation du langage Java.
Ils sont affichés dans la liste de gauche dans leur ordre d'appel par le traitement de transformation :

  • Template File : ce premier template constitue le point d'entrée de la transformation. Il consiste à créer le paquetage racine (namespaceroot) nommé Java Model dans lequel le modèle PSM et à générer.
    Comprenez que ce paquetage n'est créé que s'il n'existe pas déjà. Il se termine par l'appel du paquetage suivant pour la génération des sous-paquetages (la macro %list permet par l'appel d'un template dédié, de générer une liste d'éléments).
  • Template Namespace : crée un a un les sous-paquetages du paquetage racine à partir des informations des paquetages sources.
    Cela est réalisé grâce à la fonction %TRANSFORM_CURRENT()%. Invoquée sans paramètre, cette macro reproduit à l'identique le paquetage source du modèle PIM dans le modèle PSM (sous le paquetage Java Model).
    Après création du paquetage cible, la macro %list invoque le template Class pour transformer la liste des classes PIM du paquetage source.
  • Template Class : il est chargé de recréer les classes dans le modèle PSM. Pour cela, il utilise à nouveau la fonction %TRANSFORM_CURRENT()% en passant cette fois en paramètre l'attribut language pour indiquer que la classe source doit être reproduite à l'identique dans le modèle cible, excepté pour cet attribut dont la valeur est redéfinie à Java à la ligne suivante.
    Vous constatez également un appel à la fonction %TRANSFORM_REFERENCE()%. Chaque classe créée par transformation doit contenir un appel à cette fonction pour permettre à Enterprise Architect de la relier à une autre classe, notamment par une association.
    Plus généralement, cette fonction est nécessaire à EA pour synchroniser tout élément du modèle PIM avec celui du modèle PSM.
    Le template se poursuit par l'appel successif des templates suivants, toujours par la macro %list.
  • Template Attribute : il recrée les attributs de classe. On retrouve ici toujours les appels aux fonctions %TRANSFORM_REFERENCE()% et %TRANSFORM_CURRENT()%. Cette dernière reçoit les paramètres scope, type et stereotype, propriétés de l'attribut redéfinies en particulier comme suit :
    • Les attributs publics sont changés en privés (car accédé via les accesseurs et modifieurs),
    • Les attributs d'une énumération sont stéréotypées en enum pour leur déclaration en Java
    • Le type est transformé grâce à la fonction %CONVERT_TYPE() qui s'appuie sur la table de trans-typage présentée au paragraphe Conversion des types de données.
  • Template Linked Attribute : il est appelé de manière implicite par EA après exécution du template Attribut. Ne vous attendez pas par conséquent à trouver un appel explicite du genre %list="Linked_Attribute"; c'est l'instruction %list="Attribute" qui se charge également d'invoquer le template Linked Attribute.
    Ce modèle crée les attributs d'accès aux objets des classes distantes. La classe de collection paramétrée dans les options (voir paragraphe Paramètres de génération de code) vient typer les attributs d'accès aux objets des classes distantes dont la multiplicité est supérieure à 1 (fonction %COLLECTION_CLASS() invoquée pour obtenir le nom de la classe de collection paramétrée pour le langage Java ). Si un nom de rôle a été renseigné, il est repris pour nommer l'attribut; autrement, c'est le nom par défaut défini dans les paramètres qui est appliqué, après remplacement du texte $LinkClass par le nom de la classe distante (voir paramètre Default name for associated attrib du paragraphe Paramètres de génération de code) à l'aide de la fonction %REPLACE().
    Pour finir, le template Properties est appelé pour créer également les accesseur et modifieur (getter et setter en anglais) de l'attribut.
  • Template Attribute_AsProperties : appelle le template Properties de création des accesseur et modifieur des attributs publics de la classe PIM.
  • Template Operation : prend en charge la transformation des opérations de classe et convertit le type de la donnée retournée par chacune d'entre-elles.
  • Template Parameter : recrée les paramètres des fonctions transformées par le précédent template et effectue la conversion de leur type de données.
  • Template Connector : recrée les relations entre classes en prenant soin de changer l'accès de sa source et sa cible de Public en Private.
  • Template Properties : ajoute un accesseur et modifieur à la classe transformée pour le membre dont le nom et le type sont passés en paramètre du template (appel depuis les templates Attribute_AsProperties et Linked Attribute).
    A noter l'utilisation de la fonction %REMOVE_PREFIX() pour supprimer dans le nom du membre en paramètre un éventuel préfixe parmi ceux paramétrés (voir paramètre Remove prefixes when generating Get/Set properties du paragraphe Paramètres de transformation de classes).
    La fonction %CONVERT_NAME() enfin permet de modifier la casse du nom passé en paramètre en indiquant le format source et cible, à savoir dans l'exemple camel case (première lettre en minuscule comme par exemple monAttributDeClasse) et pascal case (première lettre en majuscule comme par exemple MaClasseDuModele).

Les templates de génération de code

Les templates de génération de code (ou modèles de génération de code) sont assez similaires à ceux utilisés par les traitements de transformation.

Ils sont invoqués pour produire le code source du logiciel à partir des classes PSM.

Ils peuvent également être personnalisés en vue de générer du code sur mesure.

Le langage utilisé pour coder les traitements de génération de code correspond à celui utilisé par les templates de transformation.

La documentation en ligne livrée avec EA décrit en détail la syntaxe de ce langage à la rubrique SDK for Enterprise Architect | Code Template Framework in SDK | Code Template Syntax, également consultable sur le site internet de Sparx Systems.

L'éditeur de templates de génération de code est affiché en cliquant dans le menu Settings | Code Generation Templates... (raccourci clavier Ctrl + Maj + P).

mda code template editorEcran 9 : éditeur des templates de génération de code

A l'instar du processus de transformation, le template File affiché en premier dans la liste intitulée Templates, est le premier appelé par EA à la génération de code.

Je ne passerai pas en revue les templates du langage Java comme j'ai pu le faire au paragraphe précédent, mais je souhaite malgré tout m'arrêter quelques instants sur les templates suivants :

  • Templates Class Notes, Attribute Notes, Linked Attribute Notes et Operation Notes : la fonction JAVADOC_COMMENT() ajoute sous forme de commentaires Javadoc les notes renseignées pour les classes et les attributs de classe.
  • Templates Import Section : il ajoute en début de fichier du code Java généré, autant d'instructions import que de classes à importer parmi celles renseignées à la génération de code (voir champ Import(s) / Header(s) de la fenêtre Generate Code au paragraphe Génération du code Java).
    Le template se termine par l'appel du template Import chargé d'ajouter une instruction d'import pour chacune des classes reliées (association, généralisation, réalisation et dépendance) connectées à la classe en cours de génération de code.
  • Template Operation Body : notez pour ce template-ci, qu'il en existe plusieurs variantes (concept de Stereotype Overrides pour désigner les variantes de code d'un template, applicables à un stéréotype en particulier, voire même à la combinaison de deux stéréotypes).
    Selon le stéréotype de l'opération en cours de traitement par le processus de génération de code, EA choisit le template conçu sur mesure pour générer le code.
    Par exemple pour les opérations stéréotypées property get, EA ajoute dans le corps de la méthode l'instruction return appliquée au membre de la classe pris en charge par l'accesseur.
    Dernier point intéressant, l'usage de la macro de substitution opTag qui associée au nom de la Tagged Value attribute_name, permet de retrouver le nom de l'attribut de classe dont il est question dans l'accesseur. Ce nom d'attribut a été associé à l'opération lors du processus de transformation grâce à la fonctionnalité de Tagged Values disponible dans EA pour associer à tout élément UML, des propriétés supplémentaires à celles prévues en standard.

Maintenant que vous êtes familiers des concepts de transformation de classes UML et de génération de code en langage Java, je vous invite à lire le chapitre suivant Quelques limites rencontrées.