:: Enseignements :: ESIPE :: IMAC2 :: IMAC2 2020-2021 :: Object oriented programming in Java ::
[LOGO]

#12.en Some design and input-output


Exercice 1 - Digital basket

You will find below some code of the package fr.umlv.shopping allowing to represent digital books (with a title, an author and a price) together with a digital basket in which it is possible to add or remove books. It is possible to display the content of the basket and to compute its price. Tests are in the package fr.umlv.shopping.test.

The shop that sells books wants now to sell other types of digital contents: video games, or pre-paid cards... code is given below.
Video games have a title, a console-type and a price. Pre-paid cards have a value (integer) and a validity time in weeks. Their price is computed according to these two parameters.

The aim of this exercice is to refactor the code in order to be able to add such new content types to the basket. Actually, shop expects to sell in the future music or movies (in a format that is not yet defined), and we want to ease such forthcoming evolutions.

  1. Modify the provided code such that the basket support adding/removing books, video games or pre-paid cards.
  2. Check that remove works well in any case.
  3. Minimize code duplication (some code could probably be factorized).

Exercice 2 - Entrées-sorties

We now want to be able to save the items of a shopping cart in a file in textual form, respecting a particular format, in order to be able to reload them in memory later.

We choose the following saving format (which is deliberately a little naive). Each item is represented on a single line of text. This line starts with a string specifying which type of digital content it is ("B" for a Book, "G" for a VideoGame or "P" for a PrePaid card). Then, separated by a delimiter (a character string, say "#"), the different characteristics of each of these items.

  1. According to the architecture of classes, abstract classes and/or interfaces that you set up for the previous exercise, write the toTextFormat() methods necessary for the following code to produce the display indicated in the comment. Be careful, you must still try to have generic code by minimizing code duplication. In particular, we would like any media type to have this method toTextFormat() which returns a String.
    public class SaverLoader {
      // ...
      public static void main(String[] args) {
        var sdb = new Book("S. de Beauvoir", "Mémoires d'une jeune fille rangée", 990);
        System.out.println(sdb.toTextFormat());
        // B#990#Mémoires d'une jeune fille rangée#S. de Beauvoir
        var zelda = new VideoGame("The legend of Zelda", VideoGame.Console.WII, 4950);
        System.out.println(zelda.toTextFormat());
        // G#4950#The legend of Zelda#WII
        var pp100 = new PrePaid(10000, 10);
        System.out.println(pp100.toTextFormat());
        // P#10000#10
      }
    }
      
    Some constants, for the delimiter (#) and for item types (B, G, P) could be defined in the class SaverLoader:
    public class SaverLoader {
        static final String SEPARATOR = "#";
        static final String BOOK_TYPE = "B";
        static final String VIDEO_GAME_TYPE = "G";
        static final String PREPAID_TYPE = "P";
        ... 
    
  2. Now write in the SaverLoader class a saveInTextFormat method that takes as argument a list of digital items and a BufferedWriter stream; this method writes in the stream the strings produced by the toTextFormat methods of the different items of the list, separating them by line breaks. Thus, the items created in the previous question must be saved in a file by the following code (remember to create the path of the save file):
    var list = List.of(sdb, zelda, pp100);
    
    Path saveFilePath = ... ; // name of the save file: "saveFile.txt"  
    try(var writer = Files.newBufferedWriter(saveFilePath, 
                                         StandardCharsets.UTF-8, 
                                         StandardOpenOption.CREATE)) {
      SaverLoader.saveInTextFormat(list, writer);
    }
    
    Verify this file content!
  3. To read back this file, or another one formatted in the same way, we now need a loadFromTextFormat method that takes as parameter a stream of characters, read and returns a list of digital items built from the indications read in the stream. Write this method in the SaverLoader class.
    You can use the br.readLine() method to read the stream line by line, and the split() method of the String class to split a line according to a given separator passed in argument.
    Test it on the file created previously, using the try-with-ressources syntax.
  4. The file below contains items that have been saved using the ISO-8859-15 encoding, an extension of the Latin-1 encoding that includes the € symbol for example.
    Save this file (by right-clicking save-as...) and reuse the code you wrote in the previous exercise to load the items from this file.

Exercice 3 - Discount

Sometimes, customers order articles in several copies (at least two). In this case, a 5% discount is applied to all the items concerned.

  1. How can we efficiently manage the multiplicity of items?
  2. Modify the code so that the computation of the basket price takes this discount into account.
  3. To go further: use a Stream to calculate the price of the basket.