:: Enseignements :: Licence :: L3 :: 2021-2022 :: Programmation Objet avec Java ::
[LOGO]

Interface et Collection


Exercice 1 - Refuge

On souhaite écrire un logiciel permettant de gérer un refuge pour chiens. Pour cela, dans un premier temps, nous allons créer un record Dog (avec un nom name et un poid entier weight en kg), ainsi qu'une classe Shelter qui contiendra les chiens du refuge.
En termes de gestion, on veut deux choses : avoir une liste des chiens du refuge et savoir combien de croquettes (biscuits in English) il faut par jour pour nourrir tous les chiens, sachant qu'un chien consomme à peu près 7.3 fois son poid en croquettes.
Note : pour le nombre de croquettes par chien, mettez-le en constante. Comme cela, on pourra la changer facilement.

  1. Écrire un type Dog sachant que l'on veut que le code suivant fonctionne
         var scooby = new Dog("scooby doo", 21);
        

    Attention à ne pas oublier les pré-conditions.
  2. Écrire un type Shelter avec les méthodes add et removeAll qui permettent respectivement d'ajouter et de retirer des chiens du refuge. La méthode add prend en paramètre un seul chien et l'ajoute au refuge. La méthode removeAll prend en paramètre un nom de chien et retire du refuge tous les chiens ayant ce nom.
    Pour tester, écrire le code suivant dans la méthode main d'une classe Main et vérifier qu'il fonctionne correctement. Vous écrirez le code de test des questions suivantes à la suite.
         var shelter = new Shelter();
         shelter.add(new Dog("scooby doo", 21));
         shelter.removeAll("scooby doo");
        
  3. On veut changer removeAll pour renvoyer tous les chiens supprimés. Cela permettra, entre autres, de savoir si au moins un chien a été retiré du refuge.
          var shelter = new Shelter();
          shelter.add(new Dog("scooby doo", 21));
          var removedDogs = shelter.removeAll("scooby doo");
          System.out.println(removedDogs);
        

    Changer le code de removeAll pour renvoyer les chiens retirés du refuge.
    Note : faites attention au type de retour de removeAll
  4. Ajouter la possibilité d'afficher l'ensemble des chiens dans l'ordre d'ajout dans le refuge, ainsi qu'une méthode biscuits qui renvoie le nombre de biscuits qu'il faut pour une journée, pour tous les chiens du refuge.
    On veut que le code suivant fonctionne :
         var shelter2 = new Shelter();
         shelter2.add(new Dog("scooby doo", 21));
         shelter2.add(new Dog("idefix", 2));
         System.out.println(shelter2);
         System.out.println("biscuits " + shelter2.biscuits());
        

Exercice 2 - Arche de Noé

Désormais, dans le refuge, on ne veut plus gérer uniquement des chiens mais aussi des chats (et pourquoi pas, dans le futur, des poissons rouges ou des éléphants). On va donc introduire un type Cat sachant qu'un chat possède un nom (name) et un nombre de croquettes par jour (biscuits).

  1. Implanter le type Cat et modifier Shelter pour que l'on puisse ajouter et retirer des chats suivant leur nom (en fait, on retirera indifféremment des chiens et des chats du refuge, s'ils ont le nom passé en paramètre de removeAll).
    Le code suivant doit marcher
          var shelter3 = new Shelter();
          shelter3.add(new Dog("pongo", 15));
          shelter3.add(new Cat("garfield", 120));
          System.out.println(shelter3);
          System.out.println("biscuits " + shelter3.biscuits());
          var garfields = shelter3.removeAll("garfield");
          System.out.println(garfields);
        

    Note : bien sûr, vous n'avez pas oublié les préconditions pour un chat.
  2. Expliquer comment faire, en Java, pour ne pouvoir avoir que des chats et des chiens dans le refuge. On ne le fera pas ici, car on veut laisser la possibilité à un utilisateur de la librairie d'ajouter lui-même d'autres sortes d'animaux.
  3. Dans notre design, un chien ou un chat peut appartenir à plusieurs refuges. On veut empêcher cela pour les chiens (pas pour les chats, ils sont trop malins pour que l'on sache ce qu'ils font) même si cela rend la modélisation bien plus compliquée. À cette fin, pour les chiens, on va ajouter un champ shelter qui est null si le chien n'est pas dans un refuge, ou qui contient le refuge dans lequel le chien se trouve, sinon.
    Dans le cas où l'on essaie d'ajouter un chien à un refuge alors qu'il est déjà dans un refuge, une exception (à vous de trouver laquelle) devra être levée.
          var shelter4 = new Shelter();
          var tramp = new Dog("tramp", 12);
          shelter4.add(tramp);
          var shelter5 = new Shelter();
          shelter5.add(tramp);   // exception !
        

    Bien sûr, on veut que toutes les fonctionnalités que l'on a implantées précédemment continuent de fonctionner.
    Quels changements doit-on faire ? Pourquoi est-ce un gros changement ?
    Faire les modifications de code qui s'imposent et vérifier que les codes précédemment écrits continuent de fonctionner.
    Note : il y a deux façons de gérer un comportement différent, soit on dit que les chiens sont spéciaux, soit on dit que les chiens et les chats font parties de la même famille, mais se comportent différemment. En programmation objet, on choisira la seconde solution.
  4. Pour un refuge donné, il arrive que les chiens "élisent" un roi des chiens ; dans ce cas, le chien est marqué comme "king" si on affiche le refuge.
    En termes d'API, on veut ajouter une méthode isNowKing sur le type Dog qui indique que le chien est le roi de son refuge. Cela ne doit pas fonctionner si le chien n'est pas dans un refuge et deux chiens différents ne peuvent pas être roi d'un même refuge en même temps : si on indique qu'un chien est roi, le précédent roi du refuge perd son titre.
          var beethoven = new Dog("beethoven", 30);
          // beethoven.isNowKing();  // exception !
          var shelter6 = new Shelter();
          shelter6.add(beethoven);
          beethoven.isNowKing();
          System.out.println(shelter6);
          // Dog[name=beethoven, weight=30] king
        

    En termes d’implantation, essayer de ne pas représenter la même information (le chien est roi) à plusieurs endroits.
  5. De façon optionnelle, si vous êtes balèze, faire en sorte qu'il ne puisse pas y avoir des chats et des chiens de même nom dans le refuge.
    Par exemple, pas possible d'avoir un chien et un chat nommés "doug" dans le même refuge :
          var shelter7 = new Shelter();
          shelter7.add(new Dog("doug", 20));
          shelter7.add(new Cat("doug", 117));  // exception !
        

    Pour cela, mettez en commentaire le code précédent de Shelter et ré-implantez la classe avec une structure de données différente. Profitez-en pour accélérer le temps d'exécution de la méthode remove
    Note : attention, l'ordre d'affichage doit toujours être l'ordre d'insertion.