Semaine 12
Activité 2
Patron de conception Template method
Le patron de conception Template method est un patron comportemental qui permet de définir de manière générale un algorithme de traitement dans une classe abstraite avec des sections de l’algorithme à être définies (« implémentées ») dans les implémentations de la classe abstraite.
Dans le cadre des IHM, ce patron de conception permet de déléguer des spécificités techniques aux implémentations de composantes graphiques dans le cadre d’algorithmes communs. Par exemple, supposons que nous voulons créer une composante graphique représentant une forme géométrique à quatre côtés (un quadrilatère …) afin d’avoir une implémentation finale telles que un carré, un rectangle, un losange, etc. Dans tout ces cas, la structure de l’algorithme pour dessiner ces formes est commun :
- Dessiner le côté gauche
- Dessiner le côté haut
- Dessiner le côté droit
- Dessiner le côté bas
Même pour la forme losange, cet algorithme fonctionne. Toutefois, pour chaque forme, la longueur des traits et l’orientation de ceux-ci diffère. Grâce à l’usage de méthodes abstraites, la spécificité du traçage des côtés serait déléguée aux sous-classes héritant de la classe abstraite. Ainsi, le code nécessaire pour mettre en place ce patron s’écrirait ainsi (pour les besoins de l’exemple, je n’utilise pas la méthode drawRect de Graphics …):
import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import javax.swing.JComponent; public abstract class Quadrilatere extends JComponent { public Quadrilatere() { this.setPreferredSize(new Dimension(420,420)); } @Override public void paintComponent(Graphics g) { //Appelle de la méthode overide de JComponent super.paintComponent(g); g.setColor(Color.BLUE); traceCoteGauche(g); traceCoteHaut(g); traceCoteDroite(g); traceCoteBas(g); } public abstract void traceCoteGauche(Graphics g); public abstract void traceCoteHaut(Graphics g); public abstract void traceCoteDroite(Graphics g); public abstract void traceCoteBas(Graphics g); }
import java.awt.Graphics; public class Carre extends Quadrilatere { // Coordonné du centre de la forme int x,y; // Taille du carré int taille; public Carre(int x, int y, int taille) { this.x = x; this.y = y; this.taille = taille; } @Override public void traceCoteGauche(Graphics g) { int x1 = x - taille/2; int y1 = y - taille/2; int y2 = y + taille/2; g.drawLine(x1, y1, x1, y2); } @Override public void traceCoteHaut(Graphics g) { int x1 = x - taille/2; int x2 = x + taille/2; int y1 = y + taille/2; g.drawLine(x1, y1, x2, y1); } @Override public void traceCoteDroite(Graphics g) { int x1 = x + taille/2; int y1 = y - taille/2; int y2 = y + taille/2; g.drawLine(x1, y1, x1, y2); } @Override public void traceCoteBas(Graphics g) { int x1 = x - taille/2; int x2 = x + taille/2; int y1 = y - taille/2; g.drawLine(x1, y1, x2, y1); } }
public class NewJFrame extends javax.swing.JFrame { /** * Creates new form NewJFrame */ public NewJFrame() { initComponents(); Carre carre = new Carre(200, 200, 200); this.setContentPane(carre); } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code"> private void initComponents() { setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 400, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 300, Short.MAX_VALUE) ); pack(); }// </editor-fold> /** * @param args the command line arguments */ public static void main(String args[]) { /* Set the Nimbus look and feel */ //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. * For details see https://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html */ try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } //</editor-fold> /* Create and display the form */ java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new NewJFrame().setVisible(true); } }); } // Variables declaration - do not modify // End of variables declaration }
En résumé, le patron de conception Template method est utilisé dans les cas où pour un objet abstrait ayant un comportement pouvant être généralisé à ses classes hérités, nous déléguons la définition spécifique des sous-comportements de l’algorithme général aux sous-classes. Dans le cadre d’autres composantes graphiques, nous pourrions utiliser ce patron de conception afin de déléguer les choix esthétiques d’affichage de certaines sections selon le profil de l’utilisateur.