III. Concepts de base : modélisation et développement de l'application d'exemple▲
III-A. L'entité Person▲
III-A-1. Modélisation▲
Dans cette section, vous allez créer votre toute première entité en utilisant AndroMDA. Puisque les gens sont au cœur de TimeTracker, nous allons commencer par modéliser une entité « Person ». Person a trois attributs: « username » (nom d'utilisateur), « firstName » (prénom) et lastName (nom de famille). Le modèle pour l'entité Person figure ci-dessous.
Notez que nous avons marqué la classe Person avec le stéréotype « Entity ». Cela indique à AndroMDA que Person est une entité, et non pas un autre type d'éléments de modèle comme Enumeration ou Service. Les stéréotypes déterminent quel type de code AndroMDA génèrera pour un élément de modèle. Plus précisément, ils déterminent quels calques de génération de code AndroMDA seront utilisés.
Les stéréotypes et les valeurs balisées sont deux mécanismes de métadonnées prévus par la norme UML. AndroMDA les utilise abondamment et avec des rôles bien précis. Les stéréotypes sont utilisés pour préciser la nature des classes dans un modèle, alors que les valeurs balisées permettent de spécifier des informations propres à la technologie d'implémentation ciblée. Sans les stéréotypes et les valeurs balisées, les capacités d'AndroMDA ne dépasseraient pas celles d'un générateur de code classique. Mais ces mécanismes permettent de donner à AndroMDA des informations de haut niveau sur la nature des éléments modélisés, des informations qui ne sont pas disponibles par défaut dans le langage UML.
Les trois attributs sont de type String. Attention à ne pas confondre ce type avec le type java.lang.String. En architecture pilotée par le modèle, le modèle doit rester indépendant de la technologie d'implémentation et donc tous les éléments de modèle sont définis en termes de types indépendants de la plateforme. Donc « String » dans ce contexte est un type indépendant de la plateforme. Quand nous exécuterons AndroMDA pour générer le code, il traduira les types indépendants de la plateforme en types spécifiques à la plateforme comme java.lang.String. Si nous devions utiliser le même modèle pour générer une application .NET, AndroMDA traduirait String en System.String. Comme vous pouvez le voir, un avantage-clé de l'approche pilotée par le modèle est que votre investissement dans les modèles métier est préservé même lorsque les technologies d'implémentation changent.
Maintenant, intégrons l'entité Person dans le modèle vide créé par le plugin AndroMDA Application. Si vous vous souvenez, ce modèle a été créé dans timetracker\mda\src\uml\TimeTrackerModel.xmi. Les sections qui suivent détaillent les procédures de modélisation suivant l'outil UML de votre choix.
MagicDraw UML▲
Cette section fournit les instructions pour créer l'entité Person en utilisant MagicDraw. Le modèle apparait ci-dessous pour votre référence.
- Démarrez MagicDraw.
- Sélectionnez Fichier > Ouvrir Projet… et ouvrez le fichier C:\TimeTracker\mda\src\uml\TimeTrackerModel.xmi.
- Si vous obtenez un message d'avertissement vous signalant « Module andromda-profile-3.2-RC1.xml.zip non trouvé. », cliquez simplement sur OK. Une boîte de dialogue de recherche de fichier apparait pour vous permettre de localiser andromda-profile-3.2-RC1.xml.zip. Pour cela, rendez-vous dans votre référentiel local Maven, qui se trouve par défaut dans C:\Documents and Settings\<votre nom d'utilisateur>\.maven\repository. Vous trouverez andromda-profile-3.2-RC1.xml.zip dans ce référentiel, dans le répertoire andromda\xml.zips. Sélectionnez ce fichier et cliquez sur « Ouvrir ».
- Le modèle de TimeTracker va maintenant s'ouvrir en affichant le seul diagramme de classes présent dans ce modèle. Le titre de ce diagramme est « DataTypes[datatype] ». Ce diagramme contient les types indépendants de la plate-forme destinés à être utilisés dans votre modèle UML.
- Dans l'Arbre de Confinement sur la gauche, cliquez droit sur l'élément racine appelé Data et sélectionnez Nouvel Elément > Modèle. Un nouveau modèle est alors créé sous l'élément racine avec une boîte d'édition. Entrez-y TimeTracker comme nom pour ce modèle. MagicDraw intègre le concept de hiérarchie de modèles. Chaque modèle dans une hiérarchie peut être sauvegardé dans un fichier séparé. Cela permet à plusieurs développeur de travailler en parallèle sur des parties différentes d'un même modèle.
- Maintenant, cliquez droit sur le modèle TimeTracker que vous venez juste de créer et sélectionnez Nouvel Elément > Paquet. Un nouveau paquet est alors créé sous le modèle TimeTracker avec une boîte d'édition. Entrez-y org.andromda.timetracker comme nom pour ce paquet. AndroMDA fera correspondre à ce paquet un package Java avec le même nom. Attention: vérifiez que le nom de paquet est exactement org.andromda.timetracker, sans aucun espace devant ou derrière. Nous avons découvert que certains navigateurs introduisent un espace avant dans le nom de paquet si vous le copiez depuis cette page!
- Créez maintenant un paquet nommé « domain » sous « org.andromda.timetracker ». Nous créerons nos entités et les classes correspondantes dans ce paquet. À noter qu'AndroMDA n'impose absolument pas cette structure de paquets. Nous suggérons simplement cette organisation pour séparer les classes du domaine métier des autres classes comme les objets de valeurs, etc.
- Dans l'Arbre de Confinement sur la gauche, cliquez droit sur le paquet « domain » et sélectionnez « Nouveau Diagramme > Diagramme de Classes ». Une boîte de dialogue « Diagramme de Classes Spécification » apparait. Saisissez « Objets du Domaine » comme nom pour ce diagramme et cliquez sur OK. Le diagramme est créé et ouvert dans une nouvelle fenêtre.
- Dans la barre d'outils sur la gauche du diagramme de classes, cliquez sur l'icône « Classe » (sixième en partant du haut). Maintenant, cliquez n'importe où dans le diagramme. Une nouvelle classe est créée. Cette classe est automatiquement sélectionnée comme l'indiquent les quatre poignées aux coins. Si vous désélectionnez cette classe, il suffit de recliquer dessus pour la sélectionner à nouveau. Tapez maintenant « Person ». Ce mot est saisi comme étant le nom de la classe.
- Ajoutons de la documentation à la classe Person. C'est toujours une bonne idée de documenter votre modèle. La documentation ajoutée aux éléments de modèles comme les classes, les attributs et les opérations seront transférés dans les commentaires du code généré. Double-cliquez sur la classe Person pour afficher la boîte de dialogue « Classe Spécification ». Ajoutez la phrase suivante dans le champ « Documentation » et cliquez sur OK: « Cette classe représentation toute personne donc le temps doit être surveillé. »
- Maintenant, ajoutez le stéréotype « Entity » à la classe Person. Pour ce faire, cliquez droit sur la classe et sélectionnez « Editer stéréotype », puis cochez « Entity » et enfin cliquez sur « Appliquer ». La classe Person a maintenant le stéréotype Entity.
- Ajoutons maintenant un attribut username à Person. Cliquez droit sur la classe Person et sélectionnez « Insérer Nouvel Attribut ». Un nouvel attribut est inséré avec la spécification « -sans nom1 ». Remplacez cette spécification par celle-ci: « +username : String » (faites bien attention à effacer le signe moins devant le nom). N'appuyez pas sur Entrée après avoir saisi cet attribut, car cela créerait un autre attribut. Cliquez plutôt en dehors de la classe pour terminer la saisie de l'attribut. Notez bien que les attributs sont toujours générés comme des membres privés d'une classe. Toutefois les visibilités des getter et setter associés sont déterminés par la visibilité de la spécification d'attribut. Ici nous avons spécifié une visibilité publique (en utilisant le signe plus) et donc l'accesseur et le mutateur de username seront publics.
- Ajoutez maintenant deux attributs supplémentaires appelés firstName et lastName à la classe Person. Affectez-leur le type String.
- Assurez-vous que votre diagramme correspond exactement à celui affiché ci-dessus. C'est normal si un compartiment opérations vide apparait dans votre classe. Il peut être caché très facilement.
- Sauvegardez votre modèle TimeTracker en sélectionnant Fichier > Sauvegarder.
Félicitations! Vous venez de modéliser l'entité Person pour l'application TimeTracker. Nous sommes maintenant prêts à générer du code. Passez maintenant à la section 3.1.2.
III-A-2. Génération de code pour l'entité Person▲
Suivez les étapes ci-dessous pour générer le code.
- Ouvrez une fenêtre de commandes et rendez-vous dans le répertoire C:\timetracker.
- Exécutez la commande « maven -o install ». Comme nous en avons parlé plus tôt, l'option -o demande à Maven de s'exécuter en mode « hors-ligne », en utilisant les librairies disponibles dans le référentiel local. Cela permet à la construction de s'exécuter beaucoup plus rapidement. Assurez-vous que vous obtenez un message BUILD SUCCESSFUL quand Maven termine son exécution.
Ouvrez le dossier C:\timetracker\core\target\src\org\andromda\timetracker\domain dans l'explorateur Windows. Vous pouvez constater qu'il y a 6 fichiers générés dans ce dossier, résultant de la création de la seule entité Person dans le modèle de l'application.
- Person.java: Il s'agit de la classe abstraite de base qui implémente l'entité Person. Elle contient les 3 attributs du modèle ainsi que leurs accesseurs et mutateurs respectifs. AndroMDA ajoute automatiquement un attribut « id » qui représente l'identificateur unique pour les instances de Person dans la base de données. De plus, AndroMDA génère les méthodes equals() et hashCode() pour l'entité. Notez que la classe Person est abstraite, et que donc on ne peut pas l'instancier. La classe PersonImpl décrite ci-dessous est une classe concrète qui hérite de Person. Elle peut être instanciée en utilisant les méthodes de fabrique de la classe Person.
- PersonImpl.java: Comment mentionné ci-dessus, PersonImpl est une implémentation concrète de la class Person. Elle est destinée à contenir tout le code personnalisé que les développeurs aimeraient ajouter à l'entité Person.
- PersonDao.java: Pour n'importe quelle entité, les objets d'accès aux données sont générés comme un trio de classes: une interface, une classe de base abstraite et une implémentation concrète. PersonDao est l'interface pour l'objet d'accès aux données de l'entité Person. Elle spécifie les méthodes CRUD pour le DAO.
- PersonDaoBase.java: PersonDaoBase implémente toutes les méthodes CRUD spécifiées dans l'interface PersonDao.
- PersonDaoImpl.java: PersonDaoImpl est une extension concrète de la classe PersonDaoBase. Elle doit contenir tout le code personnalisé que les développeurs pourraient vouloir ajouter à l'object d'accès aux données de l'entité Person. C'est notamment dans cette classe que figureront plus tard les méthodes de transformation entre entité et objets de valeurs.
- Person.hbm.xml: Il s'agit du fichier de mapping d'Hibernate qui fait correspondre l'entité Person à sa représentation dans une base de données relationnelle.
Il est important de remarquer que ces 6 fichiers sont générés dans le dossier target du projet core. Le dossier target n'est destiné qu'aux fichiers générés automatiquement. Aucun des fichiers dans ce dossier ne devrait être modifié manuellement, car la génération de code les écrasera complètement, annulant du même coup toutes vos modifications. Il est également recommandé de ne pas intégrer ce code dans votre gestionnaire de versions. Laissez plutôt votre script de construction le générer à la volée.
À présent, vous devez vous demander où ajouter du code personnalisé. Nous avons évoqué plus haut la possibilité pour les développeurs d'ajouter du code personnalisé dans PersonImpl.java et dans PersonDaoImpl.java. Mais pourquoi ces classes sont-elles générées dans le dossier target alors? Et bien cela vient du fait qu'AndroMDA est assez intelligent pour remarquer que vous ne lui avez donné aucune indication comme quoi vous vouliez écrire du code personnalisé. Aussi longtemps que cela sera vrai, il continuera à générer les classes d'implémentation dans le dossier target. Néanmoins, aussitôt que vous indiquerez à AndroMDA que vous désirez écrire du code personnalisé dans ces classes, il les génèrera dans le dossier src du projet core. Vous serez alors libre de modifier les classes d'implémentation et d'y ajouter n'importe quel code. À noter que dans ce cas, elles ne seront générées qu'une seule fois pour vous servir de base de travail. Plus tard dans ce tutoriel, nous vous montrerons comment écrire du code personnalisé.
III-A-3. Création du schéma pour l'entité Person▲
En plus des classes d'entités et de DAO évoquées ci-dessus, AndroMDA génère automatiquement le script DDL pour créer les tables dans votre base de données. Ce script DDL est situé dans C:\timetracker\core\target\schema-create.sql. Ouvrez ce fichier et vérifiez son contenu. Vous devriez y voir le code SQL nécessaire pour créer la table PERSON. Suivez les étapes ci-dessous pour créer cette table dans votre base de données.
Notez que PostgreSQL n'aime pas trop la première instruction dans schema-create.sql (drop sequence hibernate_sequence). Il est conseillé de la commenter pour ce système.
- Ouvrez une fenêtre de commandes et rendez-vous dans le dossier C:\timetracker.
- Exécutez la commande « maven -o create-schema », qui va créer la table PERSON dans votre base de données. Utilisez vos outils de gestion de base de données pour vérifier que la table a effectivement été créée.
III-B. L'objet de valeur PersonVO▲
III-B-1. Modélisation de PersonVO▲
Dans cette section nous allons créer l'objet de valeur PersonVO. Nous allons faire simple et garder une correspondance exacte entre l'objet de valeur et l'entité Person. Dans la suite de ce tutoriel, nous modéliserons des objets de valeur plus complexes qui correspondront à plusieurs entités.
Notez que nous avons ajouté une dépendance depuis Person vers PersonVO. Cette dépendance va générer du code utilitaire dans PersonDAO pour permettre la transformation entre entités Person et objet de valeur PersonVO. De plus, nous avons modélisé un nouveau type appelé PersonVO[]. Ce type sera utilisé comme valeur de retour dans nos méthodes de service.
Vous allez maintenant ajouter PersonVO et PersonVO[] à votre modèle. Pour ce faire, suivez les instructions du paragraphe correspondant à votre outil de modélisation.
MagicDraw UML▲
Cette page présente la marche à suivre pour créer PersonVO en utilisant MagicDraw. Le modèle apparait ci-dessous pour référence.
- Dans le modèle TimeTracker, créez un paquet appelé « vo » sous « org.andromda.timetracker ». Nous allons créer tous nos objets de valeur dans ce paquet.
- Dans l'arbre de confinement à gauche, cliquez droit sur le paquet « vo » et sélectionnez Nouveau Diagramme > Digramme de Classes. Entrez « Objets de Valeur » comme nom pour ce diagramme et cliquez sur OK. Le diagramme est créé et ouvert dans un nouvel onglet.
- Depuis l'arbre de confinement sur la gauche, faites glisser la classe Person vers le diagramme. Attention, il est important de réutiliser la classe Person existante dans le paquet « domain ». NE CRÉEZ PAS UNE NOUVELLE CLASSE PERSON dans ce diagramme, faute de quoi vous créeriez une nouvelle classe Person dans le paquet vo, ce qui n'est pas notre intention. Tout ce dont nous avons besoin, c'est une référence vers la classe Person du paquet « domain ».
- Ajoutez une nouvelle classe au diagramme et appelez-la PersonVO.
- Ajoutez le stéréotype « ValueObject » à PersonVO.
- Ajoutez 4 attributs à PersonVO comme indiqué dans le diagramme ci-dessus.
- Sélectionnez l'icône « Dépendance » dans la barre d'outils latérale gauche (12e icône en partant du haut) ou appuyez sur la lettre « D » de votre clavier. Maintenant cliquez gauche sur la classe Person et faites glisser la flèche jusqu'à la classe PersonVO puis validez la destination de la flèche en cliquant gauche à nouveau lorsque la classe PersonVO est encadrée de bleu. Une relation de dépendance est alors créée entre les deux classes.
- Ajoutez une nouvelle classe au diagramme et appelez-la PersonVO[].
- Assurez-vous que votre diagramme correspond à celui qui apparait ci-dessus.
- Enregistrez le modèle au moyen du raccourci clavier Ctrl+S
Nous sommes maintenant prêts à générer le code pour l'objet de valeur PersonVO. Pour cela, rendez-vous à la section 3.2.2.
III-B-2. Génération de code pour l'objet de valeur PersonVO▲
Suivez les étapes ci-dessous pour générer le code.
- Ouvrez une fenêtre de commandes et rendez-vous dans le répertoire C:\timetracker.
- Exécutez la commande « maven -o clean install ». La cible « clean » nous permet de nettoyer les dossiers target avant de régénérer le code. Assurez-vous que vous obtenez un message BUILD SUCCESSFUL quand Maven termine son exécution.
Ouvrez le dossier C:\timetracker\common\target\src\org\andromda\timetracker\vo dans l'explorateur Windows. Vous pouvez constater que la classe PersonVO est générée ici. Ouvrez-la et vérifiez son contenu.
Ouvrez maintenant le dossier C:\timetracker-magicdraw\core\target\src\org\andromda\timetracker\domain dans l'explorateur Windows. Vous vous souvenez que ce dossier contenait 6 fichiers générés automatiquement après la dernière construction. Cette fois-ci il n'y en a que 5, PersonDaoImpl.java manque à l'appel! Mais que se passe-t-il ? En fait, cette classe a cette fois été générée dans le dossier src au lieu du dossier target, parce que nous avons ajouté une dépendance depuis Person vers PersonVO. Cette dépendance est une indication pour AndroMDA afin qu'il ajoute du code utilitaire dans PersonDaoBase.java et PersonDaoImpl.java pour la conversion entre Person et PersonVO. La plus grande partie de ce code se trouve dans la classe autogénérée PersonDaoBase. Cependant, si l'on désire modifier le mécanisme de traduction par défaut, il est possible de surcharger ces méthodes dans la classe PersonDaoImpl. De plus, cette dernière est déplacée dans l'arbre des sources à un endroit où elle peut être modifiée en toute sécurité (voir C:\timetracker\core\src\java\org\andromda\timetracker\domain). Vérifiez les classes PersonDaoBase et PersonDaoImpl pour comprendre ce mécanisme de conversion.
Maintenant que nous avons modélisé l'objet de valeur PersonVO, il est temps de créer un service qui l'utilise: PeopleService.
III-C. Le service PeopleService▲
III-C-1. Modélisation du service PeopleService▲
Dans cette section nous allons créer le service PeopleService. Ce service expose 3 méthodes pour gérer l'information à propos des personnes travaillant chez Northwind.
Nous allons également modéliser une dépendance de PeopleSevice vers l'entité Person afin de s'assurer que le service a accès a PersonDao.
Pour ajouter le service à votre modèle, il vous suffit de suivre les instructions du paragraphe correspondant à votre outil de modélisation.
MagicDraw▲
Ce paragraphe fournit les instructions nécessaires à la modélisation du service PeopleService avec MagicDraw. Le modèle figure ci-dessous pour référence.
- Dans le modèle TimeTracker, créez un paquet appelé « service » sous org.andromda.timetracker. Nous allons créer tous nos services dans ce paquet.
- Dans l'arbre de confinement sur la gauche, cliquez droit sur le paquet « service » et sélectionnez Nouveau Diagramme > Diagramme de Classe. Saisissez « Services » comme nom pour ce diagramme et cliquez sur OK. Le diagramme est créé et ouvert dans un nouvel onglet.
- Ajoutez une nouvelle classe dans le diagramme et appelez-la PeopleService.
- Ajoutez le stéréotype <<Service>> à la classe PeopleService.
- Ajoutez trois méthodes à la classe PeopleService comme dans le diagramme ci-dessus. Faites attention au type de retour de la dernière méthode. Il ne sera pas interprété comme PersonVO[] si vous l'entrez dans le diagramme. Double-cliquez sur la méthode et choisissez le bon type dans la boîte de dialogue de spécification de l'opération. Dans cette boîte de dialogue, faites également attention à bien vider le champ « Modificateur du type de retour ».
- Depuis l'arbre de confinement à gauche, faites glisser la classe Person vers le diagramme.
- Créez une dépendance depuis PeoplePerson vers Person (pour indiquer que le service PeopleService va manipuler des Person).
- Assurez-vous que votre diagramme correspond à celui qui figure ci-dessus.
- Sauvegardez votre modèle.
Nous avons déjà ajouté des services, des objets de valeurs, et des entités à notre modèle. Et il arrivera très fréquemment que ces différents éléments se côtoient dans les mêmes diagrammes avec pour seul moyen de les distinguer leur stéréotype. Or dans MagicDraw, il est possible de modifier la couleur des éléments. Il peut donc être très utile de se choisir une couleur standard pour chaque stéréotype. C'est une perte de temps relative à la modélisation, d'autant qu'on aimerait pouvoir faire cela automatiquement, mais à l'usage, la lisibilité des diagrammes y gagne énormément. Pour modifier la couleur de remplissage d'une classe dans MagicDraw, ou plus précisément du symbole qui représente une classe, il vous suffit de cliquer droit sur l'élément puis de sélectionner « Éditer symbole… ». Vous avez alors accès à la boîte de dialogue des propriétés du symbole et vous pouvez modifier tout un tas de choses donc la couleur de remplissage. Autre astuce, dans les diagrammes où vous n'avez pas besoin de voir les membres des entités, ce qui est souvent le cas dans les diagrammes qui se concentrent sur les services par exemple, vous pouvez cacher à la fois les membres et les opérations de l'entité pour la faire ressembler au symbole que vous pouvez voir plus haut. Cela vous permet également d'améliorer la lisibilité de vos diagrammes.
Nous sommes maintenant prêts à générer le code pour PeopleService. Pour ce faire, rendez-vous à la section 3.3.2.
III-C-2. Génération de code pour le service PeopleService▲
Suivez les étapes ci-dessous pour générer le code.
- Ouvrez une fenêtre de commandes et rendez-vous dans le répertoire C:\timetracker .
- Exécutez la commande « maven -o clean install ». Assurez-vous que vous obtenez un message BUILD SUCCESSFUL quand Maven termine son exécution.
À ce stade, après l'exécution de maven, j'ai personnellement rencontré un problème qui aboutissait à un message BUILD FAILED. Le problème, c'était que l'interface PeopleService.java n'était pas générée du tout à cause d'une ligne manquante dans le fichier de configuration d'AndroMDA généré par le plugin AndroMDApp. Si vous vous trouvez dans une situation similaire, vérifiez que la ligne suivante figure bien dans le namespace spring, dans le fichier C:\timetracker\mda\conf\andromda.xml: <property name=« service-interfaces »>${maven.andromda.common.generated.dir}</property>
Tout comme pour les objets d'accès aux données, un service est généré sous la forme d'un trio de classes: une interface, une classe abstraite de base et une implémentation concrète. Voici les 3 classes générées pour PeopleService:
- PeopleService.java : PeopleService est l'interface qui spécifie les méthodes de service. Puisque les applications clientes ont besoin de cette interface comme de son implémentation, elle est générée dans la branche target du projet « common ».
- PeopleServiceBase.java : PeopleServiceBase implémente les méthodes spécifiées par l'interface PeopleService. Ces méthodes servent avant tout à effectuer quelques vérifications sur les paramètres, après quoi elles délèguent la véritable fonctionnalité métier à des méthodes « handle ». Les méthodes « handle » doivent être implémentées manuellement dans la classe PeopleServiceImpl. PeopleServiceBase contient également les références aux DAO dont le service a besoin. PeopleServiceBase est générée dans la branche target du projet core.
- PeopleServiceImpl.java : PeopleServiceImpl est une extension concrète de la classe PeopleServiceBase. C'est dans cette classe que les développeurs doivent coder la logique métier pour les méthodes de service. PeopleServiceImpl.java est générée dans la branche src du projet core.
III-C-3. Implémentation des méthodes du service PeopleService▲
Cette section vous indique comment implémenter les 3 méthodes « handle » dans PeopleServiceImpl. Ouvrez le fichier C:\timetracker-argouml\core\src\java\org\andromda\timetracker\service\PeopleServiceImpl.java et suivez les instructions ci-dessous.
handleCreatePerson()▲
Cette méthode de service prend en entrée un PersonVO et crée l'entité Person correspondante dans la base de données. Elle retourne l'identificateur de la personne nouvellement créée. Remplissez l'implémentation de cette méthode comme indiqué ci-dessous.
protected
java.lang.Long handleCreatePerson
(
org.andromda.timetracker.vo.PersonVO personVO)
throws
java.lang.Exception
{
Person person =
Person.Factory.newInstance
(
);
getPersonDao
(
).personVOToEntity
(
personVO, person, true
);
getPersonDao
(
).create
(
person);
return
person.getId
(
);
}
Nous créons d'abord une nouvelle instance de Person en mémoire en utilisant la fabrique de Person. Nous initialisons ensuite la Person avec les données de l'objet de valeur -- l'implémentation par défaut de personVOToEntity() fonctionne parfaitement pour cela. Ensuite, nous demandons à PersonDao de persister la Person dans la base de données. Enfin nous retournons l'identificateur de la personne nouvellement créée à l'appelant.
Attention, cette implémentation est propre à la version 3.2 d'AndroMDA. J'ai moi-même été très surpris par cet algorithme au premier coup d'œil. Mais force est de constater que la nouvelle implémentation par défaut des méthodes de transformation (il n'y en avait aucune auparavant) rend les choses beaucoup plus propres. Je me permets enfin d'insister sur l'importance de passer par la fabrique de Person, et non pas d'appeler directement le constructeur de PersonImpl, ce qui serait contraire aux principes du Design Pattern implémenté par AndroMDA.
handleGetPerson()▲
Cette méthode de service prend en entrée un identificateur de Person et retourne l'objet de valeur PersonVO correspondant. Elle est implémentée en utilisant un appel direct au DAO qui retrouve la Person, le transforme en PersonVO et le retourne.
protected
org.andromda.timetracker.vo.PersonVO handleGetPerson
(
java.lang.Long id)
throws
java.lang.Exception
{
return
(
PersonVO) getPersonDao
(
).load
(
PersonDao.TRANSFORM_PERSONVO, id);
}
handleGetAllPeople()▲
Cette méthode de service retourne toutes les personnes dans la base de données de l'application comme un tableau d'instances de PersonVO. Elle est implémentée grâce à un simple appel à PersonDao.loadAll(), qui retourne une collection d'objets PersonVO. Cette collection est transformée en un tableau et retournée à l'appelant.
protected
org.andromda.timetracker.vo.PersonVO[] handleGetAllPeople
(
)
throws
java.lang.Exception {
Collection people =
getPersonDao
(
).loadAll
(
PersonDao.TRANSFORM_PERSONVO);
return
(
PersonVO[]) people.toArray
(
new
PersonVO[people.size
(
)]);
}
Imports▲
Ajoutez les instructions d'importation requises au fichier après l'instruction package comme indiqué ci-dessous.
package
org.andromda.timetracker.service;
import
org.andromda.timetracker.domain.Person;
import
org.andromda.timetracker.domain.PersonDao;
import
org.andromda.timetracker.vo.PersonVO;
import
java.util.Collection;
Après avoir implémenté le code qui figure ci-dessus, enregistrez le fichier et compilez l'application.
- Ouvrez une fenêtre de commandes et rendez-vous dans le répertoire C:\timetracker .
- Exécutez la commande maven -o install. Assurez-vous d'obtenir un message BUILD SUCCESSFUL.
Est-ce que vous commencez à sentir la puissance de la chose ? Est-ce que vous commencez à vous émerveiller devant la magnificence de l'outil qui vous génère un squelette en implémentant des Design Patterns bien propres et vous laissant uniquement le code métier à produire ? Personnellement, je n'arrête jamais d'être épaté :oP
III-D. Création de l'application console▲
Dans cette section, nous allons essayer le service PeopleService en utilisant une simple application en ligne de commandes.
- Téléchargez le projet d'application (http://galaxy.andromda.org/docs/getting-started/java/resources/sample-code/timetracker/console1.zip) console et dézippez-la dans le dossier timetracker (C:\timetracker). Vous obtenez alors un nouveau répertoire appelé C:\timetracker\console. Ce répertoire contient trois fichiers - project.xml, maven.xml (les fichiers de projet de Maven) et TimeTrackerConsole.java (l'application console, dans src\java\org\andromda\timetracker\console).
- Ajoutez deux nouvelles cibles dans C:\timetracker\maven.xml: ces cibles vous permettent de construire et d'exécuter l'application console depuis le répertoire C:\timetracker. Les deux nouvelles cibles sont ttconsole et run. Copiez-collez ces cibles après la cible mda comme indiqué ci-dessous:
<!-- ==================================================================
Builds the Console component
================================================================== -->
<goal
name
=
"ttconsole"
>
<
maven
:
maven
descriptor
=
"console/project.xml"
goals
=
"jar:install"
/>
</goal>
<!-- ==================================================================
Runs the Console component
================================================================== -->
<goal
name
=
"run"
>
<
maven
:
maven
descriptor
=
"console/project.xml"
goals
=
"run"
/>
</goal>
- Vérifiez l'application console dans TimeTrackerConsole.java. Les méthodes clés de cette application sont reproduites ci-dessous:
public
static
void
main
(
String[] args) {
// Get services
serviceLocator =
ServiceLocator.instance
(
);
peopleService =
serviceLocator.getPeopleService
(
);
// Create people
PersonVO naresh =
createPerson
(
"nbhatia"
, "Naresh"
, "Bhatia"
);
PersonVO louis =
createPerson
(
"lcoude"
, "Louis"
, "Coude"
);
PersonVO john =
createPerson
(
"jsmith"
, "John"
, "Smith"
);
// Fetch and show all objects created above
PersonVO[] people =
peopleService.getAllPeople
(
);
showPeople
(
people);
}
private
static
PersonVO createPerson
(
String username, String firstName, String lastName) {
PersonVO person =
new
PersonVO
(
null
, username, firstName, lastName);
person.setId
(
peopleService.createPerson
(
person));
System.out.println
(
"Person "
+
person.getId
(
) +
" created - "
+
person.getUsername
(
));
return
person;
}
Comme vous pouvez le voir, la logique de l'application console est très simple. Nous avons d'abord besoin d'obtenir une référence à PeopleService, ce que nous faisons en utilisant le ServiceLocator, une classe utilitaire générée par AndroMDA qui utilise le framework Spring pour localiser les services. Ensuite, nous créons trois personnes dans la base de données en utilisant PeopleService. Pour finir, nous chargeons toutes les personnes qui existent dans la base de données, toujours en utilisant PeopleService, et nous les affichons.
- Construisez l'application console en exécutant la cible ttconsole comme suit: maven -o ttconsole.
- Exécutez l'application en exécutant la cible run comme suit: maven -o run. La sortie de la console figure ci-dessous.
C:/timetracker>maven -o run
...
[java] Person 1 created - nbhatia
[java] Person 2 created - lcoude
[java] Person 3 created - jsmith
[java] People:
[java] 1: nbhatia - Naresh Bhatia
[java] 2: lcoude - Louis Coude
[java] 3: jsmith - John Smith
[java]
BUILD SUCCESSFUL
Total time: 8 seconds
Finished at: Thu Apr 20 21:57:16 CEST 2006
C:/timetracker>
- Effacez le schéma de base de données en préparation des prochaines sections du tutoriel où nous allons ajouter plus de tables à notre base de données timetracker. Pour ce faire, exécutez la cible drop-schema comme suit: maven -o drop-schema.
III-E. Bilan intermédiaire▲
À ce stade, vous venez de terminer votre première application fonctionnelle avec AndroMDA. La fonctionnalité est assez simple, mais vous allez voir dans la suite de cette série que toute la puissance d'AndroMDA réside justement dans l'évolutivité qu'il permet. En fait, nous venons de terminer le premier cycle d'un processus de développement itératif qui va nous mener petit à petit vers une application complète.
Sur un plan méthodologique justement, l'expérience montre que la démarche MDA s'intègre parfaitement dans un processus de développement à base de cycles itératifs cours :
- on modélise une fonctionnalité précise ;
- le modèle est validé et compilé par AndroMDA pour générer le code générique de cette fonctionnalité ;
- pour faire les choses correctement, c'est MAINTENANT que l'on écrit les tests unitaires dans C:\timetracker\core\src\test ;
- On « bouche les trous » laissés par AndroMDA (que l'on repère facilement grâce aux commentaires TODO).
- on compile l'application et on corrige les éventuelles erreurs ;
- on utilise éventuellement l'application console pour faire des tests fonctionnels ;
- on recommence le cycle au départ.
Typiquement, ce cycle dure de l'ordre de 1 à plusieurs jours et permet de construire l'application par agrégation. Cette démarche se rapproche beaucoup d'une méthodologie de développement qui gagne en popularité: le processus unifié.
Dans les prochaines parties, nous allons faire évoluer cette application pour explorer les nombreuses autres possibilités d'AndroMDA. Eh oui : ce n'est que le début !