Activité Introduction aux patrons de conception : patrons de création d'objets (partie 2/3)
Objectifs
À la fin de ce travail, vous devez :
- Être capable d’expliquer l’utilité des patrons de conception de création (creational design pattern)
- Être capable de décrire et de distinguer les patrons de conception de création d’objets :
- « Static Factory Method »
- « Abstract Factory »
- « Builder »
En plus des objectifs principaux ci-dessus, vous devez :
- Connaître le principe de masquage de l’information (information hidding).
- Connaître les modificateurs
public
,private
etprotected
pour les membres (attributs et méthodes) d’une classe. - Être capable d’expliquer pourquoi un constructeur n’est jamais virtuel.
Consigne
Pour ce travail on vous demande de prendre connaissance de la situation et de réaliser les tâches proposées. Si vous ne parvenez pas à terminer le travail en classe, il vous appartient de prendre sur votre temps pour l’achever.
Le travail est individuel. Vous pouvez communiquer en respectant le code d’honneur.
Résultat attendu
- Un projet Maven contenant les classes décrites
- Un petit document où vous aurez décrit ce que vous avez fait et les difficultés que vous aurez rencontrées.
Ressources
Logiciel :
- Machine virtuelle de développement
- Visual Studio Code
Documents :
- Capsule de théorie : Classes et instances
- Capsule de théorie : Héritage et sous‑typage
- Capsule de théorie : Polymorphisme
Situation
Dans le cadre d’un projet de gestion de contacts, vous avez réalisé un « Data Mapper » qui présente une collection d’objets de type Person qui peut être chargée depuis différents formats de fichier.
Vous présentez votre travail au responsable du projet pour une revue de code. Pour documenter votre travail, vous avez réalisé les diagrammes des figures 1 et 2. Le premier est un diagramme de classes qui représente les relations et les dépendances entre les classes. Le second est un diagramme de séquence dont le but est de fournir une représentation temporelle des interactions (appels de méthodes) entre les objets (instances).
Le responsable du projet est plutôt satisfait de votre travail. En effet, il constate plusieurs choses intéressantes :
- Vous avez utilisé le patron de conception « Static Factory Method » proposé par Joshua Bloch pour instancier l’objet « factory » (
DataMapperFactory.newInstance
); - Ensemble, l’interface
DataMapperFactory
, la classeDataMapperFactoryImpl
et les sous-types dePersonDataMapper
forment une instance (légèrement simplifiée) du patron de conception « Abstract Factory », également un patron de conception du GoF. - Grâce à l’utilisation de ces patrons de conception de création (creational design patterns), le client de la bibliothèque (la classe App) dépend uniquement de classes abstraites (interfaces java) et nom de classes concrètes; le principe d’inversion des dépendances (dependency inversion principle) est de ce point de vue bien respecté.
Il voit cependant également quelques possibilités d’amélioration. Il remarque notamment que l’implémentation de la classe PersonDataMapperCsv
et PersonDataMapperXml
ne diffèrent que par l’implémentation de la méthode readFile
. Cela correspond à un « anti-pattern » connu sous le nom de « programmation copier/coller ». Avec un langage orienté-objet comme Java, on peut utiliser l’héritage pour éviter ce problème. Il vous propose donc le diagramme de la figure 3.
Il ajoute la remarque suivante : autant que possible, on respecte le principe de dissimulation d’information entre la classe de base et les classes dérivées. Cela signifie que les variables membres d’une classe de base doivent également être déclarées comme étant privées. L’initialisation des variables membres de la classe de base est la responsabilité du constructeur de la classe de base et non celle du constructeur de la classe dérivée. Un constructeur n’est donc jamais virtuel et ne peut pas être surécrit (overloaded). De plus, le constructeur d’une classe dérivée doit invoquer le constructeur de sa classe de base à l’aide du mot clé super
avant d’initialiser ses propre variables membres. Si la classe de base est abstraite, elle ne peut pas avoir de constructeur public. Dans ce cas, on utilise le modificateur protected
pour le rendre visible par les classes dérivées.
Mise en route
Faites une copie du projet de l’activité précédente.
Lancez la machine virtuelle de développement avec Vagrant. Lancez Visual Studio Code, connectez-vous à la machine virtuelle et ouvrez la fenêtre de terminal intégré.
Rendez-vous dans le répertoire de projets (~/projects
), puis dans le répertoire de votre nouveau projet et lancer la commande code -r .
pour l’ouvrir.
Tâches
- Modifiez votre code de telle sorte qu’il corresponde au diagramme de la figure 3.
- Expliquez ce qu’est une méthode virtuelle, une méthode virtuelle pure et une méthode non-virtuelle.
- En Java, comment indique-t-on qu’une méthode est (a) virtuelle (b) virtuelle pur (c) non-virtuelle ?
- Expliquez avec vos propres mots la manière dont on utilise le mot clé
super
dans le constructeur de la classe dérivée et la raison pour laquelle on procède ainsi. - Un constructeur peut-il être virtuel ? Justifiez votre réponse.
- Expliquez la raison pour laquelle il n’est pas recommandé d’utiliser le mot clé
protected
pour les variables membres. Quel principe cela violerait-il ? - Dans notre cas, par quel truchement la classe dérivée a-t-elle accès à la variable membre
persons
pour y ajouter les personnes qui se trouvent dans le fichier ? - Proposez une autre solution pour permettre à la classe dérivée d’ajouter des personnes dans la liste
persons
sans modifier sa visibilité (elle doit rester privée). - Réaliser deux tests unitaires pour vérifier le bon fonctionnement de la classe
PersonDataMapperXml
et celui de la classePersonDataMapperCsv
. Vous pouvez utiliser pour cela le fichier XML et le fichier CSV qui vous ont été fournis avec le projet. - Observez les classes
PersonDataMapperFileBase
,PersonDataMapperCsv
etPersonDataMapperXml
. Ces classes respectent-elles les principes SOLID ? Le cas échéant, indiquez quels principes ne sont pas respectés et justifiez votre réponse.
Attention : Documentez-vous et vérifiez, éventuellement à l’aide d’expériences, si le comportement correspond bien vos explications !