Introduction
On souhaite modéliser des QCMs, avec des questions acceptant soit une seule réponse, soit plusieurs réponses. Un modèle de QCM doit permettre de générer le QCM à différents formats : page web, formulaire papier, outil de gestion de questionnaires en ligne.
Métamodèle
Le métamodèle décrit les concepts supportés par le langage de modélisation, ainsi que les relations entre ces concepts.
Dans notre cas, les concepts premiers sont :
- QCM
- représente un questionnaire
- SingleChoiceQuestion
- représente une question admettant une unique réponse
- MultipleChoiceQuestion
- représente une question admettant plusieurs réponses
- Answer
- représente une réponse possible à une question
Les relations sont très simples : un QCM est composé de questions qui ont des réponses possibles.
On obtient le métamodèle suivant :
Remarques
- Dans ce métamodèle, on a explicité la notion abstraite de Question, dont SingleChoice et MultipleChoice sont des raffinements, et on a factorisé le fait d'avoir une description dans la classe abstraite DescribedEntity.
- Les classes n'ont pas de comportement, uniquement des attributs, car un métamodèle décrit une syntaxe abstraite et ne donne pas de sémantique. On a donné un attribut name de type String à QCM afin de pouvoir identifier les QCMs, et d'avoir un nom pour les fichiers à générer. On a donné un attribut score de type Integer à Answer pour représenter le nombre de points (positif ou négatif) que rapporte cette réponse.
- Les relations de composition permettent bien d'atteindre tous les éléments d'un modèle à partir d'un élément racine (ici, une instance de QCM). La structure d'un modèle selon ces relations est bien un arbre.
Génération de code HTML/JavaScript
On souhaite maintenant générer une page web qui affiche un QCM, qui permet de sélectionner des réponses, et qui affiche un score sur 20 points qui ne doit pas être négatif.
On considère l'exemple de QCM suivant :
- QCM name="qcm1" description="Example QCM"
- SingleChoice description="Is it easy?"
- Answer description="yes" score=1
- Answer description="no" score=-1
- MultipleChoice description="Why MDE is important?"
- Answer description="It is fashionable" score=-1
- Answer description="It is cool" score=0
- Answer description="It helps to design systems" score=2
- SingleChoice description="Is it easy?"
qui devrait donner cette page HTML.
Conception de la transformation
Il s'agit ici d'une transformation model to text, que nous réalisons en Acceleo. Le principe de la conception d'une telle transformation est d'écrire manuellement le résultat pour un modèle de petite taille, puis de repérer dans ce résultat les éléments qui dépendent du modèle, et de les remplacer par des instructions Acceleo de parcours et d'accès aux éléments du modèle.
Points clefs
- le nom du fichier généré est obtenu en ajoutant
'.html'
au nom du QCM. - les crochets ouvrants
[
doivent être remplacés par['['/]
(la chaîne de caractères'['
dans la syntaxe Acceleo) puisque ces crochets indiquent que l'on sort du texte à générer pour passer dans les instructions Acceleo. - dans une boucle
[for ...] [/for]
, on a accès à une variablei
qui varie de 1 à n si la boucle fait n tours. L'attributseparator
d'une boucle[for]
permet de spécifier le texte à insérer entre les éléments générés par les itérations successives de la boucle. - il est possible de définir d'autres templates que le template principal et de les appeler pour traiter des sous-parties du modèle.
- les template sont polymorphes : il fonctionnent comme des méthodes dans un langage à objets. On peut ainsi définir un template pour une classe, le redéfinir pour les différentes sous-classes, et c'est bien le type effectif de l'élément du modèle passé en argument qui détermine quelle version du template est appelée.
Code de la transformation