IFT785 Approches Orientées Objets FINAL Été 2002 2 e session d examen Début : Lundi 16 septembre 2002 à 9h00 am Remise : Jeudi 19 août 2002 à 9h00 am Professeur : Sylvain GIROUX Note : /100 points Remarques : Les énoncés sont flous à dessein. Il y aura plusieurs alternatives possibles. Vous devrez donc plusieurs décisions de design à prendre. N hésitez pas à les prendre. L examen est individuel. Vous pouvez en tout temps demandes des clarifications sur les questions, par contre aucune explication ne sera donnée sur la matière en tant que telle. Vous aurez besoin de programmer en Java. Pour ce faire, vous pouvez utiliser VisualAge ou tout autre environnement de développement. Vous devez utiliser JUnit pour écrire des tests. Vous recevrez l'examen par e-mail à 9 h00 AM le 16 septembre. Vous devez remettre vos réponses par e-mail avant 9hAM le 19 août. Prévoyez une journée pour la partie théorique et deux jours pour la partie pratique. L examen est long. Il est fort probable que vous ne réussissiez pas à tout faire parfaitement Faites des backups régulièrement de votre travail. Vous devrez remettre par e-mail sgiroux@dmi.usherb.ca o les fichiers jar contenant les programmes que vous aurez développés o un document texte contenant vos réponses aux questions théoriques.
PARTIE THEORIQUE (30 points) OBJVLISP : METACLASSES, CLASSES ET INSTANCES TERMINALES Question 1 Expliquer pourquoi en ObjVlisp, les classes sont considérées comme des objets à part entière, alors que ce n est pas tout à fait le cas en Java. Quelles en sont les conséquences? Qu est-ce qu on peut faire en ObjVlisp qu on ne peut pas faire en Java? En particulier, identifier les différences entre ces deux langages au niveau de la création des instances, de la création des classes, de la définition des méthodes et de la réflexivité. Le cas échéant, utiliser des schémas et des exemples pour appuyer votre argumentation. Question 2 a) Ecrire les classes et méta-classes nécessaires pour permettre à une instance ou une classe d avoir des variables indexées. Une variable indexée est une variable qui est accédée à l aide d un indice. Le nombre de variables indexée sera fixé à la création de l instance. Les indices seront numérotés à partir de 1. b) Implémenter la classe EquipeDeFootball dont les instances possèdent 11 variables indexées pour représenter les 11 joueurs sur le terrain. La classe EquipeDeFootball possède elle-même 17 variables indexées qui représentent les 17 règles. Ainsi nous pourrons écrire (send??? new :name EquipeDeFootball:supers (??? )) (send EquipeDeFootball? 1 (Loi 1 : Terrain de jeu.)) (send EquipeDeFootball? 2 (Loi 2 : Ballon.)) (setq Italie (send EquipeDeFootball new)) (send Italie? 10) Si vous ne connaissez pas Lisp, vous pouvez utiliser du pseudo-code et/ou des figures pour décrire votre réponse. Rappels : l accès à la valeur d une variable d instance se fait via la méthode «?» définie dans la classe Object. l accès à la valeur d une variable d instance se fait via la méthode «?» définie dans la classe Object. Il faudra redéfinir cette méthode. En ObjVlisp, l héritage multiple est permis.
PARTIE PRATIQUE (70 points) ÉTUDE DE CAS : INFORMATIQUE MEDICALE Etant donnée la désorganisation du système médical, vous avez été engagé pour y mettre un peu d ordre. Votre première tâche consiste donc à superviser le cheminement d un patient dans un hôpital pour qu il réalise et ne déroge pas à son plan de soins. Votre seconde tâche consistera à contrôler ou simuler le système hospitalier. Par chance (ou malchance), le directeur de l hôpital, qui est médecin, a trouvé sur le web un programme qui fait déjà presque tout (selon ses dires) et le problème à ses yeux est déjà pratiquement résolu. Plein d espoir, vous commencez à examiner le code du programme, (hospital1_0.jar). Le code est catastrophique, aux yeux du programmeur par objets émérite que vous êtes devenu! Les classes sont HospitalServices, Patient, PatientFile, Action, ClinicalTest, Medication, Diet, Meal. Un plan de soins est décrit par une méthode de la classe CarePlan(). Pour chaque type de plan, il faut écrire une méthode. Une étape dans un traitement correspond en général soit à une rencontre avec un spécialiste (par exemple, meetdoctor), soit à une tâche qui produit un artefact ( par exemple prelieveblood, analyseblood). Les différentes étapes liées à un traitement sont réalisées par l invocation de la méthode provide dans la classe HospitalServices. Une étape peut en entraîner une autre, par exemple la tâche prelieveblood doit être suivie de la tâche analyzeblood. Toute étapes (consultation, tâche, ) est facturable en fonction de sa catégorie. La classe Patient détient le montant total de la facture. La liste des étapes (consultation, tâches, etc.) et de leurs résultats, par exemple les résultats des tests sanguins, sont consignés dans le dossier d un patient.
Première étape : Refactorisation du code existant Les classes à partir desquelles vous devez travailler sont incomplètes, contiennent des erreurs, n utilisent pas les exceptions, sont remplies de conditionnelles. Le code est extrêmement difficile à modifier... Par conséquent, vous avez décidez qu un peu de refactorisation ne ferait pas de mal. Question 1 : Tests et JUnit Avant de commencer la refactorisation de ce programme, écrire quelques tests pour s assurer que le comportement du programme sera préservé. A l aide de JUnit, implémentez 10 tests unitaires (méthodes). Question 2 : Refactorisation et poly morphisme Refactorisez le programme. En particulier, faites disparaître les conditionnelles qui se trouvent dans les méthodes provide et bill de la classe HospitalServices. Vous aurez peut-être besoin d utiliser la réflexivité pour trouver les opérations qu offre une unité et/ou pour invoquer la méthode appropriée pour effectuer cette opération. Question 3 : Ajout de fonctionnalités L état actuel du programme que vous avez entre les mains est nettement insuffisant pour atteindre vos objectifs de supervision et de contrôle du système hospitalier. Ajouter les fonctionnalités suivantes au programme a) La classe HospitalService deviendra le point d accueil pour diriger les patients vers le bon service. Utiliser le Singleton Design Pattern pour vous assurer qu il n y aura qu un seul point d accueil dans le système. b) Subdivisez l hôpital en unités. Les unités à implémenter sont o unité de prélèvements, o unité des analyses de laboratoire, o unité d imagerie (radiologie et échographie), o unité de gynécologie (rencontre avec les médecins), o cafeteria. c) Actuellement un patient ne connaît que le montant total à payer. Implémentez un système de facturation détaillée. Ainsi en plus du total à payer, le patient recevra le détail des opérations facturées. d) Encapsulez les étapes du plan de soins sous forme de commande. Pour ce faire, utiliser le Command Design Pattern. e) Dans les unités, utiliser le Template Method Design Pattern pour introduire un prétraitement et un post-traitement des commandes.
f) Implémentez des événements représentant le début et la fin de l exécution d une commande. A l aide de votre implémentation du Template Method, déclenchez des événements au début et à la fin d une étape. g) Dans un système hospitalier des unités peuvent être ouvertes ou fermées temporairement. De nouvelles machines peuvent être achetées. Des machines existantes peuvent tomber en panne. Implémenter des événements correspondant à l ajout /retrait d unités et d opérations. Rappel : Les événements sont liés au Observer Design Pattern. Deuxième étape : Monitoring Epitalk est un framework qui permet de surveiller si l exécution d un système est correcte sans le modifier en greffant un système épiphyte sur lui. Dans Epitalk, un plan est représenté sous forme d arbre. Les feuilles de cet arbre sont associées à des événements déclenchés dans le système à observer. Lorsqu un nouvel objet est inséré dans le système hôte, la racine est informé de l arrivée de cet objet dans le système, elle en informe ses fils qui réagissent de la manière suivante Si le nœud est non terminal, alors transmettre l information aux fils Si le nœud est terminal, alors regarder si l objet déclenche des événements qui l intéressent, par exemple en utilisant java.beans.introspector pour obtenir le BeanInfo associé à cet objet. Si le nœud terminal est intéressé par ces événements, il se greffe dessus, c est-à-dire il s ajoute comme listener) Lorsqu un nœud (terminal ou non) reçoit de l information (par exemple, le déclenchement d un événement), il l analyse, puis, si nécessaire, il retransmet l information pertinente à son père, ainsi de suite jusqu à la racine. Dans ce qui suit, vous devez d abord implémenter le framework Epitalk, puis vous devez l utiliser pour que l on puisse ainsi s assurer qu un patient respecte bien les étapes et les consignes relatives à son plan de soins. Un traitement tel que décrit dans la méthode treat de la classe treatment représente en fait les feuilles d un plan de soins (voir la figure ci-dessous).
Prélever un Test d urine Diagnostic du diabète Prélever un Diagnostic Tests sanguins échantillo Diagnostic du développement du foetus Echographie Plan de soins Traitement Voir le docteur (établir le diagnostic) Prescrire une diète Prélever un Vérification Diagnostic du diabète Test d urine Tests sanguins Prélever un Question 4 : Epitalk Dans cette question, vous devez implémenter le framework Epitalk. a) Structure : A l aide du Composite Design Pattern, implémentez la représentation d un arbre des tâches. b) Greffe : A l aide de la réflexivité.et du Design Pattern Observer, implémentez la greffe d une feuille sur le système existant. Plus précisément, il s agit de pouvoir être informer quand un nouvel objet s ajoute au système observé
implémenter l algorithme qui va propager l information jusqu aux feuilles implémenter le processus de décision au niveau des feuilles pour décider de la greffe ou non de la feuilles sur cet objet implémenter la greffe comme telle en liant si un nouvel objet intéresse une feuille. Pour ce faire, vous pouvez utiliser o d une part le Adapater Design Pattern pour transformer les événements déclenchés par l objet en invocation de méthodes au niveau de la feuille o d autre part le Factory Method ou le Abstract Factory pour générer les bons adaptateurs. c) Raisonnement local : Définissez deux types de nœuds terminaux, ceux dont les fils doivent être effectuées dans l ordre et ceux pour lesquels ce n est pas important. d) Propagation de l information : Implémentez le parcours bottom-up de l information pour le monitoring Question 5 : Monitoring d un plan de soins Dans cette question, vous devez implémenter le plan de soins défini dans la figure ci-dessous. Plus précisément il faudra a) Construire l arbre des tâches correspondant. Dans cette arbre des tâches, vous devrez vous assurer que a. Les prélèvement précèdent les analyses. b. Les prélèvement précèdent la cafétéria, car il faut être à jeun pour les faire. c. Lors d une visite à la cafétéria, le repas pris ne transgresse pas la diète du patient. d. Résultat des analyses sont connus avant la consultation médicale. e. L arbre ne traite les données que d un seul patient qui sera spécifié à la création de l arbre. b) Ajouter cet arbre comme listener sur l instance unique de HospitalServices Question 6 : Simulation Troisième étape : Contrôle du système hospitalier Vous désirez maintenant modifier «légèrement» le framework Epitalk pour l utiliser pour faire de la simulation. a) Utilisez le Strategy design pattern pour transformer le parcours bottom-up en parcours top-down pour pouvoir simuler l exécution d une tâche. b) Utilisez le Command design pattern pour lancer les actions au niveau des feuilles terminales. Question 7 : Simulation d un plan de soins Utilisez votre système pour simuler le plan de soins défini dans la figure ci-dessus. FIN DE L EXAMEN