Licence Informatique 3e année – Programmation objet avancée 1
Programmation par composants (1/3)
La programmation par composant
vise le développement de logiciel par aggrégation de briques logicielles existantes
est indépendante de la POO
La programmation par composant fait évoluer la POO
Réutilisabilité accrue du code
Persistance des objets
Distribution du code et des objets (des objets peuvent être partagés par des applications différentes tournant sur des machines différentes)
Sécurité au niveau de l'exécution concurrente
Licence Informatique 3e année – Programmation objet avancée 2
Programmation par composants (2/3)
Un composant est une brique logicielle
Taille variable (d'une classe à une application entière)
Granularité variable (ossature logicielle, élément d'interface, classe métier, ...)
Fonctions variées
• Composants techniques : ossature du code, éléments d'interfaces graphiques, utilitaires pour manipuler des données, ...
• Composants métiers : représentent des entités du domaine (client, produit, ...)
• Composants applicatifs : dédiés aux traitements internes d'une application (peu réutilisables)
Un composant doit offrir
Robustesse : le comportement doit être celui attendu (et sans bug!)
Généricité : le composant doit pouvoir être adapté à l'application (sans le modifier!)
Abstraction : le composant doit offrir une interface claire et être utilisable sans consulter son code (son implémentation doit être autonome)
Licence Informatique 3e année – Programmation objet avancée 3
Programmation par composants (3/3)
Programmation par composants
Sélection des composants dans un catalogue
Eventuellement développement de nouveaux composants
Adaptation des composants à l'application
Assemblage des composants, avec ajout éventuel de code
Modèles de programmation par composants
EJB (Enterprise Java Beans) : programmation distribuée et interopérabilité
Java Beans : assemblage visuel (interfaces en particulier)
CORBA de l'OGM (Object Management Group)
OLE/ActiveX, COM et .NET dans le monde Microsoft
Licence Informatique 3e année – Programmation objet avancée 4
JavaBean (1/2)
Java propose un modèle de composant : Java Bean (grain de café)
Caractéristiques d'un JavaBean :
Règles de dénomination : permettent de normaliser le nommage des membres des bean et donc d'automatiser leur manipulation
Réflexion : les beans (comme tous les objets Java) peuvent donner des informations sur eux-mêmes, non seulement sur leur état mais aussi sur leur constitution interne
Persistance : un bean peut être sauvegardé en l'état (avec les valeurs des attributs) et réactivé plus tard par sérialisation
Communication : les beans communiquent via le modèle événementiel et le pattern d'écouteur (Listener)
Licence Informatique 3e année – Programmation objet avancée 5
JavaBean (2/2)
Les JavaBeans sont toutes les classes Java qui respectent un certains nombre de règles :
ils doivent posséder un constructeur sans paramètre. Celui ci devra initialiser l'état du bean avec des valeurs par défauts.
ils peuvent définir des propriétés : celles ci sont identifiées par des attributs et méthodes dont le nom et la signature sont normalisés
ils doivent implémenter l'interface Serializable : ceci est obligatoire pour les beans qui possèdent une partie graphique pour permettre la sauvegarde de leur état
ils définissent des méthodes utilisables par les composants extérieurs : elles doivent être publiques et prévoir une gestion des accès concurrents
ils peuvent émettre des événements en gérant une liste d'écouteurs qui s'y abonnent via des méthodes dont les noms sont normalisés
Les classes des API graphiques de Java (AWT et Swing) sont des JavaBeans
Licence Informatique 3e année – Programmation objet avancée 6
Propriétés dans un JavaBean
L'accès aux attributs (propriétés) est contrôlé
Attributs toujours privés (ou à la rigueur protégés)
Les attributs peuvent n'avoir qu'un accesseur (ils sont en lecture seule), qu'un modifieur (ils sont en écriture seule)
Accesseurs et modifieurs sont normalisés
Accesseur : <type_attribut> get<nom_attribut>() (is<nom_attribut> si l'attribut est booléen)
Modifieur : void set<nom_attribut>(<type_attribut>
<nom_variable>)
Le nom de l'attribut n'est pas forcément celui de la variable qui le contient!
public class GrainDeCafe{
private int poids;
private boolean truc;
...
public int getPoids(){return this.poids;}
public void setPoids(int a){this.poids = a;}
public void getArabica(){ return this.truc;}
}
Licence Informatique 3e année – Programmation objet avancée 7
Propriétés indexées
Quand les attributs sont des tableaux, les accesseurs et modifieurs ont un indice en paramètre supplémentaire
public class GrainDeCafe{
private float[] dimensions = new float[3];
private boolean truc;
public GrainDeCafe(){
dimensions[0] = 0.5;
dimensions[1] = 1.0;
dimensions[2] = 0.4;
truc = a;
}
public float getDimension(int axe){return this.dimensions[axe];}
public void setDimension(float a, int axe){this.dimensions[axe] = a;}
public void getArabica(){ return this.truc;}
}
Licence Informatique 3e année – Programmation objet avancée 8
Propriétés liées (1/3)
Un JavaBean peut observer une propriété d'un autre JavaBean via un mécanisme implémentant le pattern Observer. La propriété est alors dite liée (bound property)
Le JavaBean observé intègre par composition un objet PropertyChangeSupport
PropertyChangeSupport gère une liste d'écouteurs de type PropertyChangeListener qui jouent le rôle d'observateurs
PropertyChangeSupport permet de notifier aux écouteurs les changements intervenant sur une propriété liée
Les JavaBeans observateurs implémentent l'interface PropertyChangeListener qui ne contient qu'une méthode
void propertyChange(PropertyChangeEvent evt)
La classe d'événements PropertyChangeEvent encapsule les données qui décrivent le changement de valeur de la propriété (nom de la propriété, ancienne valeur, nouvelle valeur, ...)
Licence Informatique 3e année – Programmation objet avancée 9
Propriétés liées (2/3)
public class GrainDeCafe{
private int poids;
private boolean truc;
private PropertyChangeSupport pcs;
public GrainDeCafe(){
...
pcs = new PropertyChangeSupport();
}
public void addPropertyChangeListener(PropertyChangeListener pcl){
pcs.addPropertyChangeListener(pcl);
}
public void removePropertyChangeListener(PropertyChangeListener pcl){
pcs.removePropertyChangeListener(pcl);
}
public void setPoids(int a){
int temp = poids; this.poids = a;
pcs.firePropertyChange("poids",new Integer(temp),new Integer(a));
} ...
}
Licence Informatique 3e année – Programmation objet avancée 10
Propriétés liées (3/3)
public class Torrefacteur implements PropertyChangeListener{
private MachineATorrefier mat;
public Torrefacteur(){...}
public void propertyChange(PropertyChangeEvent pce){
if(pce.getPropertyName().equals("poids"))
if(((Integer) pce.getNewValue()).intValue() > 3) //changer la machine à torréfier
}
}
public class VendeurDeCafe implements PropertyChangeListener{
public VendeurDeCafe(){...}
public void propertyChange(PropertyChangeEvent pce){
if(pce.getPropertyName().equals("poids")) if(((Integer) pce.getNewValue()).intValue()
- ((Integer) pce.getOldValue()).intValue()) //changer le prix de vente
}
}
Licence Informatique 3e année – Programmation objet avancée 11
Propriétés contraintes (1/2)
Un JavaBean qui écoute une propriété d'un autre composant peut mettre son veto à un changement de valeur en créant une PropertyVetoException
Les propriétés contraintes sont gérées par des VetoableChangeSupport et écoutées par des VetoableChangeListener
Au cas où un composant écouteur de la propriété met son veto au changement de valeur, le changement doit être annulé
public class USA implements VetoableChangeListener{
...
public void vetoableChange(PropertyChangeEvent e) throws PropertyVetoException { Resolution r = ((Resolution) e.getNewValue());
if(!this.accepts(r)) throw new PropertyVetoException("resolution inacceptable!",e);
} }
Licence Informatique 3e année – Programmation objet avancée 12
Propriétés contraintes (2/2)
public class ConseilSecuriteONU{
private LinkedList resolutions = new LinkedList();
private VetoableChangeSupport vcs;
public void addVetoableChangeListener(VetoableChangeListener vcl) { vcs.addVetoableChangeListener(vcl);
}
public void removeVetoableChangeListener(VetoableChangeListener vcl) { vcs.removeVetoableChangeListener(vcl);
}
public void addResolution(Resolution r){
resolutions.add(r);
try{
vcs.fireVetoableChange("resolution",null,r);
}
catch(PropertyVetoException e){
System.out.println("un veto est emis : "+e.getMessage());
resolutions.remove(r);
} } }
Licence Informatique 3e année – Programmation objet avancée 13
Réflexivité
En programmation objet, la réflexivité consiste à offrir la possibilité d'interroger un objet sur :
sa constitution interne (attributs avec leurs types)
son état (valeurs des attributs)
son comportement (méthodes)
sa classe
Intérêts de la réflexivité :
Dans le cadre de la programmation par composants (JavaBeans) il faut que les composants puissent être interrogés dynamiquement sur leur constitution pour être utilisés par une application à l'exécution
Accès aux classes dans les outils de développement (debuggers, browsers de classe, ...) ou les applications réparties utilisant la sérialisation
Tous les langages objets n'offrent pas la réflexivité (C++ n'est pas réflexif)
Licence Informatique 3e année – Programmation objet avancée 14
API Reflexion de Java
java.lang.reflect est un paquetage Java dédié à l'introspection
la classe Field représente les attributs des classes (cette classe offre des méthodes de classe pour récupérer les valeurs des attributs d'un objet)
la classe Method représente les méthodes des classes
la classe Constructor représente les constructeurs des classes
La classe Modifier représente les modifieurs des classes et membres
La classe Array représente les tableaux
La classe java.lang.Class offre des méthodes permettant de récupérer les instances des classes précédentes
Class est instanciée chaque fois que le java.lang.ClassLoader charge une classe dans la JVM
La méthode getClass de la classe Object permet de récupérer la classe d'un objet (on peut aussi utiliser Class.forName(String nom_classe))
Class permet de récupérer des informations sur les classes (et indirectement sur les objets)
Licence Informatique 3e année – Programmation objet avancée 15
BeanInfo
java.beans.BeanInfo est une interface permettant de compléter les mécanismes d'introspection de java.lang.reflect
BeanInfo offre des méthodes permettant de récupérer des descripteurs sur un JavaBean
BeanDescriptor : description générale du composant (classe)
PropertyDescriptor : description des propriétés (attributs)
MethodDescriptor : description des méthodes
EventSetDescriptor : description des événements gérés et des écouteurs
La classe java.beans.Introspector permet de récupérer un BeanInfo
Introspector cherche une classe <nom_du_bean>BeanInfo qui doit être une implémentation de BeanInfo ou une classe qui hérite de l'adapteur SimpleBeanInfo. S'il trouve cette classe, il l'instancie et retourne l'instance
Sinon il utilise les mécanismes d'introspection classiques et construit le BeanInfo à partir des infos récupérées
Licence Informatique 3e année – Programmation objet avancée 16
Jar et fichier manifest
Un JavaBean est souvent implémenté par plusieurs classes qui sont fournies dans une archive Java (JAR : Java Archive)
Une archive JAR est générée ou ouverte avec l'utilitaire jar
Un fichier manifest peut être ajouté à l'archive pour ajouter des informations
Informations générales sur l'archive (version, ...)
Des informations sur chaque fichier de l'archive