Comprendre le pattern Observable / Observer
Bonjour à tous.
Je me pose des questions existentielles sur mon utilisation du modèle de conception Observable / Observer. En clair, j'ai un code qui fonctionne et qui fait ce que je lui demande de faire (du moins en apparence) mais je ne suis pas certain que mon utilisation de ce pattern soit la bonne. Je précise que l'utilisation d'Observer/Observable est une contrainte de l'exercice.
Le besoin : Lorsque la valeur du slider (dans la classe...Slider) est modifiée, la valeur de la JTextField (dans la classe TempC) est modifiée en conséquence (et inversement). Pour ce faire, j'ai développé une classe Thermometre qui étend Observable. Tout va bien en qui concerne cette classe : lorsqu'on modifie la valeur de m_temp directement, les deux observers (Slider et TempC) sont notifiés.
Là où je suis moins sûr de mon code (et donc de ma compréhension), c'est dans l'implémentation des deux classes Slider et TempC (Oui, mes noms de classes sont pourris, mais OSEF hein ? :mrgreen: ). Lorsque la valeur du Slider est modifiée, TempC doit en être informé. Cette information doit (je pense) passer par l'intermédiaire de Thermometre, ce qui permet de notifier tous les Observers...Oui, mais du coup, Slider est aussi notifié du changement par Thermometre et se met à jour alors que c'est lui qui est à l'origine de la modification. C'est évidemment la même chose dans l'autre sens.
Est ce que c'est grave Docteur ? J'ai l'impression qu'il y a un truc que je n'ai pas saisi. J'espère que je suis clair. Si ce n'est pas le cas, posez les question d'abord et tapez ensuite :aie:
Merci d'avance pour votre aide précieuse !
La classe Thermometre
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
package iut.uml.obs;
import java.util.Observable;
public class Thermometre extends Observable {
private float m_temp;
public Thermometre() {
super();
m_temp = 20;
}
public float getTemp() {
return m_temp;
}
public void setTemp(float temp) {
this.m_temp = temp;
this.setChanged();
this.notifyObservers(this.m_temp);
}
} |
La classe Slider
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
|
package iut.uml.obs;
import java.awt.FlowLayout;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JFrame;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
@SuppressWarnings("serial")
public class Slider extends JFrame implements Observer {
private JSlider m_slider;
private Thermometre tm = null;
public Slider (Thermometre t) {
super("Celsius");
tm = t;
this.m_slider = new JSlider(1, -50, 50, 0);
this.m_slider.setMajorTickSpacing(10);
this.m_slider.setMinorTickSpacing(1);
this.m_slider.setPaintTicks(true);
this.setLayout(new FlowLayout());
this.setSize(100, 240);
this.setResizable(false);
this.m_slider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent ce) {
tm.setTemp((int)m_slider.getValue());
}
});
this.add(m_slider);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
@Override
public void update(Observable o, Object arg) {
m_slider.setValue((int)((Thermometre)o).getTemp());
}
} |
La classe TempC
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
|
package iut.uml.obs;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
@SuppressWarnings("serial")
public class TempC extends JFrame implements Observer {
private Thermometre tm = null;
private JLabel tempLabel;
private JTextField temp;
public TempC(Thermometre t) {
super("Celsius");
tm = t;
tempLabel = new JLabel("Température");
temp = new JTextField("20");
this.setLayout(new FlowLayout());
this.setSize(200, 80);
this.setResizable(false);
this.temp.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
tm.setTemp(Integer.parseInt(temp.getText()));
}
});
this.add(tempLabel);
this.add(temp);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
@Override
public void update(Observable o, Object arg1) {
temp.setText(Float.toString(((Thermometre)o).getTemp()));
}
} |
Le main
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
package iut.uml.obs;
public class Main {
public static void main(String[] args) {
Thermometre tm = new Thermometre();
Slider slider = new Slider(tm);
TempC tempc = new TempC(tm);
slider.setVisible(true);
tempc.setVisible(true);
tm.addObserver(slider);
tm.addObserver(tempc);
tm.setTemp(30);
}
} |