Document ID: /fineweb-2-swissfilter-quality_10-filterrobots/filtered/06877.jsonl.gz/716

Activité : Gérons nos items, principe de substitution de Liskov et principe de ségrégation des interfaces
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 code des tests unitaires doit être utilisé tel quel et ne doit pas être modifié. Le code des classes doit être conforme à la spécification fournie sous forme de tests unitaires et de diagramme UML.
Le travail est individuel. Vous pouvez communiquer, mais en respectant le code d’honneur.
Situation
Vous êtes développeur dans un projet de logiciel de gestion de bibliothèque. Après la réunion avec le client, vous avez modifié les classes du système de gestion de bibliothèque en utilisant la relation « est un » entre les classes
Book,
Documentary et
Periodical et la classe
LibraryItem.
Lors d’une revue de code avec un collègue, celui-ci relève que vous utilisez le sous-typage (avec le mot clé
implements) à bon escient, car vous respectez le principe de substitution de Liskov (Liskov substitution principle, LSP, le L de SOLID). Il remarque, en effet, qu’il est possible d’utiliser une expression de type
Book,
Documentary ou
Periodical n’importe où une expression de type
LibraryItem est attendue et que cela est conforme au LSP qui stipule précisément qu’un type
S est un sous-type d’un super-type
T s’il est possible de substituer n’importe quelle expression de type
T par une expression de type
S. À ce propos, il précise que lors d’un code review, il vérifie toujours que les sous-types sont bien des sous-types selon la définition de Liskov, car ni Java ni aucun autre langage ne peut garantir le respect du LSP.
Votre collègue relève également qu’en utilisant le super-type
LibraryItem, vous respectez le principe ouvert-fermé (open-closed principle, OCP, le O de SOLID) qui stipule qu’une classe doit être ouverte pour l’extension et fermée pour la modification. Or, vous dit-il, grâce à cette interface, il est possible d’ajouter de nouvelles sortes d’items dans la bibliothèque sans avoir à modifier ni les classes qui correspondent aux sortes d’items existantes (
Book,
Documentary et
Periodical) ni la classe
Copy.
Il s’attarde ensuite sur les classes
Loan et
LoanManager et comme vous le voyez froncer un peu les sourcils vous lui demandez ce qui le dérange. Il vous répond que puisque vous connaissez maintenant la notion d’interface, on pourrait en faire usage pour améliorer le design de l’application en appliquant un autre principe SOLID : le principe de ségrégation des interfaces (interface segregation principle, ISP, le I de SOLID). Il vous explique que ce principe stipule qu’un client ne devrait pas dépendre de méthodes qu’il n’utilise pas. Or, vous fait-il remarquer, la classe
Loan expose des accesseurs sans doute utiles pour les tests, mais dont la classe LoanManager n’a pas besoin. Il vous propose donc de renommer la classe
Loan en
LoanImpl puis de créer une interface
Loan conformément au diagramme UML de la figure 1 et enfin de modifier l’instanciation des objets de type
Loan classe
LoanManager ;
Loan étant désormais une interface, l’instanciation (opérateur
new) doit se faire en utilisant le nom de la classe qui l’implémente (
LoanImpl).
Il poursuit en vous faisant remarquer que les classes
Author,
Writer et
Director sont identiques et représentent toutes des personnes ou, plus précisément, des noms de personnes. Il vous propose donc de ne faire qu’une seule classe
PersonName. Vous objectez qu’on ne sait alors plus qui est auteur, scénariste ou réalisateur. Il vous rétorque que le rôle d’une personne n’est pas une propriété intrinsèque de cette personne, une même personne peut avoir différent rôle selon le contexte dans lequel elle se trouve. C’est la relation entre le film et la personne qui détermine si la personne en est le scénariste ou le réalisateur. De plus, ajoute-t-il, il est possible qu’une personne soit tout à la fois scénariste et réalisateur. Pour finir, il vous suggère d’utiliser pour la classe
PersonName le même principe que pour
Loan, c’est-à-dire définir une interface
PersonName et une classe
PersonNameImpl qui implémente cette interface.
Pour finir, il remarque que les méthodes de la classe
LoanManager prennent en paramètre un objet de type
Copy mais qu’il n’utilise de cet objet que l’attribut
Id et rien d’autre. Cette fois, vous voyez où il veut en venir : cela va à l’encontre du principe de ségrégation des interfaces. Mais créer une interface avec un seul attribut vous semble exagéré. Lorsque vous lui faites part de votre réserve, il vous la concède et vous propose alors de passer en paramètre l’identificateur sous la forme d’une chaîne de caractère. L’avantage de ce nouveau design est que l’on voit apparaître un sous-système d’emprunt complètement découplé du reste. Vous révisez donc le modèle de l’application pour tenir compte de ces observations et vous obtenez les diagrammes des figures 1 et 2.
Résultat attendu
Un projet Maven contenant les classes décrites
Objectifs
À la fin de ce travail, vous devez :
- Connaître la relation « est un »
- Connaître la notion d’interface
- Connaître la différence entre type et classe
- Connaître les quatre premiers principes SOLID (SRP, OCP, LSP, ISP)
Ressources
Logiciel :
- maven
- Visual Studio Code
Documents :
Mise en route
Rendez-vous dans le répertoire de vos projets, lancez la commande ci-après et lorsque le système vous le demande, saisissez votre nom et votre mot de passe I-FR.
1 git clone https://gitlab.epai-ict.ch/m226/gerons-nos-items-lsp-isp.git --single-branch
Déplacez-vous dans le répertoire
gerons-nos-items-lsp-isp et lancer la commande
code . pour ouvrir le projet dans VSC (Visual Studio Code).
À vous de jouer !
Tâches
- Modifiez le projet pour qu’il corresponde aux diagrammes UML des figures 2 et 3.
Demandez de l’aide en cas de besoin, mais essayez d’abord par vous-même et respectez toujours le code d’honneur !