Framework Orienté objet

3,007
-1

Published on

Ce document présente une revue du concept de framework orienté objet, ainsi que de ses applications.

Published in: Technology, Education
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,007
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Framework Orienté objet

  1. 1. GESTION DE PROJETS ORIENTES OBJETS LES FRAMEWORKS S Y L V A I N D E S B U R E A U X S É B A S T I E N J O B I N J I M M Y P E R R O N P A T R I C K P E L L E T I E R
  2. 2. TABLE DES MATIÈRES Introduction..............................................................................................................4 1 Frameworks orientés-objets et leur développement..............................................5 2 Expérience d’application des Frameworks.........................................................52 3 Framework JAFIMA pour les systèmes agent....................................................80 Conclusion............................................................................................................110
  3. 3. TABLE DES FIGURES Figure 1-1 : La différence de contrôle entre un framework et une librairie [Landin, Niklasson 95]..............................................................................................8 Figure 1-2 : Frameworks vs Applications OO traditionnelles : la réutilisation en tête............................................................................................................................11 Figure 1-3 : Le processus de développement d'un framework.............................17 Figure 1-4 : Développement de logiciel traditionnel.............................................19 Figure 1-5 : Plan de développement du Framework.............................................26 Figure 1-6 : processus de développement des exigences.......................................27 Figure 1-7 : Les exigences et la phase d'analyse avec leurs produits..................29 Figure 1-8 : Plan de développement du Framework.............................................32 Figure 1-9 : la phase design et ses sous-processus................................................33 Figure 1-10 : le design pattern « stratégie » appliqué dans le framework pour les jeux de dés................................................................................................................34 Figure 1-11 : Utilisation d’un inline explicite.......................................................40 Figure 1-12 : La différence entre un case et le polymorphisme...........................47 Figure 2-13 : Cycle de réutilisation d’un framework............................................55 Figure 2-14 : Description du problème du premier motif de Hotdraw.................64 Figure 2-15 : Partie d’un motif du framework HotDraw [Joh, 1992]..................65 Figure 2-16 : Interface d’un template FDL...........................................................67 Figure 2-17: Introduction générale du framework...............................................70 Figure 2-18 : Présentation des concepts du module..............................................71 Figure 2-19 : Présentation techniques du module................................................73 Figure 2-20 : Description d’une classe du framework..........................................73 Figure 2-21 : Présentation des tutoriels.................................................................74 Figure 2-22 : découpage des diagrammes.............................................................75 Figure 2-23 : Architecture des classes d’affichage..............................................76 Figure 2-24 : diagramme d’objets de JTGame......................................................77 Figure 3-25 : Modèle architectural en couche d’agent.........................................83 Figure 3-26 : Diagramme de classes de la couche senseur.................................85 2
  4. 4. Figure 3-27 : Diagramme de séquence montrant l’acquisition d’une croyance par un senseur.........................................................................................................86 Figure 3-28 : Diagramme de classes de la couche des croyances........................87 Figure 3-29 : Diagramme de séquence pour la mise à jour d’une croyance primitive...................................................................................................................88 Figure 3-30 : Diagramme de séquence pour la mise à jour d’une croyance composée..................................................................................................................88 Figure 3-31 : Diagramme de classes de la couche de raisonnement....................89 Figure 3-32 : Utilisation du pattern « Command » dans la couche d’action.......90 Figure 3-33 : Le pattern « Abstract Factory » qui instancie les « ConcretePlans » ..................................................................................................................................91 Figure 3-34 : Utilisation du pattern « Decorator » dans la couche d’action.......92 Figure 3-35 : Le pattern « Future » et le pattern « Observer » dans la couche d’action....................................................................................................................94 Figure 3-36 : L’utilisation du pattern « Active Object » dans la couche d’action ..................................................................................................................................95 Figure 3-37 : Diagramme de séquence pour l’exécution d’un plan.....................96 Figure 3-38 : Le pattern « Synchronized Singleton »...........................................98 Figure 3-39 : Le pattern « Decorator » dans la couche de collaboration............99 Figure 3-40 : Design de l’interface de collaboration..........................................101 Figure 3-41 : Design de l’interface de représentation de la collaboration.........102 Figure 3-42 : Réception de message dans la couche de collaboration...............102 Figure 3-43 : Diagramme de séquence montrant l’assignation d’un message entrant à un « CollabThread »..............................................................................103 Figure 3-44 : Diagramme de séquence montrant comment un message sortant est stocké dans un « MesgHolder » et passé à un autre agent.............................104 Figure 3-45 : Architecture de la couche de mobilité...........................................105 Figure 3-46 : La création des différentes couche de l’agent par le pattern « Agent Builder »......................................................................................................106 Figure 3-47 : Design du pattern « Layer Linker »..............................................107 3
  5. 5. INTRODUCTION 4
  6. 6. 1 FRAMEWORKS ORIENTÉS-OBJETS ET LEUR DÉVELOPPEMENT 5
  7. 7. 1.1 FRAMEWORKS ORIENTÉS-OBJETS Toutes les personnes qui s’intéressent de près ou de loin à la programmation Orientée Objets ont déjà entendu parler d’un concept qui lui est souvent associé : la réutilisation. Les frameworks ont vu le jour dans un but de maximisation de la réutilisation. Nous allons donc ici nous intéresser à ce qu’est un framework, puis à la façon de développer des frameworks. 1.1.1 QU’EST-CE QU’UN FRAMEWORK ? Pour mieux comprendre ce que peut être un framework, regardons comment les spécialistes les définissent : ainsi, d’après Johnson, un framework est défini comme suit : “A framework is a set of classes that embodies an abstract design for solutions to a family of related problems.” [Johnson, Foote 91] et “A framework is a set of objects that collaborate to carry out a set of responsibilities for an application subsystem domain.”. [Johnson, Russo 91] Nous pourrions traduire ceci de cette façon : « Un framework est un ensemble de classes qui englobe un design abstrait en guise de solutions à une famille de problèmes similaires. » et « Un framework est un ensemble d’objets qui collaborent pour distribuer un ensemble de responsabilités d'un domaine de sous-système d'application ». On peut donc dire qu’un framework orienté objet est une architecture définie pour permettre au maximum la réutilisation de code dans un domaine donné, ou encore pour un pôle d’applications données. C’est à dire que chaque framework sera construit 6
  8. 8. pour un certain domaine de travail ou encore pour une certaine utilisation plus ou moins spécifique. De plus, un framework est composé de classes concrètes et abstraites. Les frameworks sont créés afin de répondre à des besoins spécifiques, et ce en englobant des classes utiles à ces applications. On pourrait donc objecter que les définitions que l’on vient de donner ainsi que les explications adjacentes correspondent exactement à l’idée que l’on se fait des librairies… Il est spécifié dans [Johnson, Foote 91] que les frameworks permettent aussi de réutiliser les implémentations (comme les librairies en fait), mais que ceci est moins important que la réutilisation des interfaces internes d’un système ainsi que la façon dont ses fonctions sont divisées entre ses composants. Et les frameworks permettent tout ceci. Lors d’utilisation de librairies, le développeur fait appel aux classes existantes de ces dernières, alors que pour les frameworks, ce sont les classes internes aux frameworks qui appellent des classes que le développeur doit personnaliser en fonction de son application, ce qui revient à dire que, contrairement aux librairies, le framework va appeler des classes spécialisées : 7
  9. 9. Figure 1-1 : La différence de contrôle entre un framework et une librairie [Landin, Niklasson 95] Pour de plus amples comparaisons entre les frameworks et d’autres concepts tels que les patrons OO (« Object-Oriented Design Patterns »), les patrons de langage (« Language Patterns »), etc., nous vous renvoyons à [Mattsson 96]. Il est aussi précisé que les liaisons dynamiques permettent aux frameworks de traiter un objet sans regarder son implémentation. En fait, pour préciser comment mieux comprendre ce qui a été dit précédemment, nous pourrions dire qu’un développeur dérive une nouvelle classe à partir de la classe abstraite fournie par le framework. En ce faisant, il spécialise le code pour son application tout en suivant le patron fourni par la super classe abstraite contenue dans le framework. On dit parfois qu’un framework fournit une base guidée par l’architecture (aussi appelée boite blanche ou focalisée sur l’héritage) avec une couche supplémentaire guidée par les données (ou boite noire, ou focalisée sur la composition). Cela signifie que le développeur utilise les fonctionnalités fournies avec le framework en créant une instance d’une classe du framework et en appelant ses fonctions membres (on a à faire ici à de la focalisation sur la composition), et qu’il étend et modifie les fonctionnalités en dérivant de nouvelles classes des classes existantes, ou encore en redéfinissant des fonctions membres (ce qui est ici de la focalisation sur l’héritage). 8
  10. 10. A noter que lorsque l’on désirera développer des applications à partir de frameworks, il y aura des librairies de sous-classes à choisir, et la personnalisation se fera alors de manière incrémentale par composition (c’est à dire que l’on ajoutera au fur et à mesure des librairies au choix que l’on personnalisera). Par contre, si les applications sont développées uniquement par composition, il n’y aura pas besoin de coder et/ou de tester notre application (on ne fait que récupérer des composants déjà testés et codés), et on gagnera ainsi énormément de temps. M. Taligent a classé les frameworks aussi bien par leur structure interne que par leur domaine d’application [Taligent 94a]. Voici ci-après les différentes catégories qu’il a dégagées : • Les frameworks de support (« support frameworks ») : Ils fournissent des services au niveau système, comme par exemple l’accès aux fichiers, le support de calcul distribué, ou encore les pilotes matériels. Les développeurs d’application utilisent habituellement les frameworks de support directement, ou utilisent des modifications apportées par des constructeurs de matériel. Toutefois, même les frameworks de support peuvent être personnalisés, comme par exemple lorsque l’on développe un nouveau système de fichier, ou un nouveau pilote de matériel. • Les frameworks d’application (« Application frameworks ») : Ils englobent une expertise applicable à une large variété de programmes. Les frameworks commerciaux d’applications de type « interface graphique usagers » (GUI) actuels, qui supportent les fonctions standards requises par toutes les applications GUI, sont un type de framework d’application. • Les frameworks de domaine (« Domain frameworks ») : 9
  11. 11. Ils englobent l’expertise dans un domaine particulier, comme par exemple les frameworks multimédia, … Maintenant que nous avons défini les frameworks et passé en revue les différents types de frameworks cités dans la littérature, on peut se demander pourquoi utiliser des frameworks… 1.1.2 POURQUOI UTILISER DES FRAMEWORKS ? Nous avons succinctement abordé précédemment la raison d’être des frameworks, et ceci en rappelant la notion de réutilisation souvent recherchée en programmation, et plus particulièrement depuis l’avènement de la programmation Orientée Objets. Nous allons préciser un peu plus les raisons qui peuvent pousser à utiliser des frameworks. Pour ce faire, nous allons citer les divers avantages que peut avoir de la programmation à base de frameworks, mais nous donnerons aussi les désavantages liés à un tel choix. Tout d’abord, précisons que l’utilisation de frameworks bien conçus, bien documentés, permet la réutilisation à la fois de l’analyse, du design et du code. Un framework rend la réutilisation de l’analyse possible en décrivant les objets importants, les relations entre objets et de quelle façon des problèmes de grande taille peuvent être scindés en des problèmes de taille restreinte. Le design est quant à lui réutilisé dans la mesure où le design du framework lui-même contient des algorithmes abstraits et définit les interfaces, aussi bien que les contraintes qu’une application se doit de satisfaire. Le code est réutilisé puisqu’une classe concrète implantée par l’utilisateur peut hériter d’une super classe. [Johnson, Russo 91] [Mattsson 96] présente, en introduisant le développement des frameworks, la figure ci-dessous qui permet de mettre en relief la réutilisation permise par les frameworks, contrairement aux applications OO traditionnelles. On constate ici qu’en développant 10
  12. 12. des frameworks, on n’effectue qu’une seule fois les phases de développement de ceux- ci. En effet, on ne fait qu’une fois l’analyse du domaine et la conception du framework, puis on peut ensuite utiliser celui-ci dans de nombreuses applications. Si l’on avait opté pour une application OO traditionnelle, on devrait refaire les phases d’analyse du domaine et de conception du framework autant de fois qu’il y a d’applications… Autant dire que lors de l’utilisation de framework, on sauve énormément de temps puisque toute l’analyse est déjà faite… Figure 1-2 : Frameworks vs Applications OO traditionnelles : la réutilisation en tête Nous venons donc ici d’évoquer un des avantages des frameworks, mais ce n’est pas le seul... Nous allons donc voir ci-après les avantages principaux, mais aussi les inconvénients, des frameworks. 1.1.2.1 Avantages Les avantages des frameworks sont nombreux et variés. Nous allons ici passer en revue ceux que [Landin, Niklasson 95] dégagent de leurs recherches. 11
  13. 13. • Le temps réduit avant la mise en marché : Lorsque l’on écrit des applications avec des frameworks comme base, seul le code qui diffère des applications précédentes doit être écrit. Il est donc nécessaire d’écrire moins de code, ce qui mène à un temps de développement amoindri et donc un temps réduit avant la mise en marché, comme évoqué en introduction de ce chapitre lors de la présentation de la Figure 1 -2. • La maintenance : La maintenance de systèmes est très chère. Entre 60 et 85% du coût total du cycle de vie d’un gros système est passé sur la maintenance, et il y a donc de grosses possibilités d’économies en réduisant le besoin de maintenance [Meyers 88]. Quand on doit tenir à jour des applications se basant sur un même framework, seul le framework lui-même et le code qui diffère de entre chaque application (les spécialisations de méthode des classes du framework par exemple) qui doivent être mis à jour. Cela signifie en outre que les changements ne sont à faire qu’en un seul endroit, ce qui augmente la cohérence de l’application. Comparé à la maintenance de plusieurs systèmes différents, les économies réalisées avec l’utilisation de frameworks est non négligeable. • Les tests : Lorsque l’on réutilise un framework, on réutilise aussi les tests. Le framework que l’on utilise a déjà été testé et il n’y a donc pas besoin de refaire ces tests. Les seuls tests qui doivent être effectués sont les tests des nouveaux modules et les tests des interactions entre ces nouveaux modules et le framework, ainsi que les tests du système. Ainsi, il y a moins 12
  14. 14. de tests et de déboggage à effectuer. Bien sûr cela sous-entend que le framework est correct et que les tests du système vérifient que le framework est utilisé correctement. • Le niveau de confiance : Un framework pourrait, comme n’importe quel autre programme, contenir des erreurs et/ou bogues, mais comme le framework est réutilisé, il tend à se stabiliser et les nouvelles erreurs et nouveaux bogues seront alors moins fréquents. On pourrait comparer ce phénomène avec les logiciels « open source » qui voient des failles corrigées par nombre de gens et qui sont sans cesse mis à jour et maintenus. Ils gagnent à être reconnus au bout d’un certain temps lorsque très peu d’erreurs sont trouvées car la participation de tous a permis de stabiliser le produit. Ainsi, le fait de réutiliser des frameworks stables offre une plus grande confiance envers le système développé que d’écrire tout le code depuis rien. • Les standards : Un framework bien conçu d’après les standards de la compagnie permet une meilleure pratique. Quand on développe des applications depuis un framework, le framework impose des contraintes sur le code de l’application développée. Cela conduit à se conformer aux standards de la compagnie aussi bien qu’à acquérir une meilleure pratique de programmation. En fait, on pourrait résumer cela en disant qu’une compagnie peut imposer de bonnes pratiques de programmation pour ses employés (utiliser des noms de fonctions évocateurs, …) mais que ces derniers ne sont pas obligés de les suivre étant donné qu’ils rédigent leur code seul. Cependant, avec la présence d’un framework, le codeur est obligé de respecter la manière dont le framework a été conçu, étant donné 13
  15. 15. que ce dernier est la abs du développement et qu’il n’est pas question de le modifier. Ainsi, les bonnes pratiques de programmation se trouvent être suivies de manière involontaire. • Les frameworks englobent de l’expertise : La conception de bons logiciels dans un domaine particulier nécessite une connaissance de ce domaine, qui est acquise généralement seulement par expérience. Puisque les frameworks contiennent cette expertise, les problèmes sont résolus une seule fois et les règles de fonctionnement et de conception sont ensuite utilisables par tous. Cela permet en outre à une société de construire des programmes depuis des bases dont on sait qu’elles ont fonctionné par le passé. Les frameworks permettent aussi aux développeurs de se concentrer sur les solutions spécifiques à leur application et de se reposer sur le framework qui leur apporte des services consistants. Cela libère aussi les développeurs qui ne sont pas nécessairement experts du domaine, en ce sens qu’ils n’auront pas à étudier en profondeur les détails du domaine, qui sont inclus dans le framework et déjà développés. Tout ceci est possible car c’est le framework qui a le contrôle de l’application (cf. Figure 1 -1). Ce dernier procure le flot de contrôle pendant que le code du programmeur de l’application attend d’être appelé par le dit framework. Cela revient à dire que le développeur n’a pas à se soucier des détails du framework et qu’il n’aura qu’à se concentrer sur le domaine du problème. [Taligent 94b] • La consistance reconnue et la compatibilité : Les applications développées à partir d’un même framework ont une plus grande capacité à travailler ensemble. Elles sont aussi mieux intégrées du 14
  16. 16. point de vue de l’utilisateur, en ce sens qu’elles ont la même interface, ou alors une interface similaire. [Taligent 94b] 1.1.2.2 Les inconvénients En fait d’inconvénients, il est plus à même de parler de difficultés. Les composants et autres architectures ne deviennent pas réutilisables d’eux même. Ils doivent être conçus avec la réutilisation en tête, ou bien avoir été re-conçus dans un but de réutilisation. Ce temps supplémentaire de travail doit être vu comme un investissement sur le long terme. [Johnson, Foote 91] [Taligent 94a] Il est aussi plus difficile de concevoir un framework qu’une bibliothèque de composants, mais le profit potentiel lié à la réutilisation d’un framework est bien plus important que celui lié à la réutilisation d’un composant d’une bibliothèque de composants. La conception d’un framework est plus difficile car l’architecture est à concevoir, mais aussi les communications entre les composants internes du framework [Johnson, Foote 91] [Taligent 94a]. Lorsque l’on conçoit un composant d’une librairie de composants, nous n’avons pas à prendre de telles décisions. Afin de permettre le succès du développement du framework, il doit être soutenu par les processus et organisation de votre équipe. Il faut que tout le monde se rende compte que les bénéfices liés aux frameworks et à la réutilisation se font avec le temps, avec de multiples utilisations du framework. [Johnson, Foote 91] [Taligent 94a] Ainsi, si l’on a vu qu’il y a de nombreux avantages à utiliser les frameworks, nous avons aussi vu qu’il n’est pas forcément si simple de concevoir puis réaliser ces dits frameworks. Intéressons-nous désormais au développement des frameworks. 15
  17. 17. 1.2 LE DÉVELOPPEMENT DES FRAMEWORKS Pendant le développement d’un framework, les développeurs doivent essayer de réunir dans le framework le plus grand nombre possible de comportements communs entre les diverses applications. Nous allons présenter ici un processus permettant la construction d’un framework adéquat. Nous avons eu un aperçu des phases de développement d’un framework en Figure 1 -2 lors de la comparaison entre la réutilisation d’un framework et celle d’une application OO traditionnelle. En fait, le processus que nous allons expliquer est plus précis que cela : 16
  18. 18. Figure 1-3 : Le processus de développement d'un framework Ce processus est tiré de [Landin, Niklasson 95] et ne doit pas être considéré comme le seul processus efficace. Il existe d’autre processus, comme le développement basé sur l’expérience, l’utilisation de « Design Patterns », … Pour de plus amples renseignements sur ces autres processus, nous vous renvoyons à [Mattsson 96]. Remarquons cependant que le processus que nous allons étudier ici est considéré par [Mattsson 96] comme le processus général de développement des frameworks, en ce Analyse du domaine Exigences et phase d’analyse Design du framework Implémentation du Framework test Analyse de l’application Design de l’application Implémentation de l’application 17
  19. 19. sens qu’il réunit toutes les caractéristiques communes des processus existants, lesquels diffèrent de ce dernier de quelques détails. Nous allons expliquer plus en détails chacune des phases de ce processus dans la suite de ce chapitre. 1.2.1 L’ORGANISATION DU PROJET Avant de considérer plus en détail le processus de développement d’un framework, il faut savoir qu’il existe des étapes importantes pour la bonne réalisation d’un projet qui n’apparaissent pas dans le processus en lui-même. L’organisation du projet en fait partie. Nous allons au cours de ce chapitre donner une brève introduction sur les questions organisationnelles liées au développement de frameworks. Nous allons dans un premier temps regarder comment un produit de développement de framework devrait être traité en fonction des contraintes temporelles. Nous poursuivrons avec les difficultés liées à la répartition du travail entre divers groupes de travail fonctionnant en parallèle. Nous verrons ensuite quelques-unes des difficultés liées à l’adaptation des organisations au développement pour et avec la réutilisation. 1.2.1.1 Un investissement stratégique La responsabilité du développement d’un framework ne devrait pas se faire comme une organisation ordinaire de projets. La réutilisation d’un framework dépend de façon très importante d’interfaces bien définies et d’une bonne architecture, étant donné que des changements plus tardifs de ces interfaces et/ou architecture affecteraient toutes les applications dépendantes de ce framework. De ce fait, le développement d’un framework ne devrait pas être une partie critique d’un projet car l’équipe responsable de ce développement ne devrait en aucun cas faire des concessions sur le framework, 18
  20. 20. ce qui conduirait à de mauvaises architectures et des interfaces mal définies. On conçoit bien là qu’il est nécessaire de faire des frameworks complets et bien définis si l’on ne veut pas qu’ils aient été conçus pour rien, et que pour ce faire il faut donner à l’équipe responsable de sa réalisation les conditions nécessaires à cette réussite. Le développement d’un framework devrait être vu comme un investissement stratégique plus que comme un investissement opérationnel. Un framework bien développé sera un plus pour la compagnie, car quand il sera réutilisé diminuera les efforts de développement et fera gagner du temps pour les autres projets. La création d’un département ou d’une équipe responsable des développements stratégiques pourrait ainsi être un plus pour la société… 1.2.1.2 L’organisation du travail Figure 1-4 : Développement de logiciel traditionnel Dans le développement de logiciel traditionnel, le travail est fait, dans la mesure du possible, par de petites équipes de développement travaillant en parallèle, avec des interfaces bien définies (cf. Figure 1 -4). Chaque petite équipe travaille sur une partie bien définie du système et chaque interface du sous-système avec les autres parties a été définie au préalable, lors de phases d’étude précédentes. Un architecte Système garde à jour l’image globale du système. Une équipe de développement de framework ne devrait pas être plus grande qu’une équipe de développement de logiciels traditionnels. En effet, quand la taille d’une 19
  21. 21. équipe de développement de logiciel augmente, les communications augmentent et il est nécessaire de fournir plus d’efforts pour garder tout le monde informé. Il est aussi plus difficile de garder une image de la progression globale de l’équipe. Une équipe appropriée pour le développement de frameworks ne devrait pas excéder huit personnes. Il peut être judicieux de faire varier le nombre de membres de l’équipe en fonction de la phase de développement dans laquelle on se trouve. Il est par exemple important que l’équipe s’occupant de l’analyse du domaine incluse un ou deux experts du domaine. Dans la suite du processus de développement, la présence d’experts du domaine n’est plus utile mais le besoin d’experts du système augmente. Ceci devrait se ressentir dans la composition de l’équipe de développement. Le développement de frameworks introduit de nouveaux aspects lors de la division du travail. L’idée principale d’un framework est de réunir les généralités d’un domaine ou un ensemble d’applications d’un domaine. Trouver des généralités nécessite une bonne vue d’ensemble du domaine mais aussi du système. Cet aspect rend le partage du travail moins facile à effectuer. Il y aura donc un compromis à faire entre un délai plus court, quand on divise le travail tôt, et un framework avec une bonne architecture stable, quand on ne travaille pas en parallèle. Le travail devrait donc être séparé entre diverses équipes le plus tard possible dans le cycle de développement. Ainsi, la structure du framework et les interfaces publiques des classes du framework devraient être stabilisées avant de diviser le travail (conformément à ce que nous avons déjà dit à ce sujet), mais il n’est pas nécessaire d’avoir défini en détails les objets et les classes. 1.2.1.3 Les équipes de développement « pour » et « avec » la réutilisation On peut dire qu’il y a deux façons d’organiser l’équipe lors de la réutilisation de frameworks. La première est de laisser les mêmes personnes créer et réutiliser le 20
  22. 22. framework. La seconde est d’avoir des équipes de développement et de réutilisation différentes. Si on a l’intention de vendre le framework en dehors de la compagnie, le choix de l’organisation de réutilisation est limité… Cependant, [Landin, Niklasson 95] pensent que la plupart des compagnies vont réutiliser leurs frameworks de façon interne et que le choix de l’organisation de réutilisation dépendra alors beaucoup de la politique de la compagnie. Le framework doit être considéré comme un produit même s’il est destiné à un usage interne. Il doit donc être bien documenté et le support du framework doit être planifié. Si les développeurs du framework sont les utilisateurs, ils connaîtront le fonctionnement de ce dernier ainsi que ses problèmes et limitations. De plus, ils auront moins de problème qu’un autre pour comprendre les intentions induites par l’architecture et les solutions. L’hésitation classique lors de la nécessité d’utiliser quelque chose développé par d’autres disparaît aussi, et le feedback nécessaire de la part de l’utilisateur pour le développeur est inévitablement présent… Les équipes de développement devraient, dans la mesure du possible, être constituées d’ingénieurs expérimentés, mais ceci n’est pas si simple étant donné d’éventuelles limites dans le nombre de personnel et d’un point de vue économique. Si l’on a des équipes différentes pour le développement et la réutilisation des frameworks, la connaissance des développeurs expérimentés ayant travaillé sur le développement sera transmise aux développeurs moins expérimentés qui réutiliseront ces frameworks. C’est là le principal argument en faveur de la séparation des équipes de développement et de réutilisation des frameworks. Nous avons donc vu ici qu’il y avait quelques différences entre le développement de logiciels traditionnels et le développement de frameworks qui pouvaient avoir un 21
  23. 23. impact sur l’organisation du projet. Lors du développement de frameworks, il est nécessaire de prêter attention à quelle fonctionnalité est générale et quelle autre fonctionnalité est spécifique, car ceci aura un impact sur l’organisation du travail. Maintenant que nous savons ce qu’il faut prendre en compte pour un projet de développement de framework, voyons comment on prépare un tel développement. 1.2.2 LA PRÉPARATION DU DÉVELOPPEMENT D’UN FRAMEWORK On va regarder ici quelles sont les activités effectuées avant de démarrer le processus de développement d’un framework, et ce qu’il est nécessaire de connaître avant de pouvoir démarrer ce processus. L’équipe de développement doit posséder de vastes connaissances du domaine que le framework doit englober. C’est pour cela qu’il est nécessaire d’effectuer une sorte d’analyse du domaine avant une quelconque initialisation du processus de développement. L’analyse du domaine sera une sorte de paramètre d’entrée du processus de développement du framework. Cependant, le processus de développement pourrait aussi retourner un feedback à l’analyse de domaine afin de l’affiner. D’après [Karlsson 95], une analyse de domaine est l’identification des classes et objets qui sont communs à toutes les applications d’un certain domaine. Une modélisation du domaine ne devrait prendre en compte que les artéfacts clé du domaine et ne pas traiter les détails. Un modèle du domaine est un bon outil lorsque l’on commence le développement d’une vue logique du domaine. Il devrait décrire les concepts que les personnes utilisent au sein du domaine, et faire du domaine d’analyse un instrument de communication entre les gens qui prennent part au développement du système, et ce en offrant une terminologie commune. Le modèle du domaine ne 22
  24. 24. devrait pas décrire le domaine du point de vue des développeurs, car cela pourrait gêner la communication et risquerait de donner trop d’importance à des détails trop tôt dans le processus de développement. Une analyse de domaine offre aussi un bon support quand on utilise une spécification à base de use cases. [Jacobson et al.92] De l’analyse de domaine devraient naître au moins deux documents : la portée du domaine et un modèle statique qui contienne les objets et classes importants du domaine. Il est important de réaliser un document de portée du domaine car il est impossible pour un framework de couvrir « le monde entier », en ce sens que le framework ne couvrira peut être pas tous les aspects du domaine considéré, et que dans certaines applications certains des aspects non couverts peuvent être importants. Ainsi, en précisant la portée du domaine, on sait ce que notre framework ne couvre pas. La portée du domaine a beaucoup d’importance dans les activités de découverte des besoins du processus de développement. Elle permet de se rendre compte facilement si un besoin fait partie du domaine et est donc valide, ou ne fait pas partie du domaine et est alors invalide. Elle servira aussi en tant qu’outil dans la réutilisation d’un framework, et ce lorsque l’on décidera s’il est judicieux ou non d’utiliser celui-ci dans une application donnée. Mais il est parfois difficile, lors de la rédaction de la portée du domaine, de choisir ce qui doit être dans le domaine et ce qui ne doit pas l’être. Il est plus aisé de développer un framework pour un domaine restreint que pour un vaste domaine. Il faut consacrer suffisamment de temps pour cette activité qui est des plus importantes. Le modèle statique devrait quant à lui contenir les plus importants objets et classes du domaine. Ce peut être des objets du monde réel et/ou des objets liés au monde de l’application. Ces objets et classes devraient porter des noms qui soient explicites pour 23
  25. 25. les utilisateurs puisque ce modèle sera un instrument de communication entre les développeurs et les utilisateurs de la future application. L’analyse du domaine produit donc les paramètres d’entrée du processus de développement de framework, en l’occurrence la portée du domaine et le modèle statique du domaine. La portée du domaine est un bon outil au moment de valider les besoins lors du processus de développement de framework. Elle est aussi utile lorsque l’on cherche à savoir quel framework pourrait être utile pour l’application que l’on souhaite développer. Le modèle statique contient tous les renseignements pratiques utiles pour permettre le développement. 24
  26. 26. 1.3 LA PHASE D’ANALYSE Cette phase est découpée en fait en deux parties : Les exigences du framework et l’analyse elle-même. Voyons d’abord où l’on se situe dans le développement du framework : 25
  27. 27. Figure 1-5 : Plan de développement du Framework Intéressons nous d’abord à trouver les exigences pour le framework. 1.3.1 LES EXIGENCES POUR LE FRAMEWORK Le but de cette phase est de trouver toutes les exigences sur le système que l’on est en train de développer. Les inconsistances entre les exigences, les exigences qui sont contradictoires ou ambiguës doivent être trouvées et résolues dans cette phase. Le Analyse du domaine Exigences et phase d’analyse Design du framework Implémentation du Framework test Analyse de l’application Design de l’application Implémentation de l’application 26
  28. 28. processus de développement de découverte d’exigence peut se décomposer comme ceci : Figure 1-6 : processus de développement des exigences Les trois sous activités sont décomposées suivant [Loucopolos, Karakostas, 95] : • L’extraction des exigences est le fait de découvrir tout le savoir nécessaire qui est utilisé dans la production des spécifications des exigences. • La spécification des exigences est le processus qui reçoit en entrée les délivrables de l’extraction pour créer un modèle formel des exigences. • La validation des exigences est le processus qui tente de certifier que le modèle d’exigence formel est en accord avec les besoins des utilisateurs. Pour le choix des personnes, il faut la plus grande diversité possible afin que tous les utilisateurs, développeurs du framework soient représentés afin de prendre en compte leurs exigences pour le produit final (les développeurs pour le framework, les utilisateurs pour l’application qui en découle). La phase de découverte des exigences est très importante parce que si on ne trouve pas toutes ces exigences, ou si on ne trouve pas les bons, cela implique que l’on devra faire des changements plus tard dans le développement. Et le coût de ces changements est très élevé du fait qu’une grande partie du code et du design doit être réécrite. C’est Extraction Spécification Validation 27
  29. 29. pourquoi une grand partie des efforts doit être mis en place lors de la phase d’analyse afin d’avoir une correcte, complète et consistante spécification d’exigences. Afin de rendre cette phase plus compréhensible pour les utilisateurs finaux des différents produits du framework, il est recommandé de créer des diagrammes use case spécifique à chacune des futures applications (connues lors de la création du framework) ainsi qu’un diagramme use case général que nous nommerons use case abstrait. Cela permettra aussi de trouver les différentes généralisations. 28
  30. 30. 1.3.2 L’ANALYSE Figure 1-7 : Les exigences et la phase d'analyse avec leurs produits Le but de l’analyse est de décrire un modèle du système qui est en accord avec les exigences trouvées. La phase d’analyse devrait se concentrer uniquement sur le problème et être faite sans aucune considération à-propos de l’environnement d’implantation. A ceci deux raisons, tout d’abord l’analyse restera ainsi correcte même si l’environnement change. De plus, si on si on pense aux détails d’implantation, il y a un risque que les développeurs se concentrent sur les problèmes d’implantation, ce qui entraînera que le système suppose résoudre le problème sera en dehors de ses exigences. Exigences Analyse Modèle d’exigences : Spécification d’exigences Modèle Use Case Modèle d’analyse : Modèle d’objet statique Modèle de flots de données Permet de trouver Design 29
  31. 31. En sortie de la phase d’analyse, on aura comme délivrables le modèle d’objet statique ainsi qu’éventuellement le modèle de flots de données par exemple. Le modèle d’analyse lorsque l’on crée un framework doit posséder la faculté de concentre l’attention des développeurs sur ce qui est similaire dans les applications développées et sur ce qui ne l’est pas. La phase d’analyse a les étapes suivantes [Taligent, 94] : • Décrire la situation et le problème. • Examiner les solutions existantes. • Identifier les abstractions clés. • Identifier les abstractions de haut niveau. • Identifier avec quelles parties du problème le framework traitera. • Demander ce que veulent les clients et raffiner l’approche. Lors du raffinement, il faut trouver des classes qui viennent du modèle du domaine et qui n’ont pas besoin d’êtres enlevées. Toutes les nouvelles classes nécessaires devraient, quand c’est possible, être mises dans les hauts niveaux de l’abstraction. En effet, introduire des hauts niveaux d’abstraction conduit à accroître la généralisation du système. Lors de la phase d’analyse, il faut trouver des classes abstraites qui permettront de trouver les frameworks dans le système. 30
  32. 32. 1.4 LA PHASE DE DESIGN Après avoir fait la phase d’analyse, la phase suivante lors du développement orienté objet est la phase de design. Nous allons voir dans cette section ce qui différencie la phase de design d’un framework par rapport a une phase de design classique 31
  33. 33. Figure 1-8 : Plan de développement du Framework Un design de framework est un design de logiciel qui, lorsque c’est implanté, procure les fonctionnalités générales et abstraites identifiées lors de la phase d’analyse. Il y a deux sous processus au design du framework, le design d’architecture et le design détaillé. Lors du design d’architecture, les objets ainsi que leurs collaborations seront changés, afin de coller avec l’environnement de d’implantation. Durant la phase de design détaillé, les objets trouvés lors de la phase de design d’architecture sont traduits dans le langage cible et si nécessaire, sont raffinés. Cela donne le schéma suivant : Analyse du domaine Exigences et phase d’analyse Design du framework Implémentation du Framework test Analyse de l’application Design de l’application Implémentation de l’application 32
  34. 34. Figure 1-9 : la phase design et ses sous-processus La chose principale à faire lors du design d’un framework est de construire une base pour une implantation générique, afin qu’elle puisse marcher pour un nombre important d’applications similaires. Lors de la phase du design, de nombreuses abstractions vont être identifiées, c’est pourquoi le design doit être facile à changer. Il faut donc d’abord identifier les abstractions. Comme de toute façon la plupart des concepts communs doivent être trouvés lors de la phase d’analyse, les abstractions trouvées lors de cette phase seront de niveau moindre. Autrement, cela veut dire qu’il faut retourner dans la phase d’analyse. Comme les abstractions sont trouvées par des méthodes de bas vers le haut (exemples concrets), il faut donc qu’il y ait un design pour trouver ces abstractions [Johnson, 95]. Afin de ne pas refaire plusieurs fois le Identification des objets Distribution des responsabilités Définition des collaborations Design détaillé Design d’architecture Examiner et prototyper Raffiner la hiérarchie d’héritage et les collaborations Raffiner la hiérarchie d’héritage et les collaborations Implémentation 33
  35. 35. même design, il est bon d’identifier les solutions de design génériques. Une bonne manière de traiter ce solutions générique est d’utiliser des « design patterns », dont les solutions qu’ils proposent sont bien prouvées, afin de faciliter la communication entre les différents teams de design et rendre le framework plus facile à comprendre. Figure 1-10 : le design pattern « stratégie » appliqué dans le framework pour les jeux de dés Evidemment, si un design pattern existe pour une partie du design, il est important de s’y conformer. 1.4.1 LE DESIGN D’ARCHITECTURE Comme on l’a vu précédemment, cette phase compte trois sous-phases que l’on va détailler. Mais d’abord, que fait-on lors de cette phase ? On identifie les objets dont on a besoin pour implanter le système, ainsi que leur collaboration. On peut aussi diviser le système en sous-systèmes pendant cette phase s’il est trop gros. 34
  36. 36. La première phase est de raffiner le modèle d’objet qui vient de la phase d’analyse. Il faut ajouter des objets afin d’adapter le système à l’environnement de développement (par exemple pour l’utilisation des API graphiques). Afin de rendre plus compréhensible le système pour l’utilisateur final du framework, il faut essayer de garder pour les objets les mêmes noms que lors de la phase d’analyse pour ne pas perdre inutilement l’utilisateur. Enfin, si une classe a plus de 25 méthodes, cela veut dire qu’il va falloir la restructurer. Une fois cela fait, il faut assigner les responsabilités du systèmes à des objets spécifiques. Pendant l'identification des opérations un objet est responsable de l'exécution et de quelle connaissance il maintiendra. Une façon commune d'exprimer des responsabilités semblables doit être employée, puisque cela peut aider pour identifier des abstractions. Si on nomme les responsabilités de manière générale, les abstractions viendront plus facilement. Parfois on n’arrive pas à trouver où exactement mettre les responsabilités, il faut donc la distribuer. Le premier souci en distribuant les responsabilités doit être de créer des méthodes qui exécutent des opérations logiques sur les instances de la classe. Le fait de distribuer l’intelligence du système permet aussi de trouver des abstractions. Définir autant de classes abstraites aussi possible impliquent la mise en place d'autant de comportements communs que possible. Puis, il faut analyser les collaborations entre les classes. Un objet collabore avec un autre objet si il invoque au moins une méthode de l’autre objet afin de satisfaire ses responsabilités [Karl,95]. Afin de faciliter l’extension du framework, il est préférable de définir des collaborations entres des classes abstraites plutôt qu’entres des classes concrètes. Enfin, pendant tout cela, il est important de raffiner la hiérarchie de classe ainsi que les collaborations. Les hiérarchies de classe doivent être assez profondes et étroites. Des hiérarchies de classes peu profondes et larges indiquent que les abstractions doivent toujours être trouvées dans la hiérarchie. Il est aussi important de préserver les 35
  37. 37. abstractions identifiées lors de la phase d’analyse car ce sont les abstractions fondamentales si l’analyse a été bien faite. 1.4.2 LE DESIGN DÉTAILLÉ Ici, toutes les classes avec leurs attributs et leurs méthodes sont identifiées en utilisant le langage d’implantation [Kar, 95]. On va donc ici trouver les méthodes des classes. Les méthodes doivent avoir peu de paramètres (moins de cinq) afin que l’utilisateur final comprenne facilement. De même, une méthode ne doit faire qu’un tache afin encore une fois de faciliter la compréhension de l’utilisateur final. Si une méthode fait plusieurs taches, il est peut être bon de la diviser entre plusieurs classe, pour que chaque partie soit unique dans les classes. 36
  38. 38. 1.5 L’IMPLANTATION D’après Johnson : « A Framework is a generalisation of the implementation of several applications » soit, un framework est la généralisation de l’implantation de plusieurs applications [Johnson, 95]. Il faut d’abord définir une stratégie. Généralement, on fait une implantation du haut vers le bas, id est avec le Analyse du domaine Exigences et phase d’analyse Design du framework Implémentation du Framework test Analyse de l’application Design de l’application Implémentation de l’application 37
  39. 39. développement des objets de haut niveaux d’abord. De plus, comme tous les objets de bas niveaux ne sont pas présent lorsque l’on doit tester le framework, il faut trouver une manière de les remplacer. Soit on mets des stubs, soit on simule les appels de ces objets [Karl, 95] et [Som, 92]. Il faut remarquer que l’implantation est en lien très étroit avec les design détaillé (puisque si on trouve une inconsistance en développant, on reviens de facto dans le design, au moins implicitement) et avec le phase de test puisque généralement les test de classes se font juste après l’avoir implanté [Karl, 95]. L’input de la phase d’implantation est comme avec une application classique une description détaillée des classes, de leurs interfaces. L’output est l’ensemble des classes crées, prêtes à être testée. On le fait en deux étapes : • Mise en oeuvre de l'interface externe de la classe. L'interface, définie pendant la conception détaillée, est achevée pour inclure la définition interne de la classe, c'est-à-dire des attributs protégés et privés et des méthodes. • Mise en oeuvre des méthodes, commençant avec un corps de méthode vide avec type de retour correct. Le comportement interne est identifié en examinant les modèles dynamiques, c'est-à-dire les diagrammes d'interaction et les graphiques de transition d'état. Les diagrammes d'interaction peuvent aussi contenir le pseudo code, sur lequel la mise en oeuvre peut être basée. Le comportement entier des méthodes est mis en oeuvre dans cette étape. Voici quelque guides pour implanter un bon framework, partie la plus importante de la création. Tout d’abord, intéressons-nous aux relations entres les classes. Il faut que la structure de relations soit la plus simple possible parce que c’est la partie la plus ardue à comprendre. Si il y a des héritages multiples, il faut absolument commenter longuement ces héritages afin que l’utilisateur du framework en comprenne l’utilité. Un 38
  40. 40. bon framework est un framework simple à comprendre, avec du code propre. Pour les mêmes raisons, il vaut mieux éviter de faire des appels à des méthodes définies plus bas dans la hiérarchie de classe mais plutôt les mettre dans l’interface de la super classe. L’utilisation de classes friend doit être aussi évitée car cela passe outre l’encapsulation et donc cela peut générer des erreurs. Il vaut mieux mettre en friend seulement les méthodes de classes qui en ont besoin. Enfin les concepts d’héritage privés (qui n’est pas un concept orienté-objets mais un concept de C++) ainsi que le fait d’utiliser des héritages restrictifs ne doit pas être mis en œuvre dans un framework pour des raisons de compréhensions de l’usager final. Il faut plutôt restructure la hiérarchie d’héritage à ce moment là. Maintenant que nous avons vus les relations, intéressons nous aux classes et aux méthodes. Tout d’abord, voyons des conseils qui peuvent être vus pour tout application à créer mais qui sont très importants lors de la création de framework, afin d’éviter que l’utilisateur final ne comprenne pas ce qui est fait ou qu’il puisse faire de fausse manipulations. Ainsi toutes les classes abstraites ne doivent pas pouvoir être instanciées (par exemple en C++, il faut déclarer au moins une méthode virtual afin que la classe ne puisse être instanciée, ou alors si le constructeur est protégé), ceci afin que l’utilisateur ne le fasse par mégarde. De même toutes les méthodes qui devront être surchargée doivent être définies comme virtual. De même, il serait bon d’avoir un mécanisme qui empêche de surcharger des méthodes qui ne doivent pas l’être (mais ce n’est pas possible en C++ par exemple), afin de ne pas passer outre l’esprit du framework. Il est bon aussi de déclarer le plus possible les membres des méthodes en const, afin que la méthode ne change pas l’état de l’objet. Ceci était pour empêcher l’utilisateur de mal utiliser le framework. De même, il est important de spécifier tous les attributs de l’objet comme privés, afin de ne montrer que l’interface de l’objet et non comment on l’implante en pratique. Maintenant, il faut qu’il comprenne comment marche le framework, et pour cela, les méthodes ne devraient pas dépasser 20 lignes de codes, ou alors il faut les redessiner. Il est intéressant aussi d’enlever tous ce qui vérifie explicitement le type de l’objet afin d’utiliser au maximum les bénéfices du polymorphisme, concept très important lors de la création d’un 39
  41. 41. framework, parce qu’il permet d’étendre facilement celui-ci en rajoutant simplement de nouvelles sous-classes. Il est préférable d’utiliser un inline explicite qu’implicite, ceci afin de rendre l’interface la plus lisible possible, et donc de la rendre plus facilement compréhensible : Figure 1-11 : Utilisation d’un inline explicite Après les classes et les méthodes, finissons par les constructeurs et les destructeurs. Afin d’avoir le contrôle de son implantation, le concepteur doit explicitement créer les constructeurs et destructeurs de sa classe, ainsi que les opérateurs copie et assignement. De plus, si ces deux derniers opérateurs ne sont pas obligatoires, il vaut mieux les cacher dans le la partie privée de la spécification de la classe, afin que l’utilisateur ne puisse les utiliser. Enfin pour les super classes, le destructeur doit être virtual, afin que les sous-classes désalloue elle-même leur mémoire. class Kitty: public Money_Container { public: void Deposit(int const nAmount){ nSum = nSum+nAmount; } // Implicit inline } // File: file.h (header file) class Kitty: public Money_Container { public: void Deposit(int const nAmount); } // File: file.cc (source file): inline void Kitty::Deposit(int const nAmount){ nSum = nSum+nAmount; } //Explicit inline 40
  42. 42. 1.6 VÉRIFICATION ET VALIDATION La vérification est le fait de vérifier que le système en construction va satisfaire toutes les exigences faites lors de la phase d’analyse. La validation est le fait de vérifier si le système en construction est le produit que les clients veulent vraiment. La validation et la vérification prenant une place importante dans les coûts de développements (en 30 et 50%) [Jacobson, 92], le fait de faire baisser le temps de cette partie aura un impact important sur le processus de développement. On peut diviser le processus de vérification et validation en trois : les tests d’unités, le test d’intégration, et enfin le test du modèle. 41
  43. 43. 42
  44. 44. 43
  45. 45. 1.6.1 TEST DES UNITÉS Ici, comme son nom l’indique, on ne teste qu’une unité à la fois (qui peut être une opération, une classe, un module contenant plusieurs classes, voire un framework). On vérifie qu’une unité bien définie avec des responsabilités bien définies satisfasse les exigences imposées sur cette unité. Analyse du domaine Exigences et phase d’analyse Design du framework Implémentation du Framework test Analyse de l’application Design de l’application Implémentation de l’application 44
  46. 46. Selon Marciniak, Jacobson et Karlsson, il y a deux méthodes pour faire des tests d’unites [Marciniak, 94], [Jacobson, 92], [Karlsson, 95] : • Le test de structure, qui exige la connaissance de la structure interne de l'unité, fournit la connaissance du code de l'essai et l'envergure de branche, qui indique la fiabilité de l'unité. • Le test de spécification, ou le test des fonctionnalités, qui est seulement basé sur les exigences imposées à l'unité. Aucune attention n'est payée à la structure interne du module, on s’intéresse seulement aux réponses de l'unité à certaines entrées. 1.6.2 TEST D’INTÉGRATION On teste ici comment les unités travaillent ensemble. [Jacobson, 92], [Karlsson, 95]. Un essai d'intégration peut, en même temps, être un essai d'unité, une unité peut consister en plusieurs sous unités. Jacobson recommande pour ces tests d’utiliser des diagrammes de uses case. Le test d'intégration final, quand tous les modules sont combinés pour former le système final, est parfois appelé le test du système. Le test du système vérifie si le système satisfait les exigences ou non. Si les exigences sont formulées comme des diagrammes use case, les résultats d'un certain use case donneront directement la satisfaction d'une exigence spécifique. L'essai de système sera la première possibilité d'évaluer si le système satisfera les exigences imposées au système. Le test d'intégration précédent satisfera seulement les exigences qui sont tirés des exigences de l’utilisateur, d’où l'importance de l'essai de système. 45
  47. 47. 1.6.3 TEST DU MODÈLE Après avoir fait cela, il faut faire un test du modèle, et ce a la fois lors du développement puis lors de la réutilisation du framework. Le test du modèle consiste en un test de cas et un test bed [Karlsson, 95]. Un test bed [Jacobson, 92] consiste a simuler tous ce qui entoure l’unité à tester. Le test fait les appels aux opérations de l’objet testé. Un test de cas consiste en une s Un test de cas consiste en une séquence d’action ou une séquence de stimulus, pour voir si l’unité répond de la manière prévue. Si l’on a utilisé des diagrammes use case dans le modèle d’exigence, ils seront une bonne base pour créer ces tests là. 1.6.4 SPÉCIFICITÉ DES FRAMEWORKS Maintenant que nous avons vus les différents types de tests, regardons quelles sont les spécificités du framework lors de cette phase. Par rapport à un test d’application normal, il n’y a pas beaucoup de différences. Mais tout d’abord, il faut voir qu’il y a deux questions principales lors des tests sur le framework. Premièrement, est-ce que le framework couvre bien le domaine comme on l’a voulu [Joh, 91] ? Ceci est vérifié si l’on réutilise souvent ce framework. Si le framework ne peut être utilisé lors du développement d’une application pourtant incluse dans son domaine d’application, le framework doit être repensé ou alors son domaine d’application changé. Ensuite, le framework doit satisfaire les parts des exigences de l’application qui sont dans son aire de responsabilité. Cela est vérifie une première fois lors du test du système. Un bon outil pour tester le système est le polymorphisme [Jacobson, 92]. Si des changements sont fait dans une sous-classe, il ne doit pas y avoir de changements à faire dans les classes du framework. Cela veut donc dire que si on change les sous- classes (et donc l’application), tout en restant dans le domaine d’application du 46
  48. 48. framework, on ne doit faire que des tests d’unités sur ces sous-classes et il ne doit pas y avoir à retester le framework avec ces sous-classes. Il faudra juste à la fin faire un test d’intégration et un test de modèle. Il faut voir qu’il y a des difficultés à utiliser le polymorphisme par rapport aux traditionnelles procédures orientées objets. En effet, une des difficultés et de tester tous les chemins possibles avec le polymorphisme lors d’un test de structure. Quand on utilise un case comme avec les anciennes techniques, tous les cas possibles sont montrés tandis qu’avec le polymorphisme, seule l’unité invoquée est montrée [Jacobson, 92]. Figure 1-12 : La différence entre un case et le polymorphisme De plus, l’héritage va diminuer la taille du code mais pas la taille des tests. Les méthodes héritées d’une super classe peuvent en effet marcher avec celle-ci et pas avec Fichier Virtual: Read() ; Write() ; Fichier DOS Virtual: Read() ; Write() ; Fichier UNIX Virtual: Read() ; Write() ; Si l’on utilise case : … store : Fichier … case store.type est    FichierDOS : readDOS(store);    FichierUNIX : readUNIX(store) ; Fin case Polymorphisme : … store : fichier … store.Read() ; 47
  49. 49. une de ses sous-classes [Jacobson, 92]. Les méthodes héritées doivent donc être testées aussi. 1.6.4.1 La certification de la fiabilité Avant de pouvoir réutiliser un composant, il est important que la personne le réutilisant puisse se faire une idée de sa fiabilité. La fiabilité est souvent critique car l’échec d’un système va souvent coûter au réutilisateur de l’argent. Les exigences doivent donc clairement spécifier le degré de fiabilité du système [som, 92]. Voici quelques métriques utilisées pour tester la fiabilité [Sommerville, 92] : • La première métrique est l'échec de probabilité sur demande qui est une mesure de la probabilité que le système se comportera d'une façon inattendue quand il est appelé. • Le taux de présence d'échec est la seconde métrique qui est mesure combien de fois le système se comportera de façon inattendu par unité de temps. Selon Sommerville ce métrique est la plupart du temps la plus générale. • La troisième métrique est le temps moyen à l'échec, qui est une mesure du temps moyen entre deux échecs arrivant sur le système. • La disponibilité donne la probabilité que le système est prêt à être utilisé. 1.6.4.2 Les tests statistiques Pour trouver ces métriques, il faut faire des tests statistiques. Il y a quatre étapes dans le processus de tests statistiques [Sommerville, 92] : 1. Déterminer le modèle d’utilisation de l’unité. 48
  50. 50. 2. Collecter et détecter les données de test qui identifient les tests de cas selon ce modèle. 3. Exécuter les tests de cas selon l’utilisation de ce modèle. Enregistrer le temps d’exécution jusqu'à ce qu’une erreur arrive. 4. Trouver la fiabilité du logiciel selon les résultats de test. Un framework est réutilisé avec le but de développer de nouvelles appplications. Différentes applications peuvent avoir différents modèles d’utilisation, ce qui peut limiter l’utilisation des tests statistiques. Cependant, un travail qui approuve l'utilisation des tests statistiques comme une méthode pour la certification de fiabilité de composants de logiciel a été fait. Le test d'utilisation peut aussi être une méthode appropriée de certifier des frameworks aussi. 49
  51. 51. 1.7 LA MAINTENANCE Le dernier point du développement d’un framework est la maintenance. En plus des aspects de maintenance normaux, le framework a d’autres besoins pour la maintenance. Regardons lesquels ils sont. La maintenance faite pour améliorer le système sans changer ses fonctionnalité prend 65% du temps de maintenance, la maintenance pour corriger les erreurs 17% tandis que la maintenance destinée à adapter prend 18% du temps [Lientz, Swanson, 80]. La structure interne d’un framework consiste en une structure de classes abstraites et concrètes. Un bon framework est une structure qui est profondément héritée mais de manière étroite. Donc un changement fait dans une super classe va affecter toutes ses sous-classes, ce qui peut être gênant. Une manière de contourner cela, mais sur le court terme est de faire une sous-classe qui implante les changements et de la faire hériter de la super classe. Les changements pourront donc être aisément contrôlés et la possibilité de dépendances inconnues est réduite. Mais de telles modifications vont, sur le long terme, conduire à la dégénérescence des classes et de la structure d’héritage. A ce moment-là, il faut restructurer le framework régulièrement [Gam, 94]. Un framework est construit avec l'intention qu'il sera employé pour développer beaucoup d'applications. L'utilité d'un framework est reflété par combien de fois il est réutilisé et toutes ces applications dépendent de la structure. Les modifications d'interfaces et des noms sont cruciales et affecteront très probablement les applications dépendantes. Il faut donc lors du développement du framework porter le plus gros effort sur le choix des interfaces et des noms. Mais il faudra probablement changer des noms et des interfaces. Quand n'importe quelle demande de changement est trouvée valable il est meilleur de mettre en oeuvre 50
  52. 52. ces changements aussi rapidement que possible parce que encore plus d’applications dépendantes peuvent être développées en attendant, augmentant le nombre de systèmes dépendants. Par contre, les changements internes dans le framework ne devrait pas dans la plupart des cas affecter les interactions entre le framework et l’application. C’est pour cela que ces changements sont moins cruciaux. Chaque personne utilisant le framework doit être prévenue lorsque des modifications sont faites, spécialement lorsque des fautes ont corrigées [Karlsson, 95]. 51
  53. 53. 2 EXPÉRIENCE D’APPLICATION DES FRAMEWORKS Dans le domaine du génie logiciel, les « frameworks » orientés objets offrent une grande puissance compte tenu de la diversité de ceux-ci. Un framework fournit un squelette d’application donnant une base solide pour le développement de logiciel dans un domaine particulier. Cette technique se voit beaucoup plus puissante que la simple réutilisation des classes parce qu’elle offre également l’architecture haut niveau (design) du système à développer. C’est pourquoi nous nous attarderons sur les aspects permettant une réutilisation simple, efficace et sans ambiguïté. Premièrement, nous étudierons l’aspect de la réutilisabilité qui peut être vue sous deux angles différents. La première façon est de se demander, lors du développement d’un framework, la bonne démarche à suivre pour que notre système soit facilement réutilisable. L’autre façon de voir la réutilisabilité est lorsque le développement utilise un framework existant. En approfondissant ces deux aspects de la réutilisabilité, nous verrons qu’une part importante d’un bon framework est la façon dont il est documenté lors de la conception. Nous terminerons cette étude avec l’exemple d’un « Framework » bien documenté ce qui permet d’augmenter sa réutilisabilité. 52
  54. 54. 2.1 RÉUTILISABILITÉ 2.1.1 RÉUTILISABILITÉ LORS DU DÉVELOPPEMENT D’UN NOUVEAU FRAMEWORK Il y a typiquement deux façons d’organiser l’équipe de développement lors de la mise en oeuvre d’un nouveau framework. La première est de laisser aux mêmes personnes le soin de développer et de réutiliser le framework. L’autre façon est d’avoir deux organisations distinctes : l’une qui développe et l’autre qui réutilise. Si l’intention est de vendre ou de distribuer le framework, il n’y aura qu’une équipe qui développera le système. Cependant selon Landin et Niklasson (1995), la plupart des compagnies utiliseront leurs « frameworks » à l’interne. Ainsi, le choix de l’organisation de la réutilisation est intimement lié à la structure de la compagnie. Lorsque le framework est développé et utilisé par les mêmes personnes, ils sont en mesure de connaître les problèmes et les limitations du système. De plus, ils n’ont aucun problème à comprendre les intentions dernières l’architecture et la solution mise en oeuvre. Cependant, lorsque qu’une équipe de développement décide d’utiliser un framework existant, ils devront, lors de l’analyse et du design, prendre en considération la réutilisabilité. 2.1.1.1 L’analyse avec la réutilisation Le processus d’analyse doit acquérir les différentes exigences en plus de pouvoir obtenir une modélisation du monde d’application. En introduisant la réutilisabilité à l’étape d’analyse, le processus de développement se voit quelque peu modifié [Karl, 1995]. En effet, il faut identifier les opportunités de réutilisation durant la phase de spécification et identifier les exigences spécifiques qui les supportent [Nato, 1991]. 53
  55. 55. Il est important de formuler les exigences aussi générales que possible lorsque nous effectuons l’analyse. La raison est que si les exigences sont trop précises et détaillées, ils ne se superposeront pas sur des exigences déjà existantes. Le même problème peut être résolu de plusieurs façons différentes donc aucune solution de devrait être proposée à ce stade-ci. Afin d’augmenter l’adéquation de la réutilisabilité, nous ne décrierons que les fonctionnalités nécessaires. Ce type d’analyse s’appelle l’analyse du domaine et elle doit être utilisée pour déterminer si les composantes requises sont comprises dans un domaine déjà couvert. Si le domaine est couvert et qu’il existe des « frameworks » pouvant être utilisés, il faut les étudier avec soin. Dans le cas contraire, le design devra prendre en considération le développement des fonctionnalités nécessaires tout en assurant une bonne réutilisabilité. 2.1.1.2 Design avec la réutilisabilité Le design se découpe en deux phases : le design de l’architecture et le design détaillé. Le design de l’architecture devra définir une stratégie haut niveau pour résoudre le problème et implanter une solution. Selon Karlsonn, il y a deux principales difficultés pour la réutilisabilité à cette étape du design : • La difficulté de comprendre les solutions prédéfinies. • Appliquer la connaissance acquise pour structurer le problème de façon à ce qu’il puisse être solutionné par les solutions prédéfinies qu’offre les « frameworks » sur le marché. C’est pourquoi le rapport d’activité dans le développement du processus de réutilisation contribuera à augmenter la maturité du framework. En général, lorsqu’un framework est réutilisé, un rapport de réutilisation devrait être conçu avec les sections suivantes [Karl, 1995] : • Des informations sur l’environnement de réutilisation. 54
  56. 56. • Des informations sur les difficultés de compréhension du framework. • Des informations sur les difficultés rencontrées lors de l’adaptation du framework. • Le coût de réutilisation. • Toutes les modifications apportées au framework. Dans le cas où un framework est réutilisé pour la conception d’un système, le cycle de vie peut différer légèrement comparativement à un développement normal. Voici le cycle de vie proposé par Kirk (2001) : Phase 1 : Identification des objectifs Phase 2 : Identification des candidats pour la réutilisation • Recherche de « frameworks » • Expériences précédentes Phase 3 : Sélection du candidat réutilisable Phase 4 : Modification • Réutilisation direct • Modification • Création Phase 5 : Évaluation des modifications Figure 2-13 : Cycle de réutilisation d’un framework La première phase définit les objectifs de la tâche à réaliser. C’est le processus qui identifie le problème et décrit une solution haut niveau pour le résoudre. 55
  57. 57. La prochaine phase tente de localiser les éléments d’un framework qui pourrait être applicable au problème présent. Les candidats sont choisis en recherchant parmi les composantes d’un framework par rapport au domaine du problème. Il existe deux méthodes pour la recherche d’un framework. Premièrement, il y a la stratégie « design first » qui crée une solution au problème avant de commencer la recherche d’un framework. Inversement, la méthode « framework first » crée une solution en identifiant des composantes utiles dans un framework et en essayant de les fusionner pour atteindre les exigences du système à développer. Selon Kirk, la méthode à prévilégier est de solutionner le problème avant d’effectuer la recherche de composantes. Ainsi, on peut avoir une idée précise des fonctionnalités recherchées et le développement est plus simple et moins décousu. La troisième phase sert à choisir l’un des candidats préalablement sélectionnés pour l’implantation. La sélection est une tâche difficile car le framework choisi influencera tout le reste du développement ainsi que le produit final (stabilité, fonctionnalité, ...). Un choix éclairé demande une bonne connaissance de l’architecture du framework ainsi que des interactions qu’il aura avec le reste du système. L’implantation est la quatrième phase de la réutilisation. Les composants sélectionnés peuvent être implantés au choix selon l’une des trois façons suivantes : • Si les composantes du framework correspondent exactement aux spécifications du problème à résoudre, il peut être utilisé directement. • Si le framework sélectionné est le plus près framework de la spécification pour la résolution du problème, il sera utilisé avec quelques modifications. • Finalement, si aucun framework n’a été identifié pour la tâche, il faudra créer le squelette de l’application à partir de zéro. 56
  58. 58. La dernière étape est celle où le produit doit être évalué. L’évaluation considère les effets du travail sur l’architecture du framework pour le présent problème. Cette phase est quelque peu subjective puisqu’il n’existe pas vraiment de méthode formelle pour effectuer l’évaluation du système. Il y a, dans la littérature, quelques chartes et quelques pistes mais il est du devoir des développeurs de s’assurer que le framework répond au problème de façon simple et efficace. 2.1.1.3 Problème de réutilisation De nombreux problèmes peuvent survenir lors du développement lorsqu’on réutilise un framework. Nous pouvons diviser ces problèmes en deux catégories : comprendre et localiser. La localisation de composantes à l’intérieur d’un framework semble être difficile dû au grand nombre de classes qu’il contient. La hiérarchie avec héritage rend la tâche ardue en camouflant les fonctionnalités dans les superclasses. Cela rend la compréhension des comportements des composantes encore plus difficile. Le problème de la compréhension peut être subdivisé en deux sous problèmes : compréhension des composantes et compréhension des interactions. Ce qui rend la compréhension des différentes parties d’un framework difficile, c’est tous les mécanismes mis en place pour assurer une bonne flexibilité : classes abstraites, « design patterns », héritage, compositions, etc. Ces mécanismes font que nous avons besoin d’une vue d’ensemble très détaillée pour être en mesure d’utiliser une sous-partie d’un framework. Les interactions causent aussi des problèmes lors du processus de réutilisation parce qu’il est difficile pour les développeurs de les visualiser. Beaucoup d’efforts sont déployés afin de reconstruire le flot de contrôle du framework. Il est assez facile de voir que tous ces problèmes pourraient être considérablement éliminés si une documentation appropriée avait été construite lors du développement du framework. Un framework ne peut être réutilisé que s’il est bien compris et c’est 57
  59. 59. suite à cela que nous allons nous pencher sérieusement sur la question de la documentation des « frameworks ». 58
  60. 60. 2.2 DOCUMENTATION Afin de devenir une tendance répandue, les techniques de réutilisation des « frameworks » doivent exiger que les concepteurs rendent leur compréhension sur le framework aussi accessible que possible. Un pont doit être mis en place entre le savoir des développeurs et la compréhension des utilisateurs sur le framework. Il n’y aura donc aucune surprise si nous insistons beaucoup sur l’importance d’une documentation simple, complète et précise. Selon [joh, 1991], un framework n’est pas complètement stable lors de sa première utilisation. Le framework aura besoin de modifications lorsqu’il sera réutilisé et chaque fois qu’il sera réutilisé, il deviendra de plus en plus stable. D’où l’importance de la bonne compréhension du framework puisqu’il nécessitera sûrement quelques ajustements. Dans cette section, nous allons présenter trois techniques de documentation qui semblent fondamentales. Premièrement, nous verrons l’approche cookbook, ensuite la technique avec les design patterns et finalement l’approche plus abstraite de Wilson & Wilson. La documentation d’une application classique orientée objet doit être décrite de différentes façons selon les différentes catégories du génie logiciel. Ceci est vrai aussi pour les librairies de classes ou les « frameworks ». Selon [Lin, 1990] l’information suivante devrait être présente dans la documentation pour la compréhension et l’utilisation des classes : • Information structurelle : il s’agit du nom de la classe, des superclasses s’il y en a, du type des paramètres d’instanciation plus les informations similaires sur les opérations. • Description, en langage naturel, de chaque classe. Cette description devra décrire l’essence de la classe et l’abstraction qu’elle représente. 59
  61. 61. • Usage : décrit si la classe doit être instanciée d’une façon ou à un moment particulier. • Configuration : décrit comment les classes sont reliées entre elles. • Assertions : documentation de contraintes sémantiques comme les préconditions, les postconditions et les invariants de classes. • Opérations : pour chaque opération, il faudra fournir de la documentation comme les paramètres, le résultat de l’opération et les types correspondants. Derrière cela, la documentation du framework doit décrire différents niveaux d’abstraction pour atteindre un plus grand nombre de développeurs et d’utilisateurs. Nous voulons surtout parler du niveau d’expérience des utilisateurs des « frameworks », car les besoins sont différents pour un utilisateur expérimenté des « frameworks » et celui qui utilise ce concept pour la première fois. Un framework doit contenir [joh, 1992] : • L’objectif du framework • Comment utiliser le framework • L’objectif des exemples d’applications • Le design du framework 2.2.1.1 Objectif du framework La première chose est évidemment de décrire l’objectif du framework, c’est-à-dire quels problèmes peut-il résoudre. Cette section doit vraiment être claire et doit 60
  62. 62. explicitement expliquer quel est le problème et quelle est la solution que le framework offre. Nous présenterons cette partie au début de la documentation pour que le lecteur détermine si le framework peu ou non satisfaire ces besoins. Si le framework n’est pas adapté aux besoins, le lecteur doit chercher ailleur donc il n’est pas nécessaire de continuer la lecture de cette documentation. 2.2.1.2 Comment utiliser le framework C’est problablement la partie la plus importante de la documentation pour un utilisateur. Plusieurs développeurs documenteront le framework en détaillant la structure et le fonctionnement de celui-ci sans toutefois expliquer comment nous pouvons nous en servir. Cette section doit donc expliquer, avec la description des classes et des méthodes, comment le framework peut être utilisé. Cette section n’abordera pas le fonctionnement à l’interne du framework. 2.2.1.3 L’objectif des exemples d’applications Les exemples d’application du framework doivent être présent tout au long de la documentation. Il est important, pour un utilisateur, de pouvoir se rattacher à des exemples. Ainsi, il pourra savoir si oui ou non il comprend bien le fonctionnement et l’utilisation de celui-ci. Les exemples peuvent être introduit dans une section spécifique ou tout simplement glissés tout au long de la documentation à des fin d’illustration. 2.2.1.4 Le design du framework La description détaillée du desgin doit contenir la description des classes et leurs relations. Il doit aussi en ressortir les différentes collaborations entre les classes. Les « frameworks » sont généralement de grande collections de classes donc les sutilisateurs prendront un certain temps pour se familiariser. Cependant, gardez toujours en tête que plus le framework est compris, plus il sera réutilisé. 61
  63. 63. Nous venons de présenter les différentes sections que la documnetation doit contenir. Maintenant, nous nous attarderons sur des approches de documentation qui ont été développées pour la conception de systèmes orientées objets. 2.2.2 LES APPROCHES COOKBOOK La plupart des utilisateurs de « frameworks » ne sont pas intéressés par les détails de la conception du framework. Ils sont plutôt à la recherche de la documentation qui décrit comment le framework peut être utilisé. Ils sont donc à la recherche de documentation du style « guide de cuisine (cookbook) ». Quelques approches utilisant l’approche cookbook existe dans la litérature [Krasner, 1988][Apple, 1989][Pree, 1994a]. 2.2.2.1 L’approche cookbook « model-view-Controller » La méthophore « model-view-controller » (MVC) tient ses origines de Smalltalk-80 et décrit comment décomposer une application ayant une interface utilisateur. Les trois composantes sont : • Le Modèle qui capture les fonctionnalités du domaine. • La Vue qui affiche l’état de l’application. • Le Controleur qui gère les interactions entre le modèle et la vue. L’approche de documentation commence avec une description de l’implantation de la métaphore MVC. La description est à un niveau très détaillée et présente de nombreux exemples. Les exemples décrivent comment le framework doit être utilisé. La faiblesse de cette approche est qu’elle décrit la voie normale dans laquelle le framework va être utilisé. Il n’y a aucune anticipation sur l’utilité du framework dans le futur. Le cookbook ne peut pas décrire tous les cas d’utilisation du framework car ce n’est pas l’intention de cette approche. 62
  64. 64. 2.2.2.2 L’approche cookbook « MacApp » MacApp est une interface utilisateur graphique développée par Apple Inc. Les deux approches, MacApp et MVC, sont des méthodes basées sur l’exemple. La principale différence est que MacApp est comme un livre de recettes où chaque recette résout un problème particulier. L’approche MVC décrivait plutôt la solution générale. La lacune de MacApp est qu’elle n’a pas la capacité de décrire les utilisations imprévues du framework mais, encore une fois, ce n’est pas l’objectif d’un « cookbook ». 2.2.2.3 L’approche cookbook Active Cette approche utilise les metapatterns pour la description des « frameworks » orientés [Pree, 1994a]. Chaque metapattern est rattaché à une partie du framework qui diffère sémantiquement des autres et il décrit de façon détaillée chaque classe et chaque méthode de la sous-partie avec des exemples. Ensuite, le design du framework et les metapatterns sont placés dans un système hypertexte. Le système hypertexte est utilisé comme un cookbook actif qui présente à l’utilisateur les parties du framework qui l’intéresse. 2.2.2.4 Discussion Les approches cookbook sont très lorsqu’il s’agit de présenter l’objectif du framework et de présenter des exemples. L’utilisation du système est bien expliquée et démontrée ce qui favorise l’utilisation rapide du framework. Si, par contre, le framework doit être modifié pour une raison quelconque, ce type de documentation ne nous est d’aucune utilité. La présentation du design et de l’architecture est souvent négligée ce qui force les développeurs à faire une trace du système pour bien comprendre. Finalement, pour utiliser ce genre d’approche, il est indispensable que le développement du framework ait atteint une très grande maturité pour ne pas effectuer des modifications inutiles. 63
  65. 65. 2.2.3 LES APPROCHES PAR PATTERN Les patterns existent sous diverses formes et quelques une d’entre elles sont très bien appropriées pour la documentation des « frameworks ». Le design de patterns orientés objets et les Motifs semblent être les deux patterns les plus prometteur pour la documentation. 2.2.3.1 L’approche motif L’approche de Johnson [Joh, 1992] utilise un type de pattern pour la documentation (motif) décrivant l’utilisation d’un framework. Tous les motifs ont une structure commune. Premièrement, une description du problème est formulée suivie par une discussion sur les différentes avenues possibles pour résoudre le problème. La discussion inclut des exemples et des pointeurs vers d’autres parties du framework. Le motif se termine avec un résumé de la solution et différents pointeurs vers d’autres motifs. Pour mieux comprendre la documentation par motif, nous présenterons un exemple de motif définit dans le projet HotDraw. HotDraw est un framework pour l’édition de graphique implanté en Samlltalk. La description du problème se trouve dans le premier motif de Hotdraw. HotDraw est un framework pour structurer les éditeurs de dessins. Il peut être utilisé pour construire des éditeurs spécialisés pour le dessins à 2 dimensions comme les diagrammes shématiques, la musique, le design de progamme, etc. Les éléments de ces dessins peuvent avoir des contraintes entre eux, ils peuvent réagir aux commandes de l’utilisateur et ils peuvent être animés. L’éditeur peut être une application complète ou être une petite partie d’un grand système. Traduit de [Joh, 1992]. Figure 2-14 : Description du problème du premier motif de Hotdraw Motif 3 : Changement d’attribut d’un élément dessiné Il y a au moins trois voies pour éditer les attributs d’une figure : avec un identificateur (handle), avec un menu associé à la figure, ou avec un outils spécial. Chaque technique est appropriée suivant différents cas. 64
  66. 66. Les attributs numériques (taille d’une figure, etc.) seront édités avec un identificateur. Les attributs textuels (nom, date, etc.) seront édités en affichant le texte comme une partie de la figure et en laissant l’usager le modifier avec un « outil texte ». L’utilisation de « l’outil texte » implique que la figure est une « CompositeFigure » (voir Figures complexes (4)). ... Figure 2-15 : Partie d’un motif du framework HotDraw [Joh, 1992] 2.2.3.2 L’approche de design de Pattern orientés objets Un pattern orienté objet décrit une partie du design. Il n’est pas approprié pour présenter le design entier avec une vue d’ensemble. Une classe dans un framework peut avoir différents rôles dépendemment du nombre de « design patterns » qui lui sont associé. Cela veut dire qu’il est difficile d’identifier les limites entre les différents « design patterns » dans un framework. Cette approche est très utilisée lorsqu’il est important de bien décrire les sections d’un framework avec des diagrammes et du nouveau vocabulaire. Dans certains cas, lorsque le framework offre la possibilité d’être adapté, la documentation par « design pattern » peut être très efficace. 2.2.3.3 Discussion Il est évident qu’une seule technique de documentation décrira généralement un seul aspect du framework. Pour être efficaces, des combinaisons doivent être envisagées lors de la rédaction de la documentation. Les motifs sont très pertinents pout introduire des exemples d’utilisation alors que les « design patterns » décrivent de façon détaillée les modules d’un framework. Habituellement, les design patterns sont utilisés tout au long du développement pour documenter pas-à-pas les modules. Vers les dernières itérations du cycle de vie, on commence à intégrer de la documentation contenant des exemples d’application et d’utilisation (Motif). 65
  67. 67. 2.2.4 L’APPROCHE « LANGAGE DE DESCRIPTION DE FRAMEWORKS » Il existe une autre approche proposée par Wilson et Wilson en 1993 qui s’appelle FDL (Framework Description Language). Selon eux, les relations d’héritages, les références et les séquences de création d’objets sont des items nécessaires pour décrire la façon de documenter un framework. Il doit aussi y avoir de l’information qui répond aux questions suivantes : • Quelles nouvelles classes devraient être fournies par le framework ? • Quelles classes devraient être utilisées ? • Quelles opérations sont souvent utilisées ? Suivant ces questions, un framework peut être vu comme un design abstrait qui décrit un concept dans un domaine d’application tout comme une classe abstraite. Cela implique que le développeur de l’application doit, conceptuellement, dériver son application de la classe abstraite qui est le framework. En procédant de cette façon, il faut se demander de quelles opérations nous auront besoin et quelles sont celles que nous devont « overrider » ? Pour répondre à ces questions, un « Framework Description Language » est proposé [Wilson, 1993]. Il s’agit d’un nombre de mots clés avec des entêtes de classe ressemblant au C++ mais appliqué aux « framwworks ». L’implantation des FDL décrit quelles opérations peut ou doit être utilisées ou réécrites dans le framework. Voici le Template d’une interface FDL : framework name { 66
  68. 68. mustInstanciate : // Ensemble des classes qui doivent être instanciées mayInstanciate : // Ensembles des classes qui peuvent être instanciées mustSubclass : // Ensemble des classes qui doivent être des sous-classes library : // Ensembles des classes qui sont utilisées à partir d’une // librairie (Donne de l’information pour le linkage de // l’application développé). private : // Ensemble des classes qui sont internes au Framework. } ; Figure 2-16 : Interface d’un template FDL Une amélioration à cette approche est d’ajouter un template « Framework Class Description (FCD) ». C’est une variante des entêtes de classe en C++ qui décrivent, pour chaque classe, quelles opérations doit ou peut être réécrites (overridden). Une documentation complète d’un framework décrite par Wilson & Wilson, devrait contenir : • Une description du framework en FDL • Un diagramme de classe • Des exemples de programmes • Des recettes d’utilisation 67
  69. 69. Après avoir identifié les principaux points de cette technique, nous sommes en mesure de dire qu’elle est similaire à l’approche des cookbooks à l’exeption du FDL. 2.2.5 CONCLUSION SUR LA DOCUMENTATION Nous avons présenté plusieurs techniques pour la documentation d’un framework qui décrivent bien l’ampleur qu’une bonne documentation peut avoir. Il n’existe pas d’approche miracle ou révolutionnaire pour la documentation d’un framework. La solution réside dans la combinaison de plusieurs méthode afin de fournir le maximum d’information sans toutefois dépenser trop d’argent. Pour un équipe de développeurs, la documentation est rarement une priorité mais ayez toujours en tête que pour mesurer la qualité d’un produit, il faut d’abord l’utiliser. 68
  70. 70. 2.3 EXEMPLE Toute cette théorie nous apprend bien des choses mais qu’en est-il vraiment dans l’industrie lorsqu’il s’agit de documentation ? Nous allons vous présenter un exemple de « frameworks » que nous analyserons selon les points suivants : • L’objectif du framework • Comment utiliser le framework • L’objectif des exemples d’applications • Le design du framework Nous allons tout d’abord présenter comment la documentation du framework JTGame répond aux objectifs et ensuite, une analyse de l’approche utilisée sera effectuée. 2.3.1.1 Objectif du framework L’introduction générale de la documentation décrit les différents modules qui composent le framework ainsi que les librairies utilisées. L’objectif est bien expliqué, l’information sur la nouvelle version est présente dans la section features et l’information générale sur le framework (nombre de classes, modules en développement, etc.). 69
  71. 71. Figure 2-17: Introduction générale du framework 2.3.1.2 Comment utiliser le framework La description des concepts et des classes est exceptionnellement illustrée de façon détaillée et modulaire. Dans la Figure 2 -18, on nous explique les différents concepts qui se retrouveront dans le framework (ce sont donc les classes qui devront être utilisées). 70
  72. 72. Figure 2-18 : Présentation des concepts du module Dans la Figure 2 -19, on entre dans la partie beaucoup plus technique sur l’utilisation des classes du framework (section reference). On y présente les différentes interfaces, les types utilisées, les fonctions, les macros, bref tout ce qui est nécessaire à l’utilisation du module. Chaque classe est détaillée d’une façon exemplaire (Figure 2 -20). 71
  73. 73. 72
  74. 74. Figure 2-19 : Présentation techniques du module Figure 2-20 : Description d’une classe du framework 2.3.1.3 L’objectif des exemples d’applications Dans la documentation du framework, des exemples d’application ont été introduit ce qui est de plus en plus souhaité pour les utilisateurs. C’est évidemment un choix judicieux pour la bonne utilisation de ce framework très large et très complexe (environ 150 classes). La documentation contient une section tutorials et samples. La section tutorials présente de façon détaillée un cas d’utilisation du framework en montrant et documentant du code source (un exemple simple). La section samples implante des exemples d’application du framework beaucoup plus difficiles et réels compte tenu que 73
  75. 75. les tutoriels servent comme introduction. Nous avons donc beaucoup de ressources à notre disposition pour utiliser le framework judicieusement et rapidement. Figure 2-21 : Présentation des tutoriels 2.3.1.4 Le design du framework L’architecture du framework est très bien décrite ce qui est assez rare. L’architecture est représentée par des diagrammes de classes qui sont découpées comme le montre la Figure 2 -22 : 74
  76. 76. Figure 2-22 : découpage des diagrammes 75
  77. 77. Figure 2-23 : Architecture des classes d’affichage Les relations entre les classes sont très bien décrites ce qui nous donne une vision concrète de ce que nous utilisons. Nous n’avons aucune figure qui nous montre un diagramme de classe complet de JTGame. Le choix qui a été fait repose sur des diagrammes d’objets qui nous montrent bien les relations entre les différents objets. Voici la représentation plus « haut niveau » du framework : 76
  78. 78. Figure 2-24 : diagramme d’objets de JTGame Un niveau beaucoup plus détaillée nous est aussi présenté pour que nous puissions bien comprendre les interactions entre les objets compte tenu que le framework possède environ 150 classes. 2.3.1.5 Analyse de la documentation du framework JTGame À prime abord, nous pouvons affirmer que la techniques de documentation se base sur la combinaison des approches de Pattern (Motifs et design patterns) et cookBook. La documenation nous permet d’utiliser facilement et rapidement le framework ce qui est très typique de l’approche CookBook où la conception du framework ne nous intéresse pas. Ce qui nous fait dire que la technique des patterns a été utilisée, c’est la façon avec laquelle le découpage est effectué (modules->classes->méthodes). 77
  79. 79. Ceci dit, la documentation de ce framework est vraiment complète, détaillée, structurée et simple. Une documentation de ce type est très coûteuse et nous pouvons imaginer que les développeurs se sont doter d’outils tel que web++ ou autre pour l’extraction de la documentation du code source en C++. Il est implrtant de considérer ces outils lors du développement car sinon, l’extraction peut être longue et coûteuse. La documentation décrit le design en entier ce qui est typique des « frameworks » gratuit. Les « frameworks » à but lucratif sont généralement moins bien documenté pour ce qui est de la structure et de l’architecture. Nous devons donc conclure en disant que la documentation de JTGame est exemplaire et très bien structurée. Toutes les informations sont présentes et bien présentés. 78
  80. 80. 2.4 CONCLUSION Nous avons présenté la réutilisabilité et nous avons vu que pour être en mesure de réutiliser efficacement un framework, il nous faut de l’information utiles. Cette information se trouve dans la documentation qui devrait inévitablement accompagner le framework. Nous avons donc présenté les différentes techniques de documentation et nous avons montré un exemple de documentation qui est, à toute fin pratique, parfaite. La plupart des concepts de documentation tournent autour de ce type de documentation qui présente des exemples, le design, la structure et la description des classes. Avec autant d’information, il devient facile pour un développeur d’utiliser un framework car n’oubliez jamais : « Pour qu’un framework soit utilisé, il doit d’abord être compris » [Perron, 2002] :-). 79
  81. 81. 3 FRAMEWORK JAFIMA POUR LES SYSTÈMES AGENT Les agents se retrouvent dans une grande variété d’applications. Le fait qu’ils soient très utilisés à amené plusieurs problèmes. Le premier problème est dans le manque de consensus dans la définition des agents et des différentes fonctionnalités qu’ils possèdent. Un second problème concerne la duplication de l’effort de développement causé par l’absence de techniques générales et du manque de réutilisation. De plus, il y avait une incapacité à satisfaire les besoins industriels d’intégration des agents, qui doivent répondre aux critères de sécurité, à l’intérieur d’infrastructures et de logiciels existants. Finalement, l’incompatibilité entre les différents agents développés confirma que la standardisation des systèmes agent était nécessaire à leur succès. Ces différents problèmes ont donc poussé les gens à développer des frameworks pour les systèmes agents. Plusieurs années de recherche, de développement et d’implémentation de systèmes agents furent nécessaire à l’élaboration de techniques, de méthodologies et d’outils de développement robustes pour les systèmes agents. Le framework étudié dans le cadre du chapitre « A Framewrok for Agent Systems » du livre [Fayad & al] est JAFIMA (Java Framework for Intelligent and Mobile Agents). Étant donnée la nature très diversifiée des agents, ce framework est orienté sur l’architecture. Les classes du framework doivent être adaptées selon l’application, au lieu d’adapter les données au framework. JAFIMA se distingue des autres parce qu’il est plus complet et tient compte de plusieurs aspects relatifs aux différents types d’agents. De plus, il met l’accent sur les problèmes d’intégration mentionnés ci-dessus. JAFIMA fournit une définition détaillée d’un agent qui est suffisamment flexible pour englober les agents simples et sophistiqués, ainsi que les sociétés d’agents. Le design 80
  82. 82. d’agent est une architecture en couches, constituées de sous-framework. Le code du framework est en Java. 81

×