nfp121 cours 04 programmation evenementielle
DESCRIPTION
java eventTRANSCRIPT
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
1/59
NFP1211
NFP121, Cnam/ParisCours 4
Patrons Observateur/MVCprogrammation vnementielle
Notes de cours
jean-michel Douin, douin au cnam point fr
version : 14 Octobre 2010
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
2/59
NFP1212
Sommaire
Patron Observateur
Programmation vnementielle
Patron MVC Modle Vue Contrleur
Patron Publish-Subscribe en annexe
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
3/59
NFP1213
Principale bibliographie utilise
[Grand00] Patterns in Java le volume 1
http://www.mindspring.com/~mgrand/
[head First]
Head first : http://www.oreilly.com/catalog/hfdesignpat/#top
[DP05] Lextension Design Pattern de BlueJ : http://hamilton.bell.ac.uk/designpatterns/
[divers]
Certains diagrammes UML : http://www.dofactory.com/Patterns/PatternProxy.aspx informations gnrales http://www.edlin.org/cs/patterns.html
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
4/59
NFP1214
Patrons/Patterns pour le logiciel
Origine C. Alexander un architecte
Abstraction dans la conception du logiciel [GoF95] la bande des 4 : Gamma, Helm, Johnson et Vlissides
23 patrons/patterns
Architectures logicielles
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
5/59
NFP1215
Introduction : rappel
Classification habituelle
Crateurs
Abstract Factory, Builder, Factory Method Prototype Singleton
Structurels
Adapter Bridge Composite Decorator Facade Flyweight Proxy
ComportementauxChain of Responsability. Command Interpreter Iterator
Mediator Memento Observer StateStrategy Template Method Visitor
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
6/59
NFP1216
Les patrons dj vus
Adapter Adapte linterface dune classe conforme aux souhaits du client
Proxy Fournit un mandataire au client afin de contrler/vrifier ses accs
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
7/59
NFP1217
Patron Observ/observateur 1)
Notification dun changement dtat
dune instance aux observateurs inscrits
Un Observ Nimporte quelle instance qui est modifie
i.e. un changement dtat comme la modification dune donne dinstanceusage dun mutateur, par exemple
Des Observateurs, ils seront notifis A la modification de lobserv, Synchrone, ( et sur la mme machine virtuelle)
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
8/59
NFP1218
Patron Observ/observateur 2)
Plusieurs Observs / un observateur Un Observateur peut observer plusieurs instances
Plusieurs Observs / plusieurs observateurs
Ajout et retrait dynamiques dobservateurs
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
9/59
NFP1219
UML & le patron Observateur, loriginal
http://www.codeproject.com/gen/design/applyingpatterns/observer.gif
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
10/59
NFP12110
Observateur en Java
Lors dun changement dtat notification aux observateurs inscrits
public interface Observer{
public void update(Observable o);
}
public interface Observable{
public void addObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
public int getState();
public void setState(int state);
}
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
11/59
NFP12111
ConcreteObservable
public class ConcreteObservable implements Observable{private Collection observers = new
private int state = 0;
public void addObserver(Observer observer){
observers.add(observer);
}public void removeObserver(Observer observer){
observers.remove(observer);
}
public void notifyObservers(){
for(Observer obs : observers)
obs.update();
}}
public void setState(int state){
this.state = state;
notifyObservers();
}}
public int getState(){return this.state;}
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
12/59
NFP12112
Observer : mise en oeuvre
Observable o = new ConcreteObservable();
Observer obs1= new ConcreteObserver();
o.addObserver(obs1);
o.setState(3); // obs1 est rveill, notifi
Observer obs2= new ConcreteObserver();
o.addObserver(obs2);
o.setState(33); // obs1 et obs2sont rveills, notifis
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
13/59
NFP12113
Dmonstration / discussion
Variante syntaxique Observ est une classe abstraite Observateur est une interface
Une liste est un Observ concret Un Observateur de Liste implmente linterface Observateur
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
14/59
NFP12114
Notification amlioration
Lobservable pourrait tre encapsul :public interface Observer{
public void update(Source src);}
Class Source
Observable obs;Object Paramtre
}
ou nous pourrions ajouter des paramtres
public interface Observer{public void update(Observable o, Object erg);
}
public interface Observer{
public void update(Observable o);
}
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
15/59
NFP12115
Observer : Encapsulation, EventObject
A chaque notification un event object est transmis
public interface Observer{
public void update(java.util.EventObject evt);}
package java.util;
public classpublic classpublic classpublic class EventObjectEventObjectEventObjectEventObject extendsextendsextendsextends ObjectObjectObjectObject implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable{{{{
publicpublicpublicpublic EventObjectEventObjectEventObjectEventObject((((ObjectObjectObjectObject source){ }source){ }source){ }source){ }
publicpublicpublicpublic ObjectObjectObjectObject getSourcegetSourcegetSourcegetSource(){ }(){ }(){ }(){ }
publicpublicpublicpublic StringStringStringString toStringtoStringtoStringtoString(){ }(){ }(){ }(){ }
}}}}
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
16/59
NFP12116
Observ/Observateurs
Prdfinies paquetage java.util
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
17/59
NFP12117
java.util, java.awt.event et plus
java.util.Observer & java.util.Observableupdate addObserver
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
18/59
NFP12118
java.util.Observer
public interface Observer{void update(Observable o, Object arg);
}
LObserv est transmis en paramtre Observable o
accompagn ventuellement de paramtres Object arg
update est appele chaque notification
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
19/59
NFP12119
java.util.Observable
public class Observable{public void addObserver(Observer o) ;
public void deleteObserver(Observer o) ;
public void deleteObservers() ;public int countObservers() ;
public void notifyObservers() ;
public void notifyObservers(Object arg) ;
public boolean hasChanged() ;
protected void setChanged() ;
protected void clearChanged() ;}
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
20/59
NFP12120
Un Exemple : une liste et ses observateurs
Une liste est observe, chaque modification de celle-ci,ajout, retrait, les observateurs inscrits sont notifis
public class Liste extends java.util.Observable{
public void ajouter(E e){
// modification effective de la liste
setChanged(); // ltat de cette liste a chang
notifyObservers(e); // les observateurs sont prvenus
}
Une liste ou nimporte quelle instance
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
21/59
NFP12121
Un Exemple : un observateur de la liste
Liste l = new Liste();
l.addObserver( new Observer(){public void update(Observable o,Object arg){
System.out.print( o + " a chang, " );
System.out.println( arg + " vient d'tre ajout !");
}});
Cest tout ! dmonstrationCest tout ! dmonstrationCest tout ! dmonstrationCest tout ! dmonstration
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
22/59
NFP12122
Observateur comme Listener
java.awt.event.EventListener Les couteurs/observateurs sont tous des EventListener
Convention syntaxique de Sun pour ses API XXXXXListener extends EventListener update
addXXXXXListener
addObserver
exemple linterface ActionListener / addActionListener
EventObject Source de la notification, XXXXXEvent extends EventObject
exemple ActionEvent
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
23/59
NFP12123
Observateur comme XXXXListener
Une grande famille !
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
24/59
NFP12124
Une IHM et ses couteurs
Chaque item est un sujet observable avec ses couteurs
Pour un Bouton , chaque clic les couteurs/observateurs sont prvenus
public class Button extends Component{
public void addActionListener(ActionListener al){
}
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
25/59
NFP12125
Un bouton prvient ses couteurs
Button b = new Button("empiler");
b.addActionListener(unEcouteur); // 1
b.addActionListener(unAutreEcouteur); // 2b.addActionListener(
new ActionListener(){ // 3 couteurs
public void actionPerformed(ActionEvent ae){
System.out.println("clic !!! ");
}
});
Une instance de la classe java.awt.Buttonprvient
ses instances inscrites java.awt.event.ActionListener
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
26/59
NFP12126
Un couteur comme Action Listener
import java.util.event.ActionListener;
import java.util.event.ActionEvent;
public class EcouteurDeBouton
implementsActionListener{
public void actionPerformed(ActionEvent e){
// traitement chaque action sur le bouton
}
}
//c.f. page prcdente
ActionListener unEcouteur = new EcouteurDeBouton();
b.addActionListener(unEcouteur); // 1
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
27/59
NFP12127
Dmonstration / Discussion
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
28/59
NFP12128
API Java, patron Observateur, un rsum
Ajout/retrait dynamiques des observateurs ou couteurs
Lobservable se contente de notifier Notification synchrone tous les observateurs inscrits
API prdfinies java.util.Observer et java.util.Observable
Listener comme Observateur La grande famille des EventListener / EventObject
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
29/59
NFP12129
patrons Observer / MVC
Modle Vue Contrleur
agit, modifie le Modle
Observs / Observateurs
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
30/59
NFP12130
MVC : Observer est inclus
Observable
Modle
Observer
Vue
(update)
(getState)
(setState)
Contrleur
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
31/59
NFP12131
MVC : exemple de capteurs
Une architecture simple et souple
CapteursContrleur
Liste des mesures
Modle
Histogramme
Vue
(1)
(2)
(3)
MVC A t s
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
32/59
NFP12132
MVC Avantages
Souple ?
Capteurs
Contrleur
Liste des mesuresModle
(1)
Capteurs
ContrleurCapteurs
ContrleurCapteursContrleur
CapteursContrleur
Capteurs
Contrleur
(1)
Histogramme
Vue
(3)
HistogrammeVueHistogrammeVue
Histogramme
VueHistogramme
Vuegraphique
Vue
(2)
(2)
(3)
U l MVC
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
33/59
NFP12133
Un cycle MVC
Utilisateur
Contrleur Vue
Modle
1
2 inscription3
4
U l MVC l b t il
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
34/59
NFP12134
Un cycle MVC, le bouton empiler
Utilisateur
Contrleur Vue
Modle
Clic !
empiler inscriptionnotification
4
D t ti / MVC ti
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
35/59
NFP12135
Dmonstration / MVC en pratique
Un Modle Plusieurs Contrleurs
Plusieurs Vues
Dm st ti : l M dl i E ti
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
36/59
NFP12136
Dmonstration : le Modle i.e. un Entier
import java.util.Observable;
public class Modle extends Observable{
private int entier;
public int getEntier(){
return entier;
}
public String toString(){
return "entier : " + entier;
}
public void setEntier(int entier){
this.entier = entier;setChanged();
notifyObservers(entier);
}
}
Vue
Modle
update
notifyObservers
Dmonstration : une Vue
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
37/59
NFP12137
Dmonstration : une Vue
public interface Vue{
public void afficher();
}
import java.util.Observable;
import java.util.Observer;
public class Vue1 implements Vue, Observer{
private Modle modle;
public Vue1( Modle modle){ // inscription auprs du modle
this.modle = modle;
modle.addObserver(this);
}
public void afficher(){
System.out.println(" Vue1 : le modle a chang : " + modle.toString());
}
public void update(Observable o, Object arg){ // notification
if(o==modle) afficher();
}
}
Vue
Modle
toString
afficherupdate
Dmonstration : un contrleur
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
38/59
NFP12138
Dmonstration : un contrleur
public class Contrleur1{
private Modle modle;
public Contrleur1(Modle modle){
this.modle = modle;
}
public void incrmenter(){
modle.setEntier(modle.getEntier() +1);
}
}
Contrleur
Modle
setEntier
incrmenter
Un modle une vue un contrleur
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
39/59
NFP12139
Un modle, une vue, un contrleur
// Un Modle
Modle modle = new Modle();
// Ce modle possde une vue
Vue vue = new Vue1(modle);
// un Contrleur ( dclenche certaines mthodes du modle)
Contrleur1 contrleur = new Contrleur1(modle);
contrleur.incrmenter();
contrleur.incrmenter();
}
Un modle deux vues deux contrleurs
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
40/59
NFP12140
Un modle, deux vues, deux contrleurs
// Un Modle
Modle modle = new Modle();
// deux vues
Vue vueA = new Vue1(modle);
Vue vueB = new Vue1(modle);
// 2 Contrleurs
Contrleur1 contrleurA = new Contrleur1(modle);
Contrleur1 contrleurB = new Contrleur1(modle);
contrleurA.incrmenter();contrleurB.incrmenter();
Discussion
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
41/59
NFP12141
Discussion
Modle
(1)
Capteurs
ContrleurContrleurA
(1)(3)
Histogramme
VueVueA
(2)
(2)
(3)
AWT / Button discussion
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
42/59
NFP12142
AWT / Button, discussion
Un Button (le contrleur) contient un MVC part entire
Text, TextField, Label, sont des Vues
Button, Liste, sont des contrleurs
Une IHM (JApplet,) contient la Vue et le Contrle Alors le compromis architecture/lisibilit est rechercher
Un JButton comme MVC
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
43/59
NFP12143
Un JButton comme MVC
Au niveau applicatif appel de tous les observateurs inscrits actionPerformed(ActionEvent ae ), interface ActionListener
Utilisateur
IHM JButton Vue du JButton
JButton
Clic !
change Modifier laspect duJButton
4
Proposition c f le TP
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
44/59
NFP12144
Proposition c.f. le TP
MVC propos : Le Contrleur est un JPanel,
Transforme les actions sur les boutons ou lentre dune oprande en oprations sur le Modle
Le Modle est une Pile Est un Observable
La Vue est un JPanel, Observateur du Modle, la vue affiche ltat du Modle chaque notification
contrleur
Vue
ou bien Le Modle est une calculette qui utilise une pile
Est un Observable
Proposition : MVC Imbriqus
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
45/59
NFP12145
C
modle
pile
V
Proposition MVC Imbriqus
Architecture possible Le contrleur inclut la gestion des actions de lutilisateur Niveau 1 : Gestion des Listeners
Niveau 2 : Observable et Observer
MVC doc de Sun
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
46/59
NFP12146
MV doc de Sun
http://java.sun.com/blueprints/patterns/MVC-detailed.html
Nouvelle Proposition
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
47/59
NFP12147
p
MVC propos : Le Contrleur implmente tous les listeners
Transforme les actions sur les boutons ou lentre dune oprande en oprations sur le Modle
Le Modle est une Pile Est un Observable
La Vue est un JPanel, Observateur du Modle, la vue affiche ltat du Modle chaque notification
contrleur
Vue
Le Modle est une calculette qui utilise une pile
Est un Observable
IHM et MVC assez rpandu
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
48/59
NFP12148
p
Discussion Evolution, maintenance, la recherche du couplage faible Exemple
peut-on changer dIHM ?, peut-elle tre supprime ?peut-on placer le modle sur une autre machine ?
Conclusion
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
49/59
NFP12149
MVC Trs utilis
Couplage faible obtenu
Intgration claire du patron Observateur
Modle Vue Contrleur (MVC) est une mthode de conception pour le dveloppement
d'applications logicielles qui spare le modle de donnes, l'interface utilisateur et la logique
de contrle. Cette mthode a t mise au point en 1979 par Trygve Reenskaug, qui travaillait
alors sur Smalltalk dans les laboratoires de recherche Xerox PARC[1].
Extrait de http://fr.wikipedia.org/wiki/MVC
Observer distribu ? Un petit pas franchir
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
50/59
NFP12150
p p
Synchrones/asynchrones ? Technologies java comme rmi, JMS (Java Messaging Service), JINI
Voir le Patron publish-subscribe
Observable
1) notifyObservers
Observer A
Observer B
Observer C
2) update
3) update
4) update
Annexe : web MVC, JSP model
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
51/59
NFP12151
Web MVC rechercher sur le web voir aussi Multi-model MVC
Publish-subscribe
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
52/59
NFP12152
Patron Observateur/Observ Les observateurs sont rveills chaque notification
Filtrage des sources dvnements ?
Patron Publish/Subscribe Observateurs inscrits auprs dun mdiateur pour un thme Les Observs notifient au mdiateur sur ce thme
Publish/subscribe
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
53/59
NFP12153
Extrait de http://www2.lifl.fr/icar/Chapters/Intro/intro.html
Un exemple, le diagramme de squences
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
54/59
NFP12154
Une notification dvnements mto et de valeurs dun sensor (p1,p2 : Publisher), Un mdiateur de gestion des abonnements et de notifications (mediator), Deux souscripteurs aux thmes mto et sensor (s1, s2 : Subscriber).
mediator : Mediatorp1 : Publishers1 : Subscriber
s2 : Subscriber
p2 : Publisher
addSubscriber (s1, meteo )
publish (p1, meteo ,"sun ")
update (p1, meteo ,"sun ")
addSubscriber (s2, sensor )
publish (p2, sensor ,"25")
update (p1, meteo ,"rain ")
publish (p1, meteo ,"rain ")
publish (p1, meteo ,"sun ")
update (p1, meteo ,"sun ")
publish (p2, sensor ,"27")
update (p2, sensor ,"27")
addSubscriber (s2, meteo )
publish (p1, meteo ,"sun ")
update (p1, meteo ,"sun ")
update (p1, meteo ,"sun ")
Diagramme de classes UML/BlueJ
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
55/59
NFP12155
MediatorI
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
56/59
NFP12156
public interface MediatorI{
/** Ajout d'un souscripteur pour ce thme de publication.
* Une seule occurrence dun souscripteur par thme.
* @param subscriber le souscripteur.
* @param topic le thme de publication.
*/
public void addSubscriber(SubscriberI subscriber, Topic topic);
/** Publication sur ce thme.* Appel de la mthode update de chaque souscripteur
* @param source l'metteur de la publication.
* @param topic le thme de publication.
* @param arg les arguments lis au thme.
*/
public void publish(Object source, Topic topic, Object arg);
}
SubscriberI, PublisherI
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
57/59
NFP12157
public interface SubscriberI{/** Notification sur ce thme.
* @param source l'metteur.
* @param topic le thme de publication.
* @param arg les arguments lis au thme.
*/
public void update(Object source, Topic topic, Object arg);
}
public interface PublisherI{/** Notification sur ce thme.
* @param mediator le mediator concern.
* @param topic le thme de publication.
* @param arg les arguments lis au thme.
*/
public void publish(MediatorI mediator, Topic topic, Object arg);
}
Topic, les thmes possibles
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
58/59
NFP12158
public class Topic implements Serializable{public final static Topic ALL = new Topic(){
public String toString(){
return "TOPIC_ALL";
}
};
// mthodes toString, equals et hashCode redfinies
//}
les classes Meteo et Sensor, hritent de Topic.Si un souscripteur souhaite tre notifi quelque soit le thme,
il choisira le thme la constante Topic.ALL.
Main, associ au diagramme de squences
-
5/22/2018 NFP121 Cours 04 Programmation Evenementielle
59/59
NFP12159
public static void main(String[] args) throws Exception{
Topic meteo = new Meteo();
MediatorI mediator = new Mediator();
SubscriberI s1 = new Subcriber("s1");
PublisherI p1 = new Publisher("p1");
mediator.addSubscriber(s1, meteo);
mediator.publish(p1,meteo,"sun");
mediator.publish(p1,meteo,"rain");
Topic sensor = new Sensor();
PublisherI p2 = new Publisher("p2");
SubscriberI s2 = new Subcriber("s2");
mediator.addSubscriber(s2, sensor);
mediator.publish(p1,meteo,"sun");
mediator.addSubscriber(s2, meteo);
mediator.publish(p2,sensor,"27");
mediator.publish(p1,meteo,"sun");
}