1
IMPLANTER LE PARADIGME MVC AVEC RMI
UNE SOLUTION (AVEC REDFINITION COMPLTE
DE LIMPLMENTATION MVC DE JAVA) :
IMPLMENTATION MVC actuelle de Java
n
MonContrleur1
Observer
MonModle
Observable
(souris / clavier)
ActionListener
ACTIONS de
lUTILISATEUR
MonContrleur2
Observer
MonContrleur3
Observer
MaVue3
TextListener
WhatChanged
NOUVELLE IMPLMENTATION
MonContrleur1
MVC/RMI pour Java
ACTIONS de
lUTILISATEUR
MvcControlerView
<W>
Remote
MonModleImpl
MvcModelAbstract
<W>
MonModle
MvcModel<W>
MaVue1
MaVue2
ItemListener
MonInterfaceModle
MaVue1
ActionListener
MonContrleur2
MvcControlerView
<W>
(souris / clavier)
q
q
MaVue1
MaVue1
Remote
MaVue2
Remote
ActionListener
MonContrleur3
MvcControlerView
<W>
MaVue3
Remote
WhatChanged
<T,U,V>
JVM 1 : SERVEUR
ActionListener
JVM 2 : CLIENT
De plus, les classes et interfaces ont t paramtres laide de types gnriques pour faciliter
lutilisation de la classe WhatChanged qui permet de fournir aux contrleurs une description de ce
qui a chang dans le modle.
Java RMI
Y. Laborde
Cours LOO - TOA
n Action de lutilisateur sur les composants actifs de linterface graphique
o Transmission au modle (vu au travers de son interface) de laction effectuer
p Notification tous les contrleurs inscrits dun changement du modle
q Mise jour des vues en fonction des modifications du modle (par utilisation de
WhatChanged)
DIAGRAMME dACTIVIT (UML)
Client
JVM 2
Vues
Contrleurs
ACTION de
lUTILISATEUR
(souris /
clavier)
Serveur
JVM 1
JVM 3
Contrleurs
Modle
n
Rception
de laction
Demande
daction au
modle
p
Mise jour q
Mise
jour q
des
vues
des vues
Vue
[actualise]
Client
WhatChanged
[paramtres]
WhatChanged
[paramtres]
Modle
[modifi]
Notification
de mise jour
tous les
contrleurs
clients
Mise jour
des vues
Diagramme d'activits : smantique
UML permet de reprsenter graphiquement le comportement d'une mthode ou le
droulement d'un cas d'utilisation, l'aide de diagrammes d'activits (une variante
des diagrammes d'tats-transitions).
Une activit reprsente une excution d'un mcanisme, un droulement d'tapes
squentielles.
Le passage d'une activit vers une autre est matrialis par une transition.
Les transitions sont dclenches par la fin d'une activit et provoquent le dbut
immdiat d'une autre (elles sont automatiques).
En thorie, tous les mcanismes dynamiques pourraient tre dcrits par un
diagramme d'activits, mais seuls les mcanismes complexes ou intressants
mritent d'tre reprsents.
Afin d'organiser un diagramme d'activits selon les diffrents responsables des actions reprsentes, il
est possible de dfinir des "couloirs d'activits".
Il est mme possible d'identifier les objets principaux, qui sont manipuls d'activits en activits et de
visualiser leur changement d'tat.
Java RMI
Y. Laborde
Cours LOO - TOA
package mvc.rmi;
public interface MvcControlerView<W> extends java.rmi.Remote {
public void update(MvcModel<W> mod, W wc)
throws java.rmi.RemoteException ;
}
package mvc.rmi;
public interface MvcModel<W> extends java.rmi.Remote {
public void addControler(MvcControlerView cv)
throws java.rmi.RemoteException ;
public boolean deleteControler(MvcControlerView cv)
throws java.rmi.RemoteException ;
public void deleteControlers()
throws java.rmi.RemoteException ;
public void notifyControlers()
public void notifyControlers(W wc)
throws java.rmi.RemoteException ;
throws java.rmi.RemoteException ;
public int countControlers()
throws java.rmi.RemoteException ;
public void clearChanged()
public boolean hasChanged()
public void setChanged()
throws java.rmi.RemoteException ;
throws java.rmi.RemoteException ;
throws java.rmi.RemoteException ;
}
package mvc.rmi;
public abstract class MvcModelAbstract<W> implements MvcModel<W> {
protected
protected
java.util.ArrayList<MvcControleurView>
boolean changed;
mvclist;
public MvcModelAbstract() {
mvclist = new java.util.ArrayList<MvcControleurView>();
changed = false;
}
public void addControler(mvcControlerView cvw)
throws java.rmi.RemoteException{
mvclist.add(cvw);
}
public boolean deleteControler(mvcControlerView cvw)
throws java.rmi.RemoteException{
return mvclist.remove(cvw);
}
public void deleteControlers()
mvclist.clear();
}
Java RMI
throws java.rmi.RemoteException{
Y. Laborde
Cours LOO - TOA
4
public void notifyControlers()
notifyControlers(null);
}
throws java.rmi.RemoteException{
public void notifyControlers(W w) throws java.rmi.RemoteException{
ArrayList<MvcControlerView<W>> suppList = null;
// Envoi des update des MvcControlerView<W>
// et non seulement des MvcControlerView !
for( MvcControlerView<W> mvc : mvclist ) {
try {
mvc.update(this, w); // Invocation de l'OD-mthode
}
// ICI: on peut vouloir supprimer le contrleur non valide
// de la liste des contrleurs du modle pour qu'il
// ne provoque plus d'erreur inutile la prochaine fois.
catch ( NoSuchObjectException e) {
// Peut arriver quand le client a t ferm !
if ( suppList == null ) {
suppList = new ArrayList<MvcControlerView<W>>();
}
suppList.add(mvc);
System.out.println("MvcModelAbstract(notifyControlers): ");
System.out.println(" Contrleur inconnu : "+e.getMessage());
catch ( RemoteException e) {
// Peut arriver pour des raisons de communication rseau
if ( suppList == null ) {
suppList = new ArrayList<MvcControlerView<W>>();
}
suppList.add(mvc);
System.out.println("MvcModelAbstract(notifyControlers) : ");
System.out.println(" Contrleur inaccessible : "+e.getMessage());
}
}
// Suppression des contrleurs inconnus !
if ( suppList != null ) {
for( MvcControlerView<W> mvc : suppList ) {
deleteControler(mvc);
}
System.out.println("MvcModelAbstract(notifyControlers) : "
+ "suppression de "
+ suppList.size() + " contrleur(s)");
}
}
public int countControlers()
return mvclist.size();
}
throws java.rmi.RemoteException{
public boolean hasChanged()
return changed;
}
throws java.rmi.RemoteException{
public void setChanged()
changed = true;
}
throws java.rmi.RemoteException{
Java RMI
Y. Laborde
Cours LOO - TOA
5
public void clearChanged()
changed = false;
}
throws java.rmi.RemoteException {
/**
* Crer un service de rsolution de noms pour la JVM courante
*/
protected boolean createRegistry(int portServeur) {
try {
System.out.print("SERVEUR cration du registry :");
// Crer un service de noms pour la JVM courante
LocateRegistry.createRegistry (portServeur) ;
// Trouve le service de rsolution de noms de RMI
registry = LocateRegistry.getRegistry(portServeur);
// echo
System.out.println(" OK");
return true;
} catch (Exception e) {
// echo
System.out.println(" ERREUR");
System.out.println(
" Warning dans createRegistry : " + e.getMessage());
return false;
}
/**
* Exporte le STUB serveur (this)
* et l'enregistre dans rmiregistry sous le nom nameOD.
*/
protected boolean registerModel(int portServeur, String nameOD) {
try {
System.out.print("SERVEUR enregistrement du modle :");
// Exporte le modle dans rmiregistry
// ICI, le STUB est cr dynamiquement
//
par l'usage de exportObject(Remote, int)
//
plutt que exportObject(Remote)
UnicastRemoteObject.exportObject(this, portServeur);
// Enregistre le nom et la rfrence distante (Stub)
registry.rebind(nameOD, this);
// echo
System.out.println(" OK : "+nameOD);
return true;
} catch (Exception e) {
// echo
System.out.println(" ERREUR");
System.out.println(
" Warning dans registerModel : " + e.getMessage());
return false;
}
}
}
Java RMI
Y. Laborde
Cours LOO - TOA
package mvc.rmi;
public class WhatChanged<T,U,V> {
public
public
public
public
final String mess;
T t;
U u;
V v;
public WhatChanged() {
this.mess = null;
}
public WhatChanged(String mess)
this.mess = mess;
}
public WhatChanged(String mess,
this.mess = mess;
this.t = t;
}
public WhatChanged(String mess,
this.mess = mess;
this.t = t;
this.u =
}
public WhatChanged(String mess,
this.mess = mess;
this.t = t;
this.u =
}
{
T t) {
T t, U u) {
u;
T t, U u, V v) {
u;
this.v = v;
Java RMI
Y. Laborde
Cours LOO - TOA