Cours de IA & POO Avancée: Pierre Chauvet
Cours de IA & POO Avancée: Pierre Chauvet
Cours de IA & POO Avancée: Pierre Chauvet
Evaluation :
- Projet permettant de mettre en œuvre les principaux
points abordés en cours
- Réalisé par binôme en Java sous Eclipse
- Restitution du code et d’un rapport (modélisation,
validation, expériences)
ROBOT Virtuel
POO et UML
Objectifs pédagogiques
Le (ou les) but du robot seront développés pendant le projet, d’un but simple
(balayer un maximum de surface, i.e. parcourir un maximum de cellules) à un but
plus compliqué (survivre !). L’environnement sera constitué d’une grille à 2
dimensions.
Le Robot R1
R1 est doté:
• de capteurs (percevoir)
• d’actuateurs (agir)
• d’un contrôleur (le « cerveau », réfléchir)
• d’un état interne (et mémoire éventuellement)
2. Réaliser une application Java fonctionnelle à partir de ce diagramme de classe, pour simuler ce robot. On implémentera un
contrôleur très simplifié pour tester l’application. Il est possible, et même recommandé, de modifier/corriger le diagramme de
classe en fonction du code développé.
Conception
Orientée Objet
Approches fonctionnelle et objet
Classe Instances
Véhicule Marque=‘Lotus’
#NombreDeVéhicules : Entier PuissanceFiscale=11
#Marque : Chaîne VitesseMaximale=230
#PuissanceFiscale : Entier VitesseCourante=170
#VitesseMaximale : Entier
#VitesseCourante : Entier Instanciation
+CréerVéhicule( ) Marque=‘Peugeot’
+DétruireVéhicule( ) PuissanceFiscale=7
+Démarrer VitesseMaximale=160
+Accélérer(Taux:Entier) VitesseCourante=90
+Avancer( )
+Reculer( )
Attributs de classe
ObjetGraphique
#Nombre : Entier
#Couleur : TypeCouleur
#X : Entier
#Y : Entier
#Epaisseur : Entier Classe de base :
+Créer( ) concept général
+Détruire( )
+getX( ) : Entier
+getY( ) : Entier
+setX(valeur : Entier )
+setY(valeur : Entier )
+DéplacerVers(dx,dy : Entier)
+Afficher( )
+Effacer( )
Exemple 1: les objets graphiques
ObjetGraphique
Classes dérivées :
Ligne concept spécialisé
Cercle
#Longueur : Entier
#Angle : Réel #Rayon : Entier
+Créer( ) +Créer( )
+Détruire( ) +Détruire( )
+getLongueur( ) : Entier +getRayon( ) : Entier
+setLongueur(valeur : Entier ) +setRayon(valeur : Entier )
+Afficher( ) +Afficher( )
+Effacer( ) +Effacer( )
Classes Abstraites
ObjetGraphique
+Afficher( )
Ligne
Méthode Ligne.Afficher( )
{ Tracer une droite;}
+Afficher( )
Cercle
Méthode Cercle.Afficher( )
{ Tracer un cercle;}
+Afficher( )
Le polymorphisme
Liste
Méthode Dessin.Afficher( ) {
déclarer objet : ObjetGraphique ;
Dessin pour i=0 à NombreObjets-1 faire {
lire objet en position i ;
+Afficher( ) appeler objet.Afficher( );
}
}
Concepts communs :
Démarrer, Accélérer, Véhicule
Ralentir, Arrêter
Voiture Camion
Exemple 2: modélisation
d’un parc de véhicules
Une hiérarchie de classes
possible pour la modélisation
Véhicule d’un parc hétérogène de
véhicules après ajout des avions
• L’héritage de construction:
Feuille2
Feuille1 Feuille3
ClasseA
VéhiculeRoulant Bateau
ClasseB ClasseC
Hovercraft
InterfaceA ClasseB
+MethodA1( ) +MethodB1( )
+MethodA2( ) +MethodB2( )
ClasseC possède en fin
de compte les méthodes:
MethodA1, MethodA2,
MethodB1, MethodB2
ClasseC
+MethodA1( )
+MethodA2( )
ClasseC implémente
MethodA1( ) et MethodA2( )
La relation d’association
ClasseA ClasseB
La relation d’agrégation
1 1 4
Voiture
1 1
Association et agrégation
Modèle 1:
Zoo
Cage 1 Gardien
*
nettoie
1 1 nourrit
contient
* Animal *
est contenu est nourri par
Association et agrégation
Modèle 2:
Zoo
Cage 1 Gardien
*
nettoie
1 1 nourrit
contient
* Animal *
est contenu est nourri par
Agrégation, héritage et interfaces
Avion Radar
AWACS
Agrégation, héritage et interfaces
(exemple AWACS)
• Encapsulation :
1) Rassemblement des données et du code traitant ces
données dans une entité appelée objet.
2) Séparation nette entre partie publique (méthodes) et
partie privée (données, implémentation).
Booch’93 OMT-2
• Réfléchir
• Définir la structure « gros grain »
• Documenter
• Guider le développement
• Développer, Tester, Auditer
Une vue, Un diagramme
Pe rson
members
Company Employe e
0..1 *
Exemple de diagramme
de classe
Diagramme d’objets
• Exemple:
Diagramme d’Activité
Attribut
⇒ Moins d’Interprétation
Méta-modèle
Bibliothèque 5 objets
• Bilbiothèque:Class
0..1 • Undefined:AssociationEnd
• Undefined:Association
• Undefined:AssociationEnd
* • Exemplaire:Class
Exemplaire
Notation
• Rational Rose
– Outil historique, forte implantation, RUP
– http://www.rational.com
– Racheté par IBM
• Together
– Synchronisation multi-langages, extension vers produits Borland
– http://www.togethersoft.com
– Racheté par Borland
• Objecteering
– Synchronisation multi-langages, français
– http://www.objecteering.com
• Visio
– Outil non complet de microsoft
– http://www.microsoft.com/office/visio
La Programmation
Concurrente en Java
- Rappels sur les processus
- Définition des threads
- Création d’un thread
- Gestion de la vie d’un thread
- Synchronisation et Accès concurrent
- La communication entre threads
- Les « Démons »
Rappels sur les processus
Logiciels de simulation
- un thread s'occupe de l’interface utilisateur (main) ;
- un ou plusieurs threads effectuent les calculs (simulations) ;
- un thread affiche les résultats (courbes, animations,…) ;
Traitements de texte
- un thread s'occupe de ce que tape l'utilisateur ;
- un thread est en charge de souligner les erreurs ;
- un thread se charge de l’aide contextuelle…
Quelques exemples
MonThread MonThread
Création d’un thread
Méthode 1: Exemple.
…
/** Le point de démarrage du programme.
* Notez bien que nous lançons deux threads et que
* chacun d'eux possède une donnée qui lui est propre. */
static public void main(String argv[]) {
FirstThread thr1 = new FirstThread("thr1");
FirstThread thr2 = new FirstThread("thr2");
}
}
Création d’un thread
Méthode 2: implémenter l'interface Runnable.
Méthode 2: exemple.
Méthode 2: exemple.
…
/** Le main crée un unique objet sur lequel vont se
* baser cinq threads. Il vont donc tous les cinq se
* partager le même attribut. */
static public void main(String argv[]) {
SecondThread p1 = new SecondThread(0);
}
}
Un exemple: L’Horloge
Objectif :
créer une classe "Horloge" permettant d'afficher l'heure en
cours.
Méthode:
• Dériver la classe java.awt.Label.
Notre objet est donc un label que l'on peut ajouter à une interface graphique
et sur lequel nous pouvons notamment changer la couleur d'arrière plan.
public Horloge( ) {
this.setText(timeFormat.format(new
this new Date()));
this.setAlignment(
this Label.CENTER );
(new
new Thread(this
this)).start();
this
}
}
Un exemple: L’Horloge
Utilisation de la classe Horloge avec une Applet :
import java.awt.*;
import java.applet.*;
public class Start extends Applet {
public void init() {
this.setLayout(new
this new FlowLayout());
Label clock1 = new Horloge();
clock1.setBackground(newnew Color(200,200,255));
Label clock2 = new Horloge();
clock2.setBackground(newnew Color(200,255,200));
Label clock3 = new Horloge();
clock3.setBackground(newnew Color(255,200,200));
this.add(clock1);
this
this.add(clock2);
this
this.add(clock3);
this
}
}
Cycle de vie d’un thread
Un thread peut passer par différents états, tout au long de son
cycle de vie. Le diagramme suivant illustre ces différents stades
ainsi que les différentes transitions possibles :
Nouveau Mort
Stop( )
Exécutable
Non Exécutable
Cycle de vie d’un thread
Etat « nouveau » :
C'est l'état initial après l'instanciation du thread. A ce stade, le
thread est opérationnel mais celui-ci n'est pas encore actif.
Etat « exécutable » :
Un thread est dans un état exécutable à partir du moment où il a
été lancé par la méthode start() et le reste tant qu'il n'est pas sorti
de la méthode run(). Dès que le système le pourra, il donnera du
temps d'exécution au thread.
Cycle de vie d’un thread
Etat « en attente » :
Un thread en attente n'exécute aucun traitement et ne consomme
aucune ressource CPU. Il existe plusieurs manières de mettre un
thread en attente. Par exemple :
♦ Appeler la méthode Thread.sleep(temps en millisecondes).
♦ Appeler la méthode Object.wait() ;
♦ Accéder à une ressource bloquante (Flux, accès en base de
données, etc…)
♦ Accéder à une instance sur laquelle un verrou a été posé.
Etat « terminé » :
Un thread dans un état terminé est un thread qui est sorti de sa
méthode run() soit de manière naturelle, soit de manière subite
(Exception non interceptée).
Gestion de la vie d’un thread
La classe Thread offre un certain nombre de méthodes pour
contrôler le comportement des threads :
Méthode:
• Instancier un objet de la classe ThreadGroup
• Attacher un thread à ce groupe via un constructeur de la classe
Thread :
Thread(ThreadGroup group, Runnable target)
Remarques:
- Par la suite, un thread ne pourra en aucun cas changer de
groupe.
- Les noms des méthodes de contrôle d’un ThreadGroup sont
identiques à ceux d’un Thread (start( ), sleep( ), …).
La synchronisation
Chaque instance de la classe thread possède ses propres attributs.
Pour partager une variable entre plusieurs threads, on peut
recourir à une variable de classe. Exemple :
public class exemplePartage extends Thread {
private static String chaineCommune = "";
private String nom;
exemplePartage ( String s ) { nom = s; }
public void run() {
chaineCommune = chaineCommune + nom;
}
public static void main(String args[]) {
Thread T1 = new exemplePartage( "T1" );
Thread T2 = new exemplePartage( "T2" );
T1.start(); T2.start();
System.out.println( chaineCommune );
}
}
La synchronisation
Le programme crée trois threads : le thread principal (qui exécute
main() ), et deux threads T1 et T2 créés explicitement.
A l'exécution, on observe :
• T2 : idem;
Exemple:
Deux threads T1 et T2 accèdent à une même variable partagée
compte, travaillent sur une copie locale tmp qui est incrémentée
avant d'être réécrite dans compte.
Un appel à sleep() simule un traitement long. Il augmente la
probabilité que le système bascule d'une tâche à l'autre durant
l'exécution de run() .
La synchronisation
public class exempleConcurrent extends Thread {
private static int compte = 0;
public void run() {
int tmp = compte;
try { Thread.sleep(1); // ms }
catch (InterruptedException e) {
System.out.println("Erreur!\n"); return;
}
tmp = tmp + 1;
compte = tmp;
}
public static void main(String args[]) throws InterruptedException {
Thread T1 = new exempleConcurrent();
Thread T2 = new exempleConcurrent();
T1.start();T2.start();
T1.join(); T2.join();
System.out.println( "compteur=" + compte );
}
}
La synchronisation
Résultats possibles:
La synchronisation
L'environnement Java offre un premier mécanisme de
synchronisation : les verrous (locks en anglais):
Description:
L'interface graphique de l'applet présente deux boutons et une
zone de dessin. Les deux boutons permettent de lancer le tracé
dans la zone de dessin. Mais l'un des boutons lance le tracé sans
synchronisation alors que l'autre le fait en synchronisant les
threads.
La synchronisation
/**
* This is the default constructor
*/
public JCanvas() {
super();
this.setSize(300, 200);
}
}
Une animation simple
public JAnimatedSimple() {
super();
this.setSize(300, 200);
}
Allure de l’horloge:
Description:
la classe se nomme Horloge , elle hérite de la classe
java.applet.Applet et utilise l'interface Runnable pour le thread.
…
gsp.drawImage(imgTmp,0,0,this
this);
this
Copie du buffer sur
} la surface affichée
}
Le Traitement
des Exceptions
Le mécanisme des exceptions permet de gérer les
erreurs en simplifiant l’écriture du code :
- il évite les cascades de « if » imbriqués
- il évite la transmission d’indicateurs de succès ou
d’échec des méthodes.
Erreur !
Traitement Traitement
Auto.
♦ La classe « Exception »
Elle possède:
- un attribut de type string, qui spécifie le message d’erreur
associé – spécifié comme paramètre du constructeur ;
- un attribut qui représente une photo de la pile d’exécution au
moment où l’erreur a été signalée ;
class Objet {
protected int posX , posY;
public Objet(int x, int y) throws ErrPos{
if ((x<0)||(y<0)) { throw new ErrPos(); }
posX=x; posY=y;
}
public void affiche() {
System.out.println(‘ posX=‘+posX+’ posY=‘+posY);}
}
Exemple: automates
Remarque:
la classe Automate hérite de la classe Objet. Le constructeur
d’Automate est le constructeur d’Objet, et Automate dispose
des attributs posX et posY.
Exemple: automates
public class Carte {
public static void main(String args []) {
try {
Automate a=new Automate(2,4);
a.affiche();
a.deplace(-1,-5);
a.affiche();
}
catch(ErrPos e) {
System.out.println(‘Erreur de construction’);
System.exit(-1);
}
catch(ErrDepl e) {
System.out.println(‘Erreur de déplacement’);
System.out.println(‘Position souhaitée: (’+e.x+’,’+e.y+’)’);
System.exit(-1);
}
}
}
Poursuite de l’exécution
Throwable
String (message d'erreur)
Exception Error
OutOfMemoryError
RunTimeException
VosExceptions... NullPointerException
ClassCastException
...
Hiérarchie des classes Exception
Rappel:
Il n'est pas obligatoire de traiter les exceptions des
classes RuntimeException, Error et leur dérivées dans
un try ... catch, et ceci qu'elles soient citées ou non dans
la clause throws des méthodes invoquées.
Les « Exception »
Suite :
• java.lang.InstantiationException : La classe spécifiée en paramètre de
newInstance() est abstraite, un tableau ou une interface, ceci interdisant la
création d'un nouvel objet.
• java.lang.InterruptedException : Le thread courant était en attente et un
autre thread a interrompu son attente grâce la méthode interrupt() de la
classe Thread.
Les « Exception »
Rappel:
Vous devez obligatoirement prendre en compte les
exceptions dont la classe dérive de java.lang.Exception
(sauf RuntimeException et ses classes dérivées), soit en les
traitant dans un try ... catch, soit en les propageant grâce
à la clause throws.
Exceptions et Informations
try {
// code pouvant déclencher une exception MonException
}
catch(MonException e) {
System.out.println(‘Message : ’+e.getMessage());
System.out.println(‘Message : ’+e.toString());
e.printStackTrace();
}
Exceptions et Informations
Exemple:
Exceptions et Informations
Résultat :
System.out.println(‘Message : ’+e.getMessage());
System.out.println(‘Message : ’+e.toString());
e.printStackTrace());
public MainApp() {
super();
//construction du modèle
thisModel = ModelFactory.makeModel(…);
//construction de l’IHM
initGUI();
}
Journalisation des applications
import org.apache.log4j.Logger;
}
Exemple d’utilisation de Log4j
Remarque 1 :
logger.debug("La méthode helloWorld est invoquée");
est équivalent à
logger.log(Level.DEBUG,"La méthode helloWorld est invoquée");
public Hello() {
try {
logger.addAppender(new FileAppender(new SimpleLayout(), "hello.log"));
} catch (IOException e) {
e.printStackTrace();
}
}
public String helloWorld() {
logger.debug("La méthode helloWorld est invoquée");
return "Hello, world";
}
• jLo : http://jlo.jzonic.org/
• Commons Logging :
http://commons.apache.org/logging/