PCOO – TD 10

Transcription

PCOO – TD 10
PCOO – TD 10
Un exemple d’utilisation de la classe précédente est donné ci-dessous :
Exercice 1 : Dessins de glyphes
public class Picture extends JPanel {
La classe suivante permet de dessiner des glyphes à l’écran :
char[][] c2 = {{'#','#','#','#',' '},
{' ',' ',' ',' ','#'},
{' ','#','#','#',' '},
{'#',' ',' ',' ',' '},
{'#','#','#','#','#'}};
public class Glyph {
public enum DotType { Square, Circle }
private DotType type;
private char[][] matrix;
public Glyph(char[][] matrix, DotType type) {
this.matrix = matrix; this.type = type;
}
char[][] c3 = {{'#','#','#','#',' '},
{' ',' ',' ',' ','#'},
{' ','#','#','#',' '},
{' ',' ',' ',' ','#'},
{'#','#','#','#',' '}};
public void draw(Graphics g, int x, int y, int size) {
int n = matrix.length;
int ds = size / n;
for (int px = 0; px < n; px++)
for (int py = 0; py < n; py++)
if (matrix[py][px] == '#')
drawDot(g, x + px * ds + 1, y + py * ds + 1, ds - 1);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Glyph glyph2 = new Glyph(c2, Glyph.DotType.Circle);
Glyph glyph3 = new Glyph(c3, Glyph.DotType.Square);
g.setColor(Color.black);
glyph2.draw(g,
0, 0, 400);
glyph3.draw(g, 440, 0, 400);
}
}
private void drawDot(Graphics g, int x, int y, int size) {
switch (type) {
case Square: drawSquare(g, x, y, size); break;
case Circle: drawCircle(g, x, y, size); break;
}
}
Si une instance de la classe Picture est insérée dans une instance de la classe
JFrame, nous obtenons les deux glyphes suivants :
private void drawSquare(Graphics g, int x, int y, int size) {
g.fillRect(x + 1, y + 1, size - 1, size - 1);
}
private void drawCircle(Graphics g, int x, int y, int size) {
g.fillOval(x, y, size, size);
}
1. Quelles parties du code doivent être modifiées pour ajouter un nouveau
type de points en forme de croix ? L’utilisation de ce nouveau type de
points dans l’exemple précédent doit produire les glyphes suivants :
}
1
Les classes et les interfaces du diagramme de la question 6 devront pouvoir être
utilisées par la version de la méthode paintComponent suivante de façon à produire les glyphes situés en dessous de celle-ci :
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Drawable glyphC = new CircleDot();
Drawable glyphS = new SquareDot();
Drawable glyph2 = new Glyph(c2, new SquareDot());
Drawable glyph3 = new Glyph(c3, new CircleDot());
Drawable glyph22 = new Glyph(c2,
new Glyph(c2, new CircleDot()));
Drawable glyph33 = new Glyph(c3,
new Glyph(c3, new SquareDot()));
glyphC.draw(g, 10, 10, 100);
glyphS.draw(g, 120, 10, 100);
glyph2.draw(g, 300, 10, 100);
glyph3.draw(g, 420, 10, 100);
glyph22.draw(g, 10, 120, 300);
glyph33.draw(g, 320, 120, 300);
}
2. Parmi les 5 principes SOLID, lequel est violé ? Justifiez.
3. Donnez le diagramme de classes d’une nouvelle organisation du code qui
respecte les principes SOLID (en utilisant le patron de conception “Patron
de méthode”).
4. Implémentez le diagramme de classes que vous avez proposé à la question
3 et réécrivez en conséquence le code de la méthode paintComponent de la
classe Picture donnée en exemple.
5. Écrivez la classe permettant de dessiner les glyphes avec les points en
forme de croix évoqués à la question 1.
6. Donnez le diagramme de classes d’une nouvelle organisation du code
permettant de réaliser les glyphes situés dans la colonne de droite. Les
classes et les interfaces de votre diagramme doivent fonctionner avec le
code de la méthode paintComponent donnée à droite (par conséquent, les
classes ou interfaces Drawable, CircleDot, SquareDot et Glyph doivent
apparaître dans le diagramme).
7. Implémentez le diagramme de classes que vous avez proposé à la question 6.
2
Exercice 2 : Images
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.
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 :
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) :
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é.
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;
}
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.
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. 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.
3
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 :
public class MyImageUtil {
private Map<String, MyImageLoader> loaders;
public MyImageUtil() {
loaders = new HashMap<String, MyImageLoader>();
loaders.put("png", new MyPngLoader());
loaders.put("jpg", new MyJpgLoader());
loaders.put("gif", new MyGifLoader());
}
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);
}
}
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.
4

Documents pareils