Session 2

Transcription

Session 2
Faculté des Sciences – Aix-Marseille Université – Site Luminy – Session 2 – Juin 2013 – Durée : 2 heures – SIN5U2TL – Licence 3 Informatique
Examen de PCOO – Licence 3 Informatique
1. Donnez les signatures des méthodes et des constructeurs des classes Png et
Jpg que vous pouvez déduire à partir du code de la classe MyImageUtil. Vous
supposerez que les largeurs et les hauteurs des images sont entières et que la
méthode load de la classe Png retourne une instance de Png.
Documents autorisés / Calculatrices interdites / Durée de l’épreuve : 2 heures
Exercice 1 : Images
2. Que doit-on modifier dans le code de MyImageUtil pour prendre en charge
le format d’image Gif en supposant que nous ayons à notre disposition une
classe Gif qui s’utilise de la façon suivante (la classe Gif n’est pas modifiable) :
Nous disposons de deux classes Png et Jpg permettant de charger des images aux
formats PNG et JPEG puis de consulter leurs tailles et la couleur des pixels de
l’image. Les classes Png et Jpg font partie de deux librairies différentes que vous
ne pouvez pas modifier. Un étudiant a écrit la classe suivante enfin de simplifier
l’utilisation de ces classes :
Gif gif = new Gif("dessin.gif");
int width = gif.getNbColumns();
int height = gif.getNbLines();
int x = 123, y = 234;
int colorIndex = gif.getColorIndex(x, y);
Color color = Gif.getPaletteEntry(colorIndex);
public class MyImageUtil {
public Object loadImage(String filename) {
String[] parts = filename.split("\\.");
String suffix = parts[parts.length-1];
if (suffix.equals("png")) return Png.load(filename);
if (suffix.equals("jpg")) return new Jpg(new File(filename));
return null;
}
3. Quel principe SOLID est violé par le code de la classe MyImageUtil ? Donnez
le sigle, la définition du principe et expliquez pourquoi il est violé.
4. Proposez le diagramme de classes d’un code qui corrige le problème constaté
à la question 3 à l’intérieur des méthodes getSize() et getColor() de
MyImageUtil de sorte que les lignes suivantes soient correctes. Dans ce diagramme, vous devez définir une interface MyImage et trois classes MyPng,
MyJpg et MyGif qui adaptent Png, Jpg et Gif à l’interface MyImage.
public Dimension getSize(Object image) {
if (image instanceof Png) {
Png png = (Png)image;
return new Dimension(png.getWidth(), png.getHeight());
}
if (image instanceof Jpg) {
Jpg jpg = (Jpg)image;
return jpg.getDimension();
}
return null;
}
String[] filenames = { "riri.jpg", "fifi.png", "loulou.gif" };
MyImageUtil imageUtil = new MyImageUtil();
for (String filename : filenames) {
MyImage image = imageUtil.loadImage(filename);
Dimension size = image.getSize();
System.out.println(size.width + "x" + size.height);
Color color = image.getColor(0, 0);
System.out.println(color);
}
public Color getColor(Object image, int x, int y) {
if (image instanceof Png)
return ((Png)image).getPixel(x, y);
if (image instanceof Jpg)
return ((Jpg)image).getColor(new Point(x,y));
return null;
}
5. Justifiez en quoi cette nouvelle organisation rétablit le principe SOLID.
6. Implémentez les classes et les interfaces que vous avez définies dans le diagramme de la question 4 et modifiez le code de MyImageUtil en conséquence.
}
1/2
Faculté des Sciences – Aix-Marseille Université – Site Luminy – Session 2 – Juin 2013 – Durée : 2 heures – SIN5U2TL – Licence 3 Informatique
7. Afin de minimiser les modifications à effectuer dans MyImageUtil pour ajouter un nouveau format, nous modifions le code de la méthode loadImage de
MyImageUtil comme suit :
Le code de la classe Grid<T> est donné ci-dessous. Il suppose que la grille est
non vide et qu’elle est rectangulaire, c’est-à-dire que toutes les lignes ont le même
nombre de colonnes.
public class MyImageUtil {
private Map<String, MyImageLoader> loaders;
public class Grid<T> implements Iterable<T> {
private T[][] elements;
public MyImageUtil() {
loaders = new HashMap<String, MyImageLoader>();
loaders.put("png", new MyPngLoader());
loaders.put("jpg", new MyJpgLoader());
loaders.put("gif", new MyGifLoader());
}
public Grid(T[][] elements) { this.elements = elements; }
public T get(int line, int column) {
return elements[line][column];
}
public int nbLines()
{ return elements.length; }
public int nbColumns() { return elements[0].length; }
public MyImage loadImage(String filename) {
String[] parts = filename.split("\\.");
String suffix = parts[parts.length - 1];
MyImageLoader loader = loaders.get(suffix);
if (loader == null) return null;
return loader.load(filename);
}
public Iterator<T> iterator() {
return new GridIterator<T>(this);
}
}
}
1. Qu’affiche le code donné en début d’exercice ?
Donnez le code de l’interface MyImageLoader et des classes MyPngLoader,
MyJpgLoader et MyGifLoader afin que le code donné ci-dessus ait le même
comportement que l’ancienne version de la méthode loadImage.
2. Donnez l’équivalent du code suivant en utilisant explicitement les méthodes
T next() et boolean hasNext() de l’interface Iterator<T> (c’est-à-dire
sans la syntaxe spéciale du for) :
Exercice 2 : Itérateur sur des grilles
for (String element : grid) System.out.print(element+" ");
System.out.println();
On considère le code suivant manipulant une classe générique Grid<T> :
String[][] elements = { { "A", "D", "G", "J" },
{ "B", "E", "H", "K" },
{ "C", "F", "I", "L" } };
Grid<String> grid = new Grid<String>(elements);
for (int line = 0; line < grid.nbLines(); line++)
for (int column = 0; column < grid.nbColumns(); column++) {
String element = grid.get(line, column);
System.out.print(element+" ");
}
System.out.println();
3. Implémentez la classe GridIterator<T> de sorte que le code donné à la
question 2 produise la même sortie que le code donné en début d’exercice.
Vous devez :
a. préciser la déclaration de la classe ;
b. préciser quels sont les attributs de la classe ;
c. Implémenter les méthodes T next() et boolean hasNext().
On ne demande pas d’implémenter la méthode void remove() de l’interface
Iterator<T>.
2/2