Cours GLCB2 Introduction au g enie logiciel - campus.emn.fr · un peu plus clair on peut...
Transcript of Cours GLCB2 Introduction au g enie logiciel - campus.emn.fr · un peu plus clair on peut...
Cours GLCB2
Introduction au genie logiciel
Jean-Claude Royer
3 novembre 2010
Table des matieres
1 Une vue globale du genie logiciel 8
1.1 Quelques definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.1.1 Bibliographie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.2 La nature du logiciel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.2.1 Genie logiciel et economie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.2.2 Contraintes d’utilisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.2.3 La crise du logiciel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.2.4 L’etat actuel du genie logiciel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.2.5 Evolution probable de l’informatique . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.2.6 Role de l’ingenieur logiciel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.2.7 Responsabilites de l’ingenieur logiciel . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.2.8 Les qualites du logiciel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.3 Le cycle de developpement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.3.1 Le developpement dans sa globalite . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.4 Les etapes du developpement logiciel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.4.1 Le cahier des charges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.4.2 L’analyse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.4.3 La specification formelle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.4.4 La conception . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.4.5 Le codage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.4.6 L’integration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.4.7 Le debogage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.4.8 La maintenance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.4.9 Inspection ou revue de code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.4.10 Atelier de genie logiciel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.5 Les methodes de developpement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.5.1 Le cycle en V . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.5.2 La programmation exploratoire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.5.3 Le prototypage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.5.4 Par reutilisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
1.5.5 Le cycle en spirale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2 Introduction a l’architecture logicielle 23
2.1 Regles de conception . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.2 Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
1
2.2.1 La notion d’interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.3 Petite introduction a UML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.3.1 Organisation en packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.4 Description d’une classe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.4.1 Description d’une instance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.4.2 Relations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.4.3 La hierarchie des classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.4.4 La relation de composition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
2.4.5 Une vue generale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
2.4.6 Que se passe-t-il a l’execution ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
2.4.7 Des outils pour UML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
2.5 Patrons de conception . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
2.5.1 Le patron singleton . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
2.5.2 Le patron composite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
2.5.3 Le patron etat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
2.5.4 Le patron observateur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
2.5.5 Le patron visiteur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
2.6 Exemples d’API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3 Outils et environnements de developpement 41
3.1 Editeur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.1.1 Le probleme des accents en Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.2 Interpreteurs et compilateurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
3.3 Archives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.3.1 Archive Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3.4 Organisation et construction du logiciel . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
3.4.1 Gestion technique d’un projet informatique . . . . . . . . . . . . . . . . . . . . . . 45
3.4.2 Sequenceur de taches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
3.4.3 make . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
3.4.4 ant pour Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
3.5 Gestionnaire de version et de configuration . . . . . . . . . . . . . . . . . . . . . . . . . . 48
3.5.1 Concurrent Version System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
3.6 Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
3.6.1 javadoc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
3.7 Recherche et correction des erreurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
3.7.1 Log4J . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
3.7.2 Le debogueur d’Eclipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
3.8 Generation de tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.8.1 L’API JUnit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.9 Mesure des performances . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
3.10 Qualite du code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
3.10.1 Checkstyle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
3.10.2 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
3.10.3 Quelques corrections classiques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
3.11 Environnement de developpement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
3.11.1 Environnement pour UML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
2
3.12 ArgoUML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
3.13 Quelques remarques sur ArgoUML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
3.13.1 Aspects avances . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
A Annexes 68
A.1 Regles et consignes de bon sens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
A.2 Quelques regles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
A.3 Code Java du DigitCode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
B Trucs pour depanner 74
B.1 Sauvegarde ASCII impossible car le texte contient des accents . . . . . . . . . . . . . . . . 74
B.2 Il manque un caractere NewLine a la fin du programme . . . . . . . . . . . . . . . . . . . 74
B.3 Mise a jour d’un plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
B.4 Utilisation du patron.jar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
B.5 Jar rete de poisson . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
C Un petit dictionnaire du genie logiciel 76
Index 76
Bibliographie 78
3
Table des figures
1.1 Genie logiciel et economie : chiffres du SYNTEC . . . . . . . . . . . . . . . . . . . . . . . 11
1.2 C’est pas drole ! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.3 C’est toujours pas drole ! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.4 Schema des grandes taches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.5 Le cycle en V . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.6 Le cycle en spirale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.1 STSLib le diagramme des classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.2 Exemple MyClass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.3 La vue principale du jeu de Nim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.4 La vue en cours de partie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.5 Interface de Joueur obtenu par javap. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.6 Exemple de paquetage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.7 La classe Arbitre. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.8 La classe Joueur. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.9 Une instance. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.10 La classe Expert. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.11 L’organisation des joueurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.12 La relation de composition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
2.13 La structure generale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.14 Un cas d’execution dynamique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
2.15 Prototype d’un message et son diagramme de sequence. . . . . . . . . . . . . . . . . . . . 33
2.16 Un autre exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
2.17 Un exemple avec bouml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
2.18 Schema UML : le singleton . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
2.19 Schema UML : le composite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
2.20 Schema UML : le patron etat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
2.21 Le digit code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
2.22 Schema UML : l’observateur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.1 Exemple de l’editeur java d’Eclipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
3.2 Compilation et interpretation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.3 Le cas de Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.4 jar sous Eclipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3.5 Un exemple de structure simple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
3.6 ant sous Eclipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
4
3.7 Javadoc pour Nim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
3.8 La Javadoc sous Eclipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
3.9 Un breakpoint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
3.10 La perspective debug . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
3.11 Installer checkstyle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
3.12 La configuration du checkstyle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
3.13 Une vue d’ArgoUML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
3.14 La vue commentee d’ArgoUML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
B.1 Probleme de jeu de caracteres sous Eclipse . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
5
Objectifs et preliminaires
Le genie logiciel est un terme vague pour beaucoup et qui regroupe tout un tas de choses. Pour y voir
un peu plus clair on peut s’inspirer de la definition du SWEBOK http://www.swebok.org :
The application of a systematic, disciplined, quantifiable approach to the development, ope-
ration, and maintenance of software ; that is, the application of engineering to software.
Le genie logiciel doit etre consideree comme une discipline emergente, il est donc d’autant plus important
de sensibiliser les etudiants ingenieurs a ce domaine.
Compte-tenu des connaissances et de la provenance des etudiants, une approche pragmatique mais
assez exhaustive est a privilegier. Cela etant nous mettrons l’accent sur le cadre general du developpement
mais plus particulierement tout ce qui concerne la conception et la programmation. Les aspects de
modelisations plus avances, de gestion de projets, de compilation, etc seront vus en GS1, voire en GS2.
Un point important est de fournir des elements de base aux etudiants pour architecturer, documenter,
tester leur logiciels. Ceci va de pair avec l’utilisation et la presentation d’outils d’aide dans ce domaine.
La notion d’environnement de developpement logiciel (comme Eclipse) mais aussi les familles d’outils
(editeurs, compilateur, debogueur, etc) et des exemples concrets d’utilisation sont une partie importante
de ce programme. Un aspect crucial est de confronter les etudiants a un code qu’il faut reprendre et docu-
menter voire corriger et faire evoluer. C’est une activite importante de la vie courante d’un informaticien,
et cela permet de mieux comprendre certains problemes qui restent trop abstraits sinon.
Un objectif a ne pas sous-estimer est de montrer la cohesion de la science informatique et de faire
le lien avec les differents domaines ou cours vus ulterieurement. Ceci devrait les aider dans leur choix
de cursus. Accessoirement le cours a pour but de les sensibiliser a certaines techniques ou concepts
plus avances : automates, grammaires, polymorphisme, generation de code, code avec effets de bord ou
purement fonctionnel, exceptions, ... et les illustrer avec des exemples (il s’agit d’indications et d’idees
possibles a explorer mais non du contenu exact du cours).
Les cours
Ce document est divises en trois grandes parties :
Introduction au genie logiciel : il s’agit de definir ce qu’est le genie logiciel, de le connecter avec
les autres domaines, avec l’economie ou les problemes de securite, ...
Elements pour les architectures logicielles : il s’agit d’un ensemble de propositions visant a
ameliorer la production logicielle (documentation, abstraction, evolution, structuration, patron de
conception etc).
Outils et environnements de developpement : les outils sont nombreux et indispensables pour
etre efficace et plus rigoureux, il faut avoir une bonne idee de ce qui existe.
Seules les deux premieres parties font l’objet d’une presentation orale, la lecture du polycopie est
donc indispensable pour realiser correctement les TP. Par ailleurs vous devez vous assurez d’avoir un
systeme operationnel sur vos portables, une version d’Eclipse au moins 3.2. Pour le premier TP
vous devez installer chekstyle et pour le second ArgoUml, cela ne presente generalement pas de
difficulte. Voir le chapitre 3 ou le site sur campus pour les details d’installation.
Objectifs
Les principaux objectifs sont :
6
– Connaıtre les grandes lignes du developpement d’un projet informatique et pratique de la gestion
technique d’un petit projet.
– Acquerir une culture des grandes familles d’outils du genie logiciel et une pratique de quelques uns.
– Connaissance des notions de base en architecture logicielle.
– Lire et elaborer des diagrammes de classe et des diagrammes de sequences UML.
– Savoir generer du code automatiquement et le completer manuellement.
Les travaux pratiques
Il y a 5 seances (2 fois 1H15) de TP qui sont prevues. Les travaux se feront toujours individuellement
et 2 seront notes : le TP2 et le TP4.
TP0 : Le projet makeindex sous Eclipse.
TP1 : Implementation du patron composite.
TP2 : Note.
TP3 : Generation de code pour le composite.
TP4 : Note.
Controle des connaissances
Deux des cinq travaux de TP donneront lieu a une note. La formule savante est : 0.5*tp + 0.5*tp.
Organisation
– Responsable : Jean-Claude Royer
– Intervenants : Jacques Noye, Jean-Claude Royer, Mario Sudholt, Gilles Chabert, Fabien Hermenier,
Xavier Lorca
– Jours des TP : lundi et mercredi
– Amphi A. Kastler et salles de TP B0*
– Lire le polycopie avant les TP
– Verifier votre installation Eclipse et la mettre a jour
– Installer ArgoUML (voir chapitre III) du polycopie
– https://nte.gemtech.fr/campus/course/view.php?id=371
Planning
Date Seances Contenu
Lundi 17/11/09 C C1 : Introduction au genie logiciel
Lundi 25/11/09 C C2 : Elements pour les architectures logicielles
Mercredi 7/12/09 2TP TP0
Lundi 9/12/09 2TP TP1
Mercredi 14/12/08 2TP TP2
Lundi 4/01/10 2TP TP3
Mercredi 6/01/10 2TP TP4
7
Chapitre 1
Une vue globale du genie logiciel
1.1 Quelques definitions
Le genie logiciel peut-etre defini comme l’ensemble des principes, des methodes, des techniques et
des outils utiles au developpement d’un projet logiciel. C’est evidemment un domaine vaste qui couvre
de nombreuses et diverses activites touchant aux technologies du logiciel, a la gestion des ressources
et a la mesure de la qualite. Un objectif important du genie logiciel est d’essayer de rationaliser, de
maıtriser et de rendre efficace le processus de production du logiciel. Donc le genie logiciel essaie de
fournir des garanties sur les temps, les couts et la qualite du produit. Le genie logiciel ne s’interesse
donc pas uniquement aux aspects techniques d’analyse et de conception mais a tout le cycle de vie :
analyse des besoins, conception, maintenance, tests, certification, normalisation, deploiement mais aussi
aux aspects organisationnels : constitutions des equipes, gestion du processus, prevision des couts et
des delais. C’est un domaine toujours en evolution et qui est etroitement lie avec la gestion de projet, plus
precisement la gestion de projet informatique. On a fait beaucoup de progres mais les choses ne sont pas
encore satisfaisantes sur bon nombre de points, le genie logiciel doit etre considere comme une discipline
en emergence.
Une bonne alternative est d’aller voir ce qu’en dit Wikipedia (http://fr.wikipedia.org), qui dans
le domaine de l’informatique est souvent bien renseigne.
Le genie logiciel est en fait de l’ingenierie appliquee au logiciel informatique. Cette branche de
l’informatique s’interesse donc plus particulierement a la maniere dont le code source d’un lo-
giciel est specifie puis produit. Le genie logiciel touche donc au cycle de vie des logiciels. Toutes
les phases de la creation d’un logiciel informatique y sont donc enseignees : le developpement,
l’analyse du besoin, l’elaboration des specifications, a la conceptualisation du mecanisme in-
terne au logiciel ainsi que des techniques de programmation et finalement a la maintenance.
Les projets relatifs a l’ingenierie logicielle sont de l’ordre du ”Programming in the large”, c’est
a dire que les projets sont generalement de grande envergure et depassent souvent les 10000
lignes de code. Ces projets necessitent donc une equipe de developpement bien structuree. La
gestion de projet se retrouve donc le complement naturel du genie logiciel.
La page http://fr.wikipedia.org/wiki/ a la rubrique Genie logiciel contient des informations
courtes mais bien faites. On peut bien sur consulter des dictionnaires plus classiques ou academiques.
Une source dont l’origine est nantaise est le “Dictionnaire du genie logiciel” ecrit par H. Habrias.
Il ne serait pas bon d’ignorer ce qu’en dit l’IEEE (http://www.ieee.org) qui est une association
importante pour l’ingenieur informaticien.
8
Definition 1.1.1 (Definition de l’IEEE)
Software engineering : The application of a systematic, disciplined, quantifiable approach to the develop-
ment, operation, and maintenance of software ; that is, the application of engineering to software.
Cette definition est extraite du http://www.swebok.org qui est une reference incontournable dans
ce domaine. Les pages I-8 et I-9 (The SWEBOK Knowledge Areas) donnent une idee de l’ampleur du
domaine :
1. Software requirements
2. Software design
3. Software construction
4. Software testing
5. Software maintenance
6. Software configuration management
7. Software engineering management
8. Software engineering process
9. Software engineering tools and methods
10. Software quality
En ce qui nous concerne nous verrons quelques elements globaux et des considerations relevant des points
1, 2, 3, 4, 9 et 10.
1.1.1 Bibliographie
Il n’existe pas vraiment de livre reellement adapte a ce cours, toutefois des documents voisins existent
mais en aucun cas ils ne sont obligatoires pour suivre ce cours.
– Genie logiciel : principes, methodes et techniques, PPUR, A. Strohmeier et Didier Buchs ([4]).
Ce livre presente differentes techniques utiles et des generalites sur le genie logiciel.
– Software Design Using Java 2, Kevin Lano, Jose Luiz Fiadero, Luis Andrade, 2002, Palgrave Mac-
Millan ([3]).
Fiadero and al. : UML + Java une approche a la fois pragmatique et bien fondee
– Dictionnaire encyclopedique du genie logiciel, Henri Habrias, Masson, 1997 ([2]).
– Cours sur Web : EPFL, IRO, Bordeaux I, ...
1.2 La nature du logiciel
Les difficultes a realiser des projets informatiques et a enseigner cette discipline ont surement beaucoup
a voir avec la nature du logiciel dont le but principal est de manipuler de l’information. Il s’agit donc
d’un domaine d’application tres vaste et souvent difficilement palpable ou materialisable. Le logiciel est
un produit immateriel, une production intellectuelle au meme titre qu’une œuvre artistique. Il faut bien
reconnaıtre que la comparaison avec l’artiste s’arrete la car souvent beaucoup de realisation sont tres mal
realisees. Toutefois l’objectif du genie logiciel n’est pas de faire de l’art mais des produits technologiques
repondant correctement aux besoins plus ou moins precis d’un cahier des charges. Ceci demande peut-etre
moins de creativite mais le respect de normes diverses. Une particularite de cette production est que c’est
le travail d’ingenieurs et de programmeurs il n’y a pas de manufaction comme dans l’industrie lourde
9
classique ou il faut par exemple maquetter le produit puis mettre en place une chaıne de production. Le
logiciel est un produit tres specifique, ce qui a quelques consequences sur sa production. Dans le genie
logiciel il n’y a qu’un travail d’ingenierie mais celui-ci est finalement assez subtile et delicat.
Pour completer ce tableau il faut egalement noter que le logiciel n’est pas sensible a l’usure, la copie
et les destructions sont tres faciles ce qui implique par exemple des habitudes ou des processus de
sauvegardes specifiques. Il faut aussi savoir que le cout du logiciel est actuellement tres superieur a celui
du materiel. Le cout de la maintenance du logiciel est aussi plus important que celui du developpement.
La fiabilite et l’adequation du logiciel devraient etre des caracteristiques primordiales d’un logiciel. La
fiabilite (mais nous y reviendrons) : “est-ce que je peux utiliser le logiciel sans risque ou avec un taux
de risques connus”. La fiabilite est fondamentale dans les cas de logiciels dit critiques, c’est a dire ceux
mettant en jeu la vie humaine (transports, gestion de l’energie, production de produit dangereux, etc).
C’est l’aspect le plus critiquable de la plupart des logiciels, on ne tolererait pas de telles erreurs dans
d’autres secteurs ! On constate souvent d’importantes derives dans ce domaine : beaucoup trop de bugs,
des interactions trop sophistiquees ou une ergonomie delirante.
Pour des ingenieurs d’autres disciplines, l’informaticien d’aujourd’hui peut apparaıtre comme un char-
lot 1. Une explication amusante de Rich Cook est la suivante :
”La programmation est aujourd’hui une course entre les ingenieurs informaticiens qui essaient
de construire des programmes plus grands et mieux a l’epreuve des idiots, et l’univers qui
essaie de produire des idiots plus grands et plus idiots. Jusqu’a present, l’univers gagne.”
1.2.1 Genie logiciel et economie
Dans notre monde courant, l’economie de toute nation developpee depend du logiciel et de plus en plus
de systemes sont controles par logiciel. C’est une tendance industrielle mais aussi tertiaire, loisir, famille,
etc. La part de l’informatique represente une partie importante du PIB d’un pays developpe. On observe
facilement une correlation entre la courbe des investissements en informatique et la courbe du PIB, voir
documents du SYNTEC informatique : http://www.syntec-informatique.fr pour plus de details et
des chiffres tres interessants. L’evolution aux US entre 1980 et 1990 a ete estime : augmentation de 12%
par an de la valeur du logiciel dans le PIB. L’emploi informatique est toujours un secteur important
(toujours premier secteur en France avec plus d’un quart des emplois de cadres).
1.2.2 Contraintes d’utilisation
Il existe des contraintes d’utilisation liees pour beaucoup a des besoins de fiabilite necessaires aux
systemes logiciels critiques. Par exemple dans le domaine des transports : le logiciel est autorise si aucune
augmentation du taux de mortalite “normale” n’est constatee. Par exemples les taux de defaillance
acceptables sont : 10−7 pannes/heures pour l’avion et 10−9 pannes/heures pour le train. Ceci implique
donc des probabilites de defaillance plus faible pour la partie logicielle soit : 10−9 pannes/heures (avion)
et 10−11 pannes/heures (train) respectivement.
Il n’est malheureusement pas tres difficiles d’enumerer des problemes recents :
– Ariane 5 : probleme de debordement de calculs et explosion lors du lancement.
– Mars Pathfinder Mission : probleme de reset du a une tache trop longue.
– Robot Spirit : debordement des fichiers et redemarrage continuel.
– Erreur du Pentium (calculs flottants) : sur-cout de 470 106 $.
– Anomalies “spatial” en 1999 : 8 de lanceurs, 16 de satellites, 4 sondes, telescopes, ...
1. En Francais dans le texte, NDTLR !
10
Figure 1.1 – Genie logiciel et economie : chiffres du SYNTEC
Le site suivant contient pas mal d’exemples : http://www.mines.inpl-nancy.fr/~tisseran/cours/
qualite-logiciel/qualite_logiciel.html mais egalement des informations en rapport avec le genie
logiciel.
1.2.3 La crise du logiciel
La notion de crise du logiciel apparaıt des 1969, c’est le constat de la difficulte de mener a bien un
projet de developpement informatique. Par exemple il a ete constate : un depassement moyen de budget
de 70%, un depassement moyen de delai : 50%. On s’est egalement apercu que la maintenance etait aussi
un gros probleme, et qu’une grande partie du cout du logiciel provient de la maintenance (40 a 70 %).
Parmi d’autres tendances qu’il est bon d’avoir en tete : le cout du logiciel est tres superieur a celui du
materiel. Attention il s’agit bien du cout de production du logiciel, le prix public peut lui varier fortement
en fonction du nombre de licences mais aussi pour d’autres raisons commerciales. Il faut egalement noter
que le rapport des couts logiciel/materiel a evolue au cours du temps : 50-50 en 1965, 70-30 en 75, 80-20
en 1985 ... Fabriquer 1 ou 100 exemplaires d’un logiciel ca coute la meme chose (ou a peu pres), mais
commercialiser 1 ou 100 licences d’un logiciel c’est tres different. Si les chiffres du rapport logiciel/materiel
sont discutables, la tendance elle ne l’est pas, le logiciel coute de plus en plus cher. La complexite des
taches demandees a l’informatique s’est aussi accrue fortement depuis les debuts de l’informatique. La
simple taille des programmes est un element qui donne une idee de sa complexite : 1 million de lignes
pour une commande d’avion et 10 millions pour celle d’une station orbitale. Un projet genre OSE3 c’est
quelques milliers de lignes tout ou plus.
1.2.4 L’etat actuel du genie logiciel
La notion de genie logiciel apparaıt dans les annees 60, c’est une discipline jeune et en pleine evolution.
Malheureusement les techniques de developpement sont trop informelles, il existe quelques tendances plus
rationnelles mais encore tres insuffisantes et peu repandues. Les ingenieurs logiciels aimeraient disposer
11
Figure 1.2 – C’est pas drole !
de techniques similaires a celles utilisees dans la construction des circuits electroniques et qui ont permis
d’atteindre des performances d’integration enormes avec des couts de plus en plus minimes. Il n’existe
pas vraiment de consensus sur l’ensemble des technologies du developpement logiciel, dans un sens le
genie logiciel est une “anomalie” par rapport aux autres sciences de l’ingenieur. Elle manque de genie
mais plus vraisemblablement cela est du a un manque de maturite.
Si on regarde un peu de loin l’histoire de la chimie par exemple : l’alchimie c’est pendant le moyen age
jusqu’a Lavoisier (1743-1794), i.e. au moins 300 ou 400 ans (voir plus meme) et pour le Genie chimique
il faut ajouter encore 100 ans ! Moralite : l’informatique c’est un bebe !
Quelques donnees relativement recentes (Standish Group 1995) :
– 31 % des projets non acheves ou abandonnes a la livraison
– 53 % des projets depassent les ressources allouees
– 16 % des projets se deroulent comme prevus
Par rapport aux activites de programmation il y a un facteur d’echelle dans la taille des systemes,
dans la duree et dans les ressources necessaires. Pour preciser un peu les idees : programme = 1 acteur, un
projet informatique = 1 equipe et pas uniquement de la programmation. On atteint des facteurs de taille
100, 1000, 106 par rapport a un programme, les temps de developpement sont de quelques mois*hommes
contre des annees * hommes. La encore on peut prendre l’exemple du projet OSE3 : quelques mois *
hommes. On peut aussi noter l’absence de legislation de type droit du logiciel ! Les professionnels du
contrat considerent que la gestion des contrats informatiques n’est pas satisfaisante.
1.2.5 Evolution probable de l’informatique
Une tendance generale pour le genie logiciel est principalement de promouvoir une veritable science
de l’ingenierie du logiciel. Parmi les facteurs positifs : economie, recherche, interets industriels, systemes
12
Figure 1.3 – C’est toujours pas drole !
critiques, ameliorations constantes des formations. Pour les facteurs negatifs : monopoles, approche trop
commerciale et a court terme, manque de formation, echecs de projet. Les efforts constants de normali-
sation vont se poursuivre et on peut esperer des avances importantes dans le domaine legislatif. Les deux
aspects sont fortement lies vraisemblablement et il faut du temps et des experiences, y compris des mau-
vaises, pour arriver a trouver des indicateurs et des regles definissant les bonnes pratiques. Les travaux en
science cognitive, linguistique et en ergonomie pourraient ameliorer notamment la communication entre
les systemes informatiques et les clients.
1.2.6 Role de l’ingenieur logiciel
L’ingenieur logiciel est un personnage central dans cette evolution, ses aptitudes et competences sont :
– Communication avec le client ou l’utilisateur dans les termes de l’application
– Lecture (voire aide a l’ecriture) du cahier des charges
– Traduction de cahier des charges en specifications
– Maıtrise des niveaux d’abstraction
– Maıtrise des phases et des differentes approches de developpement
– Maıtrise des techniques de programmation
– Capacite a elaborer des modeles, y compris des modeles formels
– Connaissance et pratique des ateliers de genie logiciel
– Capacite d’organisation, de gestion et de communication
C’est plus qu’un metier !
La page Wikipedia donne une petite table des competences visees par le genie logiciel. Cela fait
beaucoup pour un meme homme et donc nous avons des metiers plus specialises dans des sous-domaines.
1.2.7 Responsabilites de l’ingenieur logiciel
Ces competences s’accompagnent egalement de responsabilites :
– Responsabilites associees a la gestion d’un projet
– Responsabilites ethiques, sociales et professionnelles
– Confidentialite
13
– Competence
– Droit de propriete individuel
– Mauvaise utilisation de l’ordinateur
Malheureusement il n’y a pas de droits clairs ou bien formalises sur ces problemes, c’est aussi un constat
qu’a fait le SYNTEC informatique au niveau de la gestion des contrats de developpement logiciel.
Repris d’un cours de J-M. Favre :
X-Software Ltd. does not guarantee the accuracy, adequacy, or completness of any information and is
not responsible for any errors or omissions or the results obtained from use of this software.
1.2.8 Les qualites du logiciel
Quant on parle de qualites il faut s’interesser aux qualites du produit et aux qualites du proces-
sus de production. On distingue les qualites externes (pour l’utilisateur), des qualites internes (pour le
developpeur). Bien sur ces elements ne sont pas independants.
Les qualites externes
Il est souvent utile de distinguer les qualites associees aux fonctions ou besoins du client et d’avoir
d’autres criteres concernant les performances ou l’ergonomie. D’une facon generale on considere actuel-
lement les fonctions ou services rendus par le systeme logiciel et la qualite de service : divers indicateurs
qui caracterisent la facon dont les services sont rendus. Il faut privilegier la fonctionnalite en general : a
quoi sert un logiciel qui fait vite quelque chose d’inutile pour le client. Un defaut souvent reproche aux
informaticiens est de substituer leurs desirs et leur comprehension d’un systeme a celle du client. C’est
un probleme difficile pour lequel actuellement l’elaboration du cahier des charges et la communication
avec le client sont les seules reponses connues.
– Fonctionnalite :
– Correction : le logiciel satisfait a ses specifications, La correction est en principe verifiee par
une phase de verification. Un exemple : un micro-processeur de calculette qui calcule π a 10−6.
– Fiabilite : probabilite d’execution sans defaillance, par exemple un OS avec une fiabilite de 0,92
sur 8 H : fonctionnement 8H sans probleme 92 fois sur 100.
– Robustesse : comportement raisonnable dans des conditions anormales, par exemple la soute
de l’avion s’ouvre en vol, un signal declenche une procedure d’urgence (tolerance aux fautes).
– Performance : gestion efficace des ressources (temps, espace, materiels), mesures et statistiques
sont possibles
– Ergonomie : facilite d’utilisation et d’apprentissage, interface utilisateur conviviale (voir le cours
d’IHM)
Les qualites internes
Les qualites internes sont plus specifiques de l’informaticien mais l’experience a montre qu’elles per-
mettaient de realiser correctement un projet et d’esperer obtenir un produit maintenable. Mais il est clair
que ceci n’est pas definitif et de nombreux travaux se font toujours dans ce domaine.
– Maintenabilite : le produit doit pouvoir s’adapter, evoluer, se corriger ; le plus couteux.
– Verifiabilite : liee aux possibilites de verification et de mesurabilite du produit.
– Reutilisation : reprise de tout ou partie pour la construction d’autres systemes.
– Portabilite : independance vis a vis de l’environnement courant.
14
– Interoperabilite : capacite a interagir avec d’autres systemes
Voici quelques illustrations relatives a ces diverses qualites internes.
– Le changement de numeration telephonique de 8 a 10 chiffres a entraıne une evolution des logiciels
gerant les centraux telephoniques.
– Un simulateur de vol doit respecter les contraintes du systeme reel (inertie par exemple).
– Un module de compte bancaire avec ses variations peut-etre reutilise pour la conception de plusieurs
systemes d’information bancaire.
– Utiliser le meme logiciel sous Windows ou Linux ? (oui avec les applications Java).
– un systeme bancaire distribue doit operer des transactions entre des etablissements ni du meme
groupe ni du meme pays.
Une approche classique pour estimer ces qualites est la mesure du logiciel (metrologie du logiciel) pour
laquelle beaucoup de travaux et d’outils existent, mais ils ne couvrent pas tout. La metrologie est un
aspect du genie logiciel, nous n’en dirons pas plus ici. Par exemple l’outil SourceMonitor permet ce
genre de mesure. L’outil checkstyle, que nous utiliserons, integre quelques notions de metrique.
Les qualites du processus
En ce qui concerne le processus de developpement :
– Productivite : efficacite du processus.
– Predictivite temporelle : capacite a estimer les delais.
– Visibilite : le processus et l’etat du developpement doivent etre faciles a comprendre.
– Supporte : par un ou des outils.
– Maıtrise : par tous les acteurs du developpement.
1.3 Le cycle de developpement
Definition 1.3.1 (Cycle de developpement)
C’est l’ensemble des etapes necessaires au bon developpement d’un logiciel.
Pour les grandes etapes il y a un relatif consensus dans la communaute : analyse/specification, conception,
codage, integration, test et maintenance sont les principales.
Un bon developpement logiciel doit reposer sur une methode et un cycle de developpement bien precis.
On identifie differentes phases dans un developpement : analyse, conception, codage, maintenance, etc.
Chaque phase ou etape produit en general des documents qui vont servir a une autre phase ulterieure. Le
cycle de developpement decrit les enchaınements prevus des differentes phases. Il existe plusieurs cycles
de vie du logiciel nous verrons brievement les principaux.
1.3.1 Le developpement dans sa globalite
– Autour de l’aspect purement logiciel on trouve :
– Gestion administrative
– Documentation
– Gestion des versions et configurations
A cote du processus de developpement proprement dit on distingue des processus paralleles : processus de
gestion administrative, la documentation, la gestion des versions et des configurations. C’est un domaine
tres vaste que nous n’aborderons pas.
Quelques explications sur les differentes activites :
15
retraitinitiation
analyse
codagetest
etm
aintenanceassistance
conception
installation
vérification et validation
planification du projet
pilotage et suivi du projet
gestion de qualitéprojetdu
étude
préalable
gestion de la configuration
formation
développement de la documentation
Figure 1.4 – Schema des grandes taches
– Planification du projet : decomposition en sous-taches et permet d’avoir une reference sur le
deroulement du projet.
– Pilotage et suivi du projet : Le pilotage consiste a enregistrer l’avancement du projet, a comparer
avec la planification et a prendre des mesures correctives.
– Gestion de la qualite : mesure de la qualite, recommandations pour continuer, garantir que le
processus engendre un bon produit. Cette activite pilote en fait la verification-validation et est
parfois regroupee avec.
– La documentation : un element essentiel du logiciel (de gestion du projet, technique ou de
reference, d’utilisation, d’installation et d’exploitation). La documentation accompagne le produit
et donne un etat de son avancement, elle est le moyen de communication entre les differents acteurs.
– Configuration : maıtriser l’evolution du logiciel et de sa documentation. Une notion bien connue
de la configuration est le numero de version et il existe des outils comme CVS. Son interet est
de gerer l’ensemble des elements, leurs evolutions et la coherence du tout au fur et a mesure des
evolutions.
– Verification et validation : La verification consiste a assurer que le logiciel reponds aux besoins
du client (adequation avec le cahier des charges).
– Formation : formation a l’utilisation du logiciel.
– Le retrait : actions a realiser lors du retrait ou abandon d’un logiciel : avertir les utilisateurs,
retirer et eventuellement remplacer le produit, arret du support logiciel.
Figure 1.4 nous avons un exemple de developpement (obsolete) en cascade avec les 5 principales etapes
ou phases : analyse, conception, codage, test, installation.
16
Dans les normes du genie logiciel (ANSI/IEEE 1002) la classification est ainsi decrite :
– Ingenierie du produit : analyse des besoins, conception, codage, integration, debogage, support
du produit, maintenance.
– Verification et validation : revues et audits, analyse du produit, test
– Gestion technique : gestion du processus, gestion du produit, gestion des ressources.
Il faut maintenant ajouter l’aspect specification formelle et preuve qui se positionne de plus en plus dans
l’ingenierie du produit ou dans la validation. A partir d’une specification formelle on peut lancer en
parallele les activites de conception et de verification.
1.4 Les etapes du developpement logiciel
Cette section essaie de donner une idee plus precise concernant le developpement technique du logiciel.
Notamment les differents concepts generaux et les activites qui font consensus sont presentees.
1.4.1 Le cahier des charges
Le cahier des charges est le document le plus important puisqu’il est la reference obligee de tout le
developpement. Il contient le contexte, les besoins et leurs evolutions, on parle de specifications fonc-
tionnelles ou des besoins du client. C’est le document de reference du produit et nous sommes dans une
approche client-fournisseur. C’est un document en grande partie informel et donc l’activite de validation
n’est donc jamais une preuve formelle de l’adequation du produit aux besoins. La validation consiste
a verifier que le produit fourni (le logiciel) est en adequation ou conforme a la demande du client (ses
besoins). Ce document, etabli par le demandeur ou client, definit les clauses techniques, les clauses de
qualite et les clauses administratives applicables a la fourniture recherchee. Il sert de base a la proposition
du fournisseur et pourra faire l’objet d’un contrat, comme preconise dans la norme AFNOR Z61-102. AF-
NOR est un organisme qui elabore des referentiels demandes par les acteurs economiques pour faciliter
leur developpement strategique et commercial, voir http://www.afnor.org/portail.asp.
Un modele
Voici un modele de cahier des charges pour avoir une idee plus precise de ce qu’il contient.
– Positionnement et objectifs : dans quel contexte le cahier des charges est-il etabli et quels sont
ces objectifs.
– Specifications applicatives ou fonctionnelles : descriptions des donnees, traitements, presentations,
interfaces.
– Specifications techniques : informations plus specifiques sur le contexte.
– Contraintes de realisation.
– Specifications administratives : budget, delais, propriete, clauses legales.
– Specifications d’evaluation : les elements qui permettront de valider l’offre faite par le futur
contractant.
La forme et le contenu sont variables d’une entreprise ou d’un client a un autre, le principal est de
s’adapter et de bien comprendre a quoi sert ce document. D’autre part il decrit le point de vue du
client et donc pas mal de considerations n’interessent pas directement le developpeur ... Celui-ci est plus
particulierement concerne par les specifications fonctionnelles et applicatives. Une activite importante de
l’ingenieur informaticien est de participer a la redaction de ce type de document et de pourvoir le lire et
le comprendre.
17
Exemple : le carnet d’adresse
Pour illustrer partiellement ce concept important vous trouverez ci-dessous un exemple pour un carnet
d’adresse logiciel.
Objectifs : la societe machin veut gerer un carnet d’adresse de ses clients et integrer celui-ci dans son
systeme d’information ...
Fonctions : Elle veut pouvoir creer des fiches de ses contacts avec des informations, pouvoir retrouver
une fiche, la modifier ou bien la supprimer. Tout ceci doit pouvoir se faire d’une facon agreable avec
utilisation de menus, souris et clavier, point sur lequel elle a plein d’idees originales ...
Techniques : ce sera sous systeme CPM, avec 10KO de RAM et un processeur a relais electromagnetiques !
Contraintes : standard XXL et pas le droit de fumer ni de manger dans les locaux.
Administration : 3 mois sur place, 4 personnes avec portables, 10MF en 10 versements ...
Evaluation : tests intensifs en interne pendant un mois sans restriction
Le CDC selon J-R. Abrial
Pour insister sur cette notion voici le point de vue d’un expert du domaine.
Le cahier des charges d’un systeme informatique est constitue par l’ensemble des documents
qui rassemblent, du point de vue du client, tous les elements techniques a partir desquels un
futur contractant va pouvoir realiser le systeme en question.
A cote de cette finalite technique, le cahier remplit aussi souvent un role contractuel : il
contient en fait une certaine definition “legale” du systeme a realiser. Cela signifie que tout
litige, qui pourrait apparaıtre entre le client et le contractant au sujet du systeme final, devrait
pouvoir etre tranche, en derniere analyse, apres consultation du cahier.
Cette double caracteristique (technique et contractuelle) du cahier des charges justifie son
importance et donc le soin que l’on doit apporter a son ecriture.
1.4.2 L’analyse
Definition 1.4.1 (Analyse informatique)
Terme general designant la comprehension et la formulation d’un probleme. Une analyse part du cahier
des charges et produit une specification.
Partant des besoins du client exprime dans le cahier des charges, l’analyse produit des specifications fonc-
tionnelles du systeme, c’est a dire une formulation sensee etre plus complete, moins ambigue, structuree,
... des besoins. Il existe une approche dite analyse formelle et qui produit une specification formelle, c’est
a dire redigee dans un langage rigoureux.
Attention une specification decrit seulement le probleme.
L’analyse des besoins designe l’activite de “specification” des besoins du client. Il s’agit de preciser,
de detailler et d’eclaircir le contenu fonctionnel et technique du cahier des charges. Du fait des deficiences
d’une analyse informelle de plus en plus de methodes recourent a des langages semi-formels voire formels.
Il existe par exemple des procedures visant a rationaliser l’analyse des besoins et utilisant la verification
de modeles ou des techniques de traitement des langues naturelles. UML peut etre considere comme un
langage semi-formel, sa semantique laisse serieusement a desirer d’ailleurs.
18
1.4.3 La specification formelle
Les langages B, PVS ou COQ sont des exemples de langages de specifications formelles. Le but es-
sentiel est de permettre une description d’un probleme dans un langage ayant une semantique formelle
(une approximation parlante est mathematique). Cela permet des verifications, traduction automatique
en code, tests automatiques, documentation, de la rigueur, etc. C’est une approche tres importante pour
le developpement de logiciel dit critique. D’un point de vue methode de developpement cela autorise une
construction du logiciel par transformation ou generation de code a partir de la description formelle. Tou-
tefois, malgre tous ces avantages ceci n’est pas si simple a mettre en œuvre. Le recours aux specifications
formelles est exige dans certains developpement ou par certains clients.
1.4.4 La conception
Activite destinee a produire une solution a un probleme
Cette activite part du resultat de l’analyse et son resultat est un ensemble de documents decrivant :
architecture, solutions fonctionnelles (algorithmes), considerations de performances, format des donnees
d’entree et de sortie ... Dans les projets un peu complexe on distingue au moins la conception grossiere
et la conception detaillee, on peut donc avoir plusieurs niveaux de description de la solution.
1.4.5 Le codage
Activite plus traditionnelle de programmation ou d’implementation du resultat de la conception dans
un langage executable (ou plusieurs langages). Il s’agit du codage dans un langage de programmation,
i.e., de la traduction generalement des structures de donnees et des algorithmes definis dans la phase de
conception.
1.4.6 L’integration
Un logiciel un peu complexe doit interagir avec l’exterieur ou d’autres systemes existants, mais il est
aussi generalement en plusieurs morceaux qu’il faut donc assembler, on parle d’integration. Concretement
cette phase realise les liens entre les differents morceaux concus et ceux avec lesquels le systeme doit inter-
agir. Le systeme final est donc compose d’un ensemble de sous-systemes qui sont assembles et d’interfaces
ou de connexions avec d’autres systemes. Il peut y avoir integration materiel et logiciel (co-conception)
dans certains cas notamment les systemes embarques. Eventuellement ce materiel peut etre non informa-
tique (robotique, capteurs, etc). L’aspect architecture materielle ou logicielle du systeme est apparente
ici car c’est le plan d’assemblage du systeme global.
1.4.7 Le debogage
Une activite classique et naturelle et qui a fait ses preuves est celle du debogage ou de recherche et
correction des erreurs. C’est une tache couteuse et assez “artistique” mais une reponse pragmatique au
probleme difficile de l’adequation et de la validation du logiciel. L’activite de debogage est naturelle et
bien connue, mais neanmoins a certaines tares irremediables.
Insuffisance fondamentale : trouve des erreurs mais ne prouve pas qu’il n’y en a plus.
Il existe quant meme quelques techniques pour rationaliser les tests et trouver des erreurs, mais insuffisant
avec les systemes infinis ou tres gros en particulier car les tests ne peuvent pas etre exhaustifs. Il y a aussi
19
une perte d’efficacite : plus une erreur est trouvee tardivement plus cela coute cher a corriger. Toutefois
des outils et des methodes existent et ils sont indispensables en pratique.
1.4.8 La maintenance
Il s’agit d’un aspect important et crucial de le vie d’un logiciel : c’est l’ensemble des activites destinees
a ameliorer, adapter ou corriger un logiciel. On distingue en fait plusieurs cas :
– Perfectionnement : amelioration des performances, pas de changement fonctionnel.
– Adaptation : a l’evolution de l’environnement.
– Correction : debogage alors que le produit est livre et en utilisation
Par ailleurs on retrouve la distinction fonctionnel/efficacite : le premier cas ne change pas les fonc-
tionnalites seulement les performances. Un exemple du premier cas est l’acces a une base de donnees que
l’on veut optimiser. Pour le 2eme : changement des adresses, des telephones, des francs en euros autant
d’exemples recents qui ont coute parfois tres chers. Le 3eme cas est plus classique. Les cas 1 et 2 sont
plutot faits a froid (hors fonctionnement) mais le cas 3 survient parfois a chaud, par exemple un serveur
gerant les transactions des cartes bancaires que l’on ne peut pas completement arreter.
1.4.9 Inspection ou revue de code
Definition 1.4.2 (Inspection ou revue de code)
Il s’agit d’une analyse manuelle avec une ou un groupe de personnes de la description du systeme,
generalement du code.
Elle ne constitue pas une phase du cycle car peut s’appliquer a tous les produits du cycle de developpement.
C’est une activite importante pour la qualite du logiciel et elle peut prendre des formes tres diverses. La
revue se fait en se referant a un guide des regles de developpement en usage dans l’entreprise (standard,
norme, etc), souvent en interaction avec les auteurs. Une organisation courante est un groupe heterogene
avec un programmeur experimente, ils lisent les codes sources et signalent des erreurs ou les doutes,
eventuellement peuvent tester manuellement des cas. Meme si cela peut paraıtre assez stupide comme
facon de faire, l’inspection de code a ete prouvee comme etant une activite essentielle pour la qualite !
Des estimations donnent de 50 a 90 % d’elimination de problemes contre 30 % avec des
tests !
Pour plus de details voir : http://www-lor.int-evry.fr/~raffy/Poly/v&v.htm, Wikipedia et http:
//www.site.uottawa.ca/~ssome/Cours/SEG3603/reviews.pdf
1.4.10 Atelier de genie logiciel
Definition 1.4.3 (Atelier de genie logiciel)
Un AGL ou environnement de developpement est un ensemble d’outils logiciels et materiels assistant le
developpement
Il a pour but d’aider a realiser, controler et suivre un logiciel tout au long de son cycle de vie. Il doit
faciliter la coordination des differentes taches, mesurer et ameliorer la qualite du produit. Nous disposons
d’outils comme MSProject plutot specialise dans la gestion du projet et Eclipse plutot pour les aspects
techniques du developpement.
20
1.5 Les methodes de developpement
Il n’existe pas une seule methode ou approche pour developper un logiciel, c’est un domaine qui est
toujours en pleine evolution.
Les principales approches du developpement qui seront commentees :
– Modele de la cascade et cycle en V
– La programmation exploratoire
– Le prototypage
– Par reutilisation
– Autres : hybride, par exemple le modele en spirale ou RUP
On peut envisager d’utiliser conjointement differentes approches mais attention a la gestion complexe du
processus global.
1.5.1 Le cycle en V
analyse
conceptiongénérale
conceptiondétaillée
codage
test unitaire
et testintégration
et testinstallation
Figure 1.5 – Le cycle en V
Le premier etait en cascade ou en chute d’eau, puis le V est apparu et presente pour des raisons his-
toriques. L’AFNOR Z67-130 propose quelque chose de legerement different avec la validation en derniere
phase. Processus assez bien maıtrise mais difficile de prendre en compte des modifications, par exemple
des erreurs constatees lors d’une phase. L’amelioration principale entre la cascade et le V est d’avoir mis
en correspondance logique les phases du developpement.
1.5.2 La programmation exploratoire
On part d’une specification informelle et on itere codage et evaluation par tests. Des tendances actuelles
sont RAD (rapide a developper) ou eXtreme programming par exemple. Le processus est trop simple, la
prevision des couts impossible et le produit est souvent de mauvaise qualite. Mais c’est souvent la seule
connue des amateurs.
1.5.3 Le prototypage
Tres proche de la precedente, prototype : logiciel developpe rapidement sans soucis de performance,
mais l’objectif n’est generalement pas de fournir un vrai produit utilisable. Le prototype peut-etre jetable
ou evolutif, mais son principal interet est de permettre de completer les specifications au fur et a mesure
21
de l’evolution. Le probleme est le processus peu structure et difficile a gerer en general. Peut servir a
une meilleure comprehension des besoins ou des interfaces utilisateurs. C’est une variante de la methode
precedente qui demande souvent un langage adapte.
1.5.4 Par reutilisation
Le principe est d’essayer de maximiser l’investissement fait dans les developpements precedents et
d’essayer de reutiliser des composants existants. On definit une architecture a partir d’autres elements
logiciels disponibles et il faut assembler le tout. Le processus est gerable et economique, mais les difficultes
sont : l’interoperabilite, la fabrication des composants, la recherche et l’adaptation des composants. Les
techniques a base de patron, de genericite, de template, peuvent s’apparenter a cela. Cette approche est
la base des lignes de produits logiciels qui s’inspire des lignes de produits industriels.
1.5.5 Le cycle en spirale
Aujourd’hui on preconise des iterations, donc plutot un cycle en spirale. C’est un cycle assez interessant
notamment pour les developpements a objets. On produit d’abord un prototype qui est affine au cours des
differents tours de la spirale. Ce modele est reconnu pour certains avantages : une plus grande attention
sur la reutilisabilite, meilleure elimination des erreurs, objectifs de qualite pris en compte et integre
maintenance et developpement dans un meme contexte.
évaluation et réduction des risquesplanification
développement et validation
identification des objectifs
Figure 1.6 – Le cycle en spirale
22
Chapitre 2
Introduction a l’architecture
logicielle
Soit une application qui fait environ 15000 lignes de Java donc plutot petite mais neanmoins pas simple
a comprendre. Comment faire pour aborder cette application si je veux la comprendre ou la corriger ou
encore m’en inspirer ? Mais si je dispose d’une representation graphique me montrant des abstractions
lisibles des classes et les relations qu’elles entretiennent entre elles comme dans la figure 2.1, alors j’ai
deja une comprehension macroscopique du systeme qui peut etre utile pour discuter de developpements
additionnels ou de restructuration ou de partie que je veux reutiliser etc.
Cette notion d’architecture est l’equivalent des plans de constructions d’une maison, des plans tech-
niques (http://fr.wikipedia.org/wiki/Dessin_technique en automobile ou en mecanique, des schemas
electriques ou electroniques. Dans tous les domaines ou il existe une ingenierie, un tel support de commu-
nication et de travail est utilise. Une importante difference avec tous ses domaines est que ces notations
ne sont pas encore standardisee en informatique et leur usage n’est pas encore tres repandu.
2.1 Regles de conception
Pour la suite de vos travaux en Java il est imperatif de respecter certaines conventions d’ecriture
de vos programmes. Une classe concrete doit definir des attributs prives et des accesseurs public, un
constructeur par defaut. La fonction principale main doit etre placee dans une classe a part appelee Test
par exemple comme dans la figure 2.2.
Sauf cas vraiment tres precis ne melanger pas fonctions et procedure, isoler les operations d’entree/sortie
ou les presentations graphiques des calculs. Un des objectifs de ce cours est d’ailleurs de renforcer vos
connaissances des bonnes regles de programmation et nous verrons des outils pour aider en ce sens comme
l’utilisation systematique de la javadoc ou des normes de codage.
2.2 Definition
Definition 2.2.1 (Architecture logicielle)
Une architecture logicielle est une description abstraite et structuree d’un systeme logiciel futur ou exis-
tant.
23
Figure 2.1 – STSLib le diagramme des classes
Le principe d’une architecture logicielle est d’abstraire des informations structurelles et organisationnelles
d’une application logicielle. Cela permet de donner une organisation du systeme d’une facon “simple” et
“lisible”. C’est egalement un guide pour l’analyse et la conception et qui ameliore la comprehension du
systeme. Ce genre d’information est indispensable pour maintenir voire re-concevoir le systeme.
Nous allons prendre un petit exemple pour illustrer cette notion et les notations que nous utiliserons.
Il s’agit d’une version simple du jeu de Nim, nous avons trois categories de joueur. Une partie se joue entre
deux joueurs et nous pouvons faire un choix du nombre d’allumettes manuellement ou aleatoirement.
Le joueur doit faire les choix du type d’initialisation du tas ainsi que la categorie des joueurs (Humain,
Simple, Expert). Il peut egalement propose des valeurs en remplacement de celles par defaut. La sortie
se fait par le bouton de sortie de la fenetre. Le bouton LANCER, figure 2.3, lance la partie qui se fait
par l’intermediaire d’une autre fenetre.
Cette nouvelle fenetre affiche les informations relatives au deroulement de la partie. Un bouton est
associe a chacun des joueurs et ne s’utilisent qu’en alternance. Lorsque la partie est finie le bouton nouvelle
partie permet de retourner a la fenetre d’initialisation et ferme la fenetre courante. On peut interrompre
la partie en fermant la fenetre. Apres une presentation du fonctionnement utilisateur (ou principe du jeu
dans notre cas) comment faire pour expliquer la conception de ce systeme ?
24
// Fichier MaClasse
public class MaClasse {
private int QI;
public MaClasse () { this.QI = 32; }
public int getQI() { return this.QI; }
public void setQI(int q) { this.QI = q;}
...
} // fin MaClasse
// Fichier Test.java
public calss Test {
public static final vois main(String [] args) {
MaClasse ma = new MaClasse ();
...
}
}
Figure 2.2 – Exemple MyClass
2.2.1 La notion d’interface
C’est une notion qui est d’abord apparue dans le domaine des specifications formelles pour etre ensuite
introduite dans les langages, comme Java ou les notations d’UML. Vous l’avez deja aborde concretement
avec Java mais cette notion est tres generale en conception et en specification.
Definition 2.2.2 (Interface)
Une interface donne les regles syntaxiques d’utilisation d’une classe ou d’un composant logiciel en general,
elle decrit les services publiques du composant.
En pratique une interface est constituee d’un ensemble de profils ou de signature des services ou operations
de la classe ou du composant. Par exemple le profil ou la signature du service check de la classe Joueur
est : check : Joueur TextField Integer --> Integer. Il indique le nom du service, les types des
arguments et le resultat. Ici il s’agit d’une fonction, dans le cas d’une procedure il n’y a pas de type
resultat ou alors on utilise un type specifique comme void en Java. Attention le vocabulaire est varie ici :
on peut parler de type et ceci est justifie car une interface defini un type ; on parle aussi de type abstrait
car l’implementation n’est pas decrite, un terme equivalent est aussi celui de signature qui s’applique a
la fois pour un profil et une interface. Fondamentalement, aux details de presentation pres, une signature
c’est un nom d’operation, si c’est une fonction ou une procedure, les types des arguments et le type du
resultat si besoin. L’outil javap permet d’avoir l’interface (et plus) d’une classe compilee Java (fichier
.class). La figure 2.5 represente l’interface de la classe Joueur obtenue en utilisant javap.
Vous remarquerez que dans les profils le type Joueur a ete omis car il est implicite en programmation
par objet, mais attention cette habitude n’est pas valable en programmation fonctionnelle par exemple.
Cette notion d’interface est tres utile a des fins de documentation et pour pouvoir realiser des
developpements separes sur des composants. En realite l’interface a un sens plus general : elle abstrait
des informations d’un composant logiciel. Dans un sens plus large on peut egalement ajouter d’autres
informations dans une interface, notamment une description formelle de la semantique des operations.
25
Figure 2.3 – La vue principale du jeu de Nim
Figure 2.4 – La vue en cours de partie
2.3 Petite introduction a UML
UML pour Unified Modelling Language est un langage de modelisation tres utilise en informatique
et qui fait quasiment office de standard dans l’industrie. Il s’agit d’un langage tres complexe et nous
n’aborderons ici que quelques notions parmi les plus utiles, des elements des diagrammes de classes et de
sequences principalement. Un developpement plus complet est fait dans l’UV GL en GS1. Un langage de
modelisation va nous servir a ecrire des modeles de systemes logiciels. A l’origine UML n’etait pas tres
bien adapte aux architectures, mais c’est un peu mieux avec la version 2.0 actuelle. En programmation
modulaire, la notion de base est un module et on adopte le principe de faible couplage et forte cohesion
entre les modules, ceci s’applique surtout aux classes et aux packages dans notre cas. Il existe egalement
des ADL ou langage de description d’architectures mais ils ne sont pas encore d’un usage tres repandus.
2.3.1 Organisation en packages
Definition 2.3.1 (Package)
Un package est un moyen de structure de facon arborescente des elements de modelisation.
Une notion tout a fait similaire est celle de repertoire dans le systeme d’exploitation Unix par exemple.
Donc un package sert generalement a regrouper des classes et eventuellement d’autres packages. Les
packages sont organises au moyen de relations :
– Notion d’importation : le package Solver utilise/importe Fourrier, c’est une notion d’inclu-
sion/imbrication de package.
26
// Interface de la classe Joueur
Compiled from "Joueur.java"
public abstract class fr.emn.jroyer.nim.Joueur extends java.lang.Object{
private java.lang.String nom;
public fr.emn.jroyer.nim.Joueur ();
public java.lang.String getNom ();
public abstract int compter(int);
public java.lang.String toString ();
public int check(int , java.awt.TextField );
}
Figure 2.5 – Interface de Joueur obtenu par javap.
– Notion de client - fournisseur : une entite (operation, module) a besoin d’une autre entite pour
se realiser. La fleche en pointillee indique une dependance en UML que l’on peut qualifier par un
stereotype (<< ... >>) si on veut en dire plus.
Maths Fourrier
Solveur
Outils
<<import>>
<<import>>
compute()
Calculator
<<import>>
Figure 2.6 – Exemple de paquetage
L’organisation en packages donne une description statique pauvre mais utile par exemple pour ordon-
nancer les taches de compilation des differents modules d’une application.
2.4 Description d’une classe
Pour decrire une classe en UML on utilise une boite avec trois compartiments comme dans la figure 2.7.
Cette classe definit 4 attributs : les deux joueurs, le courant et le nombre d’allumettes. Il y a plusieurs
services, certains pour l’acces aux attributs mais d’autres qui calculent des informations ou modifient
l’etat de l’objet courant. La description de l’interface est insuffisante pour montrer la semantique d’une
operation, elle donne la syntaxe uniquement. Cette description nous donne l’interface de la classe Arbitre
mais aussi les parties publiques car celles-ci ont une importance forte.
Une partie publique est soit un champ publique, soit un champ protege ou prive pour lequel il existe
27
Arbitre # premier : Joueur # deuxieme : Joueur # courant : Joueur # tas : Integer + getPremier() : Joueur + getDeuxieme() : Joueur + getTas() : Integer + setTas(Integer) + getCourant() : Joueur + encore() : Boolean + Arbitre() : Arbitre + Arbitre(Joueur,Joueur,Joueur,int) : Arbitre + initialize(Joueur,Joueur,Integer) + enleverEtChanger() + nim() + toString() : String + changer()
Figure 2.7 – La classe Arbitre.
un accesseur (lecture ou ecriture) publique.
Joueur# nom : String + Joueur() Joueur + getNom() : String + compter(Integer) : Integer + toString() : String + check(Integer, textField) : Integer
Figure 2.8 – La classe Joueur.
Les notations de portee sont :
– # : designe un element protege en UML
– + : designe un element publique (le defaut)
– - : serait un element prive
2.4.1 Description d’une instance
Une instance se decrit par une boite avec deux compartiments (voir figure 2.9) un pour le nom et un
autre pour sa description. Le nom est un identificateur, si il est absent on parle d’instance anonyme et il
est generalement type par le nom de la classe. La description d’une instance est l’ensemble des noms des
attributs avec une valeur compatible avec le type declare dans la classe de l’instance.
2.4.2 Relations
On indique en italique qu’une classe est abstraite ou avec le stereotype � abstract�, par exemple dans
la figure 2.8. Il existe une notation identique pour les methodes.
28
Figure 2.9 – Une instance.
Expert
+ Expert(String) : Expert + compter(Integer) : Integer + toString() : String
Figure 2.10 – La classe Expert.
Les classes entretiennent entre elles des relations ou associations dans la terminologie UML. Parmi
celles-ci certaines sont predefinies :
– La relation de composition/agregation relie une classe avec ses parties, celles qui nous interessent a
ce niveau sont les parties visibles.
– La relation d’heritage a un sens tout a fait similaire a celle de l’heritage en Java.
La sous-classe Expert herite de Joueur et redefinit certaines methodes.
2.4.3 La hierarchie des classes
Dans un diagramme des classes les fleches a bout triangulaire (figure 2.11) represente l’heritage en
UML. C’est un des cas particuliers de relation entre les classes. Dans la figure 2.11 il y a aussi un exemple
de commentaire UML. Ces boites de commentaires sont bien pratiques, en particulier si vous voulez poser
une contrainte sur la classe (par exemple elle a une unique instance, ou son attribut toto est positif, etc)
vous pouvez attacher un commentaire informel a la classe et decrivant la contrainte voulue.
Joueur
Humain Simple
Expert
Exemple d'une note :héritage et deux sous
classes
Figure 2.11 – L’organisation des joueurs
29
2.4.4 La relation de composition
+ getPremier() : Joueur + getDeuxieme() : Joueur + getTas() : Integer + setTas(Integer) + getCourant() : Joueur + encore() : Boolean + Arbitre() : Arbitre + Arbitre(Joueur,Joueur,Joueur,int) : Arbitre + initialize(Joueur,Joueur,Integer) + enleverEtChanger() + nim() + toString() : String + changer()
# tas : IntegerArbitre
Joueur
3
premier
courantdeuxième
Figure 2.12 – La relation de composition
Ce nouveau diagramme (figure 2.12) dit qu’une instance de la classe Arbitre utilise trois instances de
la classe joueur. La relation de composition/agregation designe une notion de tout partie entre les objets.
Le chiffre 3 represente la cardinalite de la relation. Attention : en UML il y a le losange noir et le blanc,
ici nous ne ferons pas de distinction entre les deux.
2.4.5 Une vue generale
Le diagramme de la figure 2.13 est plus complique. L’idee est de faire apparaıtre la structure de
l’ensemble mais uniquement les parties et services publiques. Pour les services publiques on peut se referer
a la description de l’interface. Bien sur des commentaires doivent accompagner et expliquer l’interet des
liens et des parties. La notation avec le rond designe l’implementation d’une interface (exemple avec
Main et ActionListener). Cela donne une idee des dependances structurelles entre les classes, mais ce
n’est pas suffisant car n’explique pas le lien entre les vues par exemple. Toutefois une telle vue est tres
utile et tres importante pour obtenir rapidement une architecture de votre application : les classes et les
interfaces, les liens d’heritage et les relations de compositions pour les parties publiques.
2.4.6 Que se passe-t-il a l’execution ?
Le type de diagramme precedent dit diagramme des classes represente plutot une structure statique
du programme. Mais si on veut avoir des informations sur le deroulement a l’execution nous utilisons
plutot des diagrammes comme ceux de sequences. Les diagrammes de sequences apportent une reponse
simple et limitee mais tres appreciee pour decrire la chronologie des evenements entre les objets. En effet
ils permettent d’etre plus ou moins detailles ou abstraits et donc s’adaptent bien au niveau de detail que
l’on souhaite.
Dans le diagramme de sequence (figure 2.14 a gauche et a droite) verticalement nous avons les lignes
de vies des objets (le temps) et horizontalement ce sont les envois de messages entre objets. Au depart
(lecture du haut vers le bas partie gauche) il y a un envoi de creation d’un objet de type VueMain par un
objet de type Main. C’est une creation car la pointe de la fleche arrive sur la boite designant l’objet. Les
30
JoueurArbitre
Main
VueMain VueRun
3
Integer
String
JPanel
2
pnlPrincipal
pnlPrincipal
premierdeuxième
courant
tas
nom
defaultPremdefaultSec
defaultTas
vue
modèle
WindowListener
JFrame
ActionListener
Figure 2.13 – La structure generale
deux instances sont anonymes mais nous connaissons leur classe. Ensuite l’instance de la classe VueMain
s’envoie plusieurs messages avec ou sans argument.
– initialize()
– setSize()
– setLocation()
Remarque : <<super>>("jeu de Nim") : sert a designer un appel a la super methode, UML ne connaıt
pas super qui est pourtant un concept interessant dans les objets.
Les messages de la figure 2.14 a droite vous sont connus pour la plupart car ils proviennent de SWING
ou AWT.
– r=getPnlPrincipal()
– setContentPane(r)
– addWindowListener(self)
– this.show()
Le premier envoi avec r:= permet de recuperer un resultat d’une fonction qui sera utilise plus tard.
Attention (voir figure 2.15) la fleche atteint l’objet receveur
Donc le code objet.message(parametre) dans un contexte instance : C correspond a une
fleche de l’instance de C vers objet d’etiquette message(parametre).
Noter que UML est tres riche et tres complexe. Pour faire des presentations plus complexes, en
programmation concurrente ou en IHM on utilise les diagrammes d’etats. UML fournit un formalisme
de ce type appele Statechart. On peut les voir comme une forme condense d’un ensemble fini ou non de
31
:Main
:VueMainnew(self)
<<super>>("jeu de Nim")
initialize()
setSize(...)
setLocation(...)
:VueMain
r:=getPnlPrincipal()
setContentPane(r)
addWindowListener(self)
show()
Figure 2.14 – Un cas d’execution dynamique
diagrammes de sequences. Nous verrons un exemple simple de ce genre de formalisme avec l’exemple du
digit code.
2.4.7 Des outils pour UML
Il existe de nombreux outils payants ou gratuits et plus ou moins sophistique pour UML. Ils sont
capables d’editer les differents diagrammes pour les plus simples. Certains font de la generation de code,
des controles des diagrammes sont possibles et parfois la retro-conception est possible. Par exemple la
figure 2.17 presente une vue de l’outil bouml, mais il en existe bien d’autres comme Jude, Rational Rose,
ou ArgoUml que nous utiliserons.
2.5 Patrons de conception
Pour ameliorer une architecture et rationaliser la conception, plusieurs outils ont ete proposes dont la
notion de patron de conception (design patterns).
Definition 2.5.1 (Patron de conception)
Un patron de conception est une solution particuliere mais eprouvee a un probleme recurrent.
Par exemple pour organiser des hierarchies d’objets il est souvent necessaire d’utiliser le patron composite.
On peut classifier les patrons en structurel, comportemental et fabrique. Un autre element orthogonal
est la cible qui peut-etre la classe ou l’instance. Les patrons servent surtout en conception a capturer
de bonnes solutions a des problemes recurrents. Il existe une autre notion voisine. Framework : modele
d’architecture qui peut etre utilisee pour organiser une application complete, par exemple J2EE pour les
applications Internet en Java. Une difference importante entre les deux est la granularite.
32
Figure 2.15 – Prototype d’un message et son diagramme de sequence.
http://www.research.umbc.edu/~tarr/dp/fall00/cs491.html : est un cours complet sur les patrons
avec application a Java. Nous allons donc passer en revue quelques patrons parmi les plus importants et
les plus utiles dans l’immediat.
2.5.1 Le patron singleton
Le probleme est le suivant : definir une classe ayant une seule instance accessible a differents clients.
Eventuellement on peut avoir besoin de sous-classer cette information pour la redefinir. Un cas typique
est la classe Main principale d’un programme, elle est unique dans le programme. Un autre exemple est la
liste vide qui parmi les listes est unique donc un seul representant concret est necessaire. Mais ce besoin
existe dans beaucoup de cas. Exemple d’une unique connexion reseau partagee, d’un compteur qui est
global et partage par plusieurs processus, maintenir et connaıtre la liste des objets crees d’une certaine
classe, certaines valeurs singulieres d’un systeme peuvent devenir des singletons, etc. Il s’agit d’un patron
de type fabrique pour un objet.
La solution (figure 2.18) passe par une creation d’instance concrete qui va representer les informations
voulues. Cette solution peut etre adaptee pour creer plusieurs elements de ce type au lieu d’un seul. Une
solution un peu rigide est de recourir au qualificatif static qui remplit en partie ce role. Toutefois la
creation d’une instance est plus flexible et plus evolutive grace a l’heritage. Ici la situation est simple
mais l’heritage et la concurrence peuvent notablement compliquer les choses, voir http://java.sun.
com/developer/technicalArticles/Programming/singletons/ : mais attention tres avance !
public class Singleton {
// il est unique
private static Singleton uniqueInstance = new Singleton ();
// le constructeur
private Singleton () {
33
button1:JButton action:Main
setDefaultPrem(un.getText())
setDefaultSec(lautre.getText())un:TextField
setEditable(false)
lautre:TextField
setEditable(false)
letas:TextField
setEditable(false)
msg2:TextField
setText("c'est parti ...")
setModele(....)
VueRun
r:= getVue()
new (r)
Figure 2.16 – Un autre exemple
// faut qd meme travailler un peu ...
}
// l’accesseur
public static Singleton getUniqueInstance () {return uniqueInstance ;}
} // end
Exercice : dans l’exemple des listes d’entiers par patron composite il serait bien d’ajouter le singleton
pour la liste vide ...
Exercice : imaginons que certaines fois j’ai besoin de cet objet mais d’autre fois non alors comment
faire pour l’instancier a la demande lors du premier acces ?
2.5.2 Le patron composite
Le probleme est cette fois d’organiser des informations en liste ou en structures plus complexes de
type arborescente. Il s’agit d’un patron structurel pour des objets. Ce patron permet d’uniformiser les
manipulations des objets de base et les composer en utilisant la classe racine : Compound (figure 2.19).
Exemple : arbre binaire, liste d’arite et de profondeur variable, objets graphiques, expressions arithmetiques,
grammaires des langages, ... La solution passe par une organisation subtile liant heritage et composition.
Attention l’implementation dans un langage fortement type peut-etre parfois delicate. Ce schema possede
de nombreuses variations suivants les operations et les donnees definies dans les classes. On peut egalement
jouer sur le nombre de classes de base, sur la cardinalite du lien de composition, la racine concrete ou
abstraite etc.
Exercice : en principe cette cardinalite, dans le cas d’une racine abstraite, ne devrait pas etre 0 ! pour-
quoi ?
34
Figure 2.17 – Un exemple avec bouml
Figure 2.18 – Schema UML : le singleton
// squelette du code Java du composite
public abstract class Compound {
// une methode
public abstract Type operationGenerale ();
} // end
public class Base extends Compound {
// redefinie
public Type operationGenerale () { ... };
} // end
public class Composite extends Compound {
// redefinie
public Type operationGenerale () { ... };
} // end
– Compound : contient generalement des methodes abstraites redefinies dans les sous-classes.
– Base : redefinition assez triviale car cas de base simple.
– Composite : redefinition assez simple recursive ou iterative suivant ce que l’on souhaite.
Nous verrons l’exemple d’application aux listes d’entiers et de chaıne de caractere lors des TPs. Il
est possible d’enrichir les services de Composite avec des operations d’ajouts et d’acces aux elements. La
35
operationGénérale()
Compound
operationGénérale()data
Base
operationGénérale()data
Composite
*
Figure 2.19 – Schema UML : le composite
definition des operations du composite peut-etre purement recursive ou iterative et dans ce cas il faut
connaıtre le nombre d’elements au niveau courant. En general pas besoin de tester le type du composant,
cela doit rester exceptionnel et controle. Pour une reference assez basique : http://www.javaworld.com/
javaworld/jw-09-2002/jw-0913-designpatterns.html.
Quelques regles a retenir :
– Avoir une structure aussi precise que possible mais extensible : dans une liste “plate” les composants
sont uniquement des feuilles.
– Organiser logiquement les services : une methode commune doit avoir un profil dans la super-classe.
– Eviter les tests de type, ou passer par une methode adequate.
– Exception ou pas exception ? : par exemple la suppression d’un element peut-etre placee dans
Compound ou dans Composite.
– Une politique uniforme recursive ou iterative de definition des methodes doit etre privilegiee.
2.5.3 Le patron etat
Le probleme est assez classique et concerne le codage d’un aiguillage avec des actions associees. Celles-
ci pouvant etre de simple transformations de l’entree ou des actions complexes. Par exemple si je tape
“CTRL i” je passe en mode insertion mais si c’est “CTRL o” je passe en mode reecriture dans mon
editeur. Il existe de nombreuses solutions non basees sur un patron :
– Utilisation du switch : un peu cablee car il faut modifier le source en cas de changement.
– Matrice de transition : bonne solution si le systeme de transition varie mais peut-etre grosse.
– Patron etat : compromis interessant car facilement extensible et modulaire.
– Analyse, lexicale, syntaxique et compilation : voir cours de GS1 !
Beaucoup de solutions existent mais elles ne sont pas forcement comparables en termes de maintena-
bilite, de modularite et de facilite de mise en œuvre. Voir par exemple www.informit.com/articles/
printerfriendly.asp?p=28677 pour d’autres details.
Notre probleme est plus precisement le suivant : coder des etats finis et des changements d’etats
en gardant un systeme maintenable. Il s’agit d’un patron de type comportemental pour un objet. Par
exemple un ascenseur qui a un comportement different suivant qu’il monte, descend ou est a l’arret, d’une
presentation graphique ou d’une vue, etc. La solution passe par l’isolation des etats dans une classe et la
definition d’un gestionnaire ( handler pour associer les actions (voir figure 2.20).
Ci-dessous l’exemple du “digit code” : realiser un controleur qui verifie que la sequence “a,b ,c” a
ete entre sur un clavier avec 4 touches “a,b, c, d”. Et que seulement cette sequence declenchera l’action
voulue (ouverture d’une porte, acces a des donnees confidentielles, etc).
36
State
handle()
State1
handle()
State2
handle()
Context
request()state
state.handle()
Figure 2.20 – Schema UML : le patron etat
C’est l’occasion de parler de machines a etats et transitions : i.e. ce que represente la figure 2.21. Il
existe de nombreux formalismes apparentes : automates, reseaux de Petri, etc.
Les etats (les ronds) representent des situations importantes du systeme (ici il s’agit du nombre de
caractere reconnu) ou des etats dit stables. Ensuite une fleche (ou transition) decrit les changements
d’etats autorises. Une transition porte une etiquette qui designe un evenement et une action (ici la frappe
d’une touche). L’implementation du patron etat pour cette exemple est donnee ci-dessous.
// le digit code
public abstract class State{
// avec nommage explicite
private String _label;
public String getLabel () { return _label ;}
// public abstract State handle(char k); ou mieux ici
public State handle(char k) {return new State4 (); }
} // fin
public class State0 extends State{
public State0 () {_label = "0"; }
public State handle(char k) {
if (k==’A’) {
return new State1 ();
}
else {
return super.handle(k);
}
}
} // fin
Le code Java complet du programme correspondant est donne dans l’annexe A.3. Par rapport au
patron ici Context est la classe DigitCode et la classe State porte le meme nom.
Quelques regles a retenir :
– Faire le diagramme avec le contexte, la classe abstraite etat et les sous-classes plus les services a
definir.
– Utiliser l’heritage pour organiser et simplifier le comportement d’aiguillage.
– Penser au cas d’erreur qui peut etre le comportement par defaut dans la super-classe.
37
Figure 2.21 – Le digit code
– Preferer le nommage implicite (par la classe) plus simple et plus evolutif.
– L’etat peut-etre un attribut d’un objet ou passe en parametre des methodes.
La solution de nommage implicite est la suivante : au lieu d’avoir un champ avec ses accesseurs il suffit
d’ecrire dans la racine State :
public String getName () { return getClass().getName(); }
Nous utilisons ici le fait que nous avons acces a la classe de l’objet, et que celle-ci est vue comme un
objet et donc a des attributs. La generalisation de ce genre de sport s’appelle la Metaprogrammation ...
mais nous n’en dirons pas plus ici.
2.5.4 Le patron observateur
Le probleme est : deux entites sont dependantes l’une de l’autre et comment maintenir dynamiquement
la coherence entre les deux. Il s’agit d’un patron de type comportemental pour un objet. Par exemple :
des donnees et leur presentation graphique comme dans le cas des IHM en general. Tres utile si j’ai une
donnee a presenter sous plusieurs vues qui doivent toutes etre coherentes avec ma donnee. La solution
passe par un double lien observateur - sujet observe qu’il faut maintenir dynamiquement. Ce lien sert de
vehicule pour les notifications et les mises a jour.
Les mises a jour (update) sont propages aux observateurs qui vont alors remettre a jour l’etat observe
(getState). Subject dispose d’une interface pour gerer (ajout/suppression) les observateurs. Le MVC,
vu ou a voir en IHM, peut s’implementer a l’aide de ce patron mais ce patron existe de facon native dans
38
Subject
attach(Observer)detach(Observer)notify()
ConcretSubjectsubjectState : TgetState() : TsetState(t:T)
Observer
update()
observerState=subject.getState()
*
subject
for all e in observersdo e.update()
ConcreteObserverobserverStateupdate()
observers
return subjectState()
subjectState := t notify()
Figure 2.22 – Schema UML : l’observateur
java.util - Observer/Observable. Il sert a la conception des GUI ou le sujet concret est l’evenement
source et l’objet concret l’ecouteur d’evenement.
2.5.5 Le patron visiteur
Le patron visiteur permet une meilleure separation entre traitement et donnees. Mais pour des raisons
de temps nous n’en dirons pas plus.
2.6 Exemples d’API
Une API ou Application Programming Interface n’a rien a voir avec la Pomme d’Api ou un dieu
egyptien ! Un exemple d’API est celle de Java que l’on peut consulter a http://java.sun.com/j2se/
1.5/docs/api/index.html. Si on veut connaıtre l’API d’une classe en Java on utilise javap. Nous en
verrons d’autres exemples avec la plupart des applications et outils pour Java.
javap java.lang.String :
Compiled from "String.java"
public final class java.lang.String extends java.lang.Object
implements
java.io.Serializable,java.lang.Comparable,java.lang.CharSequence {
public static final java.util.Comparator CASE_INSENSITIVE_ORDER;
public int hashCode();
public int length();
static {};
39
public java.lang.String();
public byte[] getBytes();
public char[] toCharArray();
public char charAt(int);
public int indexOf(int);
public int lastIndexOf(int);
public int indexOf(int,int);
public int lastIndexOf(int,int);
public void getBytes(int,int,byte[],int);
java.lang.String(int,int,char[]);
public void getChars(int,int,char[],int);
public java.lang.String(byte[]);
...
}
40
Chapitre 3
Outils et environnements de
developpement
Pour rationaliser la production du logiciel des outils s’imposent. Les taches sont variees et les possibi-
lites de l’informatique sont importantes. Ces outils varient dans leur nature et dans leur degre d’assistance.
Il est possible de les classer en grande famille suivant leur domaine d’usage. La plupart des systemes mo-
dernes disposent d’une aide en ligne et d’une interface conviviale.
Pour la partie outils de developpement Java voir par exemple “Java in a Nutshell”, D. Flanagan [1].
Une autre importante source de documents est Internet. Nous allons nous concentrer sur ce que propose
l’environnent Eclipse. Cette partie du cours doit etre vu comme un aide memoire pour maintenant et
plus tard. En fait nous allons en TP uniquement utiliser l’environnement d’Eclipse et quelques uns de
ces outils : l’editeur, le compilateur, le debogueur, fabriquer un .jar, generer la javadoc, checkstyle ainsi
que l’outil ArgoUml. Attention les tests et illustrations ont ete faits avec Eclipse 3.3 et Java 1.5, des
differences existent si vous utilisez d’autres environnements.
3.1 Editeur
Un editeur permet de creer et de modifier les textes sources des programmes (Java) ou des donnees
(HTML par exemple). De preference il doit reconnaıtre les mots-cles du langage et les mises en forme
(indentation). On dit que l’editeur est dirige par la syntaxe quand il aide au formattage et a l’ecriture
en fonction de la structure logique du texte. Attention : fins de ligne et de fichiers, environnement (Mac
OS, Unix, Wx), codage des caracteres non ASCII peuvent malgre tout vous poser des problemes d’un
environnement a l’autre mais Eclipse est assez a l’abri de ces problemes, mais pas completement.
Eclipse possede son propre editeur, rien a faire de ce cote la. Utiliser la perspective “java” et ouvrir
le fichier a editer. Completion automatique avec CTRL+Espace et compilation/verification a la volee.
3.1.1 Le probleme des accents en Java
Java n’a pas completement regler les problemes d’accents. Pour avoir un caractere accentue de notre
alphabet utiliser une table Unicode et \udddd ou il faut (ex \u00c8 pour e). Mais il est aussi possible
d’utiliser l’outil suivant qui permet de convertir les accents de votre plateforme en accent Unicode :
native2ascii TestE.java > TestU.java produira une fichier TestU.java avec les accents transcodes
en Unicode.
41
Figure 3.1 – Exemple de l’editeur java d’Eclipse
Vous pouvez aussi avoir le probleme suivant sous Eclipse : sauvegarde ASCII impossible car le texte
contient des accents. La solution est d’utiliser UTF-8 partout dans votre espace de travail : Windows >
Preferences > General > Workspace > Text file encoding. C’est la valeur par defaut utilisee pour
tout les fichiers texte du workspace, mais cela peut etre modifie au cas par cas pour chaque projet (clic
droit sur le projet > Properties > section "Info").
3.2 Interpreteurs et compilateurs
Ce sont des outils essentiels pour rendre executable le code source qui est generalement d’un niveau
tres different de celui compris par la machine. Il existe des compilateurs et des interpretes pour quasiment
tous les langages et tres souvent meme plusieurs. Pour Java les principaux sont javac et java mais il en
existe bien d’autres.
La compilation fait une traduction globale puis une execution. L’interpretation traduit pas a pas les
differentes unites et les executent. Ces deux modes ne sont pas equivalents au niveau des performances
mais egalement de l’interactivite. Le cycle “edition - traduction - execution - test” est plus court dans le
second cas. Ce sont les deux modes de base mais en fait la plupart des langages modernes proposent des
solutions diverses melangeant les deux approches. Java utilise a la fois la compilation et l’interpretation
42
Code sourceu1u2...
Code exécutabletraduction
exécution
Compilation
Interprétation
Code sourceu1u2...
traduire u1 puis exécuter
traduire u2 puis exécuter
traduire ... puis exécuter
Figure 3.2 – Compilation et interpretation
mais il existe aussi des compilateurs produisant directement du code machine. Il existe egalement des
“decompilateurs” qui permettent de donner une forme plus lisible (niveau code source) a une code compile.
le bytecode
Les résultats
Interprétation (JVM
)C
ompilation
java
javac
file.java
le source
file.class
Figure 3.3 – Le cas de Java
Pour avoir plus de details sur ces notions voir le cours FI3 “langages et traducteurs”.
3.3 Archives
La notion d’archive est un paquet d’information (generalement des fichiers, un repertoire complet)
representant un document, les sources d’un projet, un executable etc. Ces donnees sont souvent com-
pressees et encodees de facon a en diminuer la taille et a en faciliter l’envoi par reseau. Il existe des tas
de format et d’outils pour les fabriquer et les ouvrir. Sous UNIX on utilise plutot le format tar, sous
Windows le format zip et sous MAC les dmg.
43
3.3.1 Archive Java
Avec Java on utilise egalement les archives zip mais aussi une variante qui est le format jar. Avec
Java : jar permet de creer, observer et extraire des elements d’une archive.
– Fabrication : jar -cvf nim.jar *.class de nim.jar
– Le manifeste : jar -ufm nim.jar MANIFEST
– Execution par : java -jar nim.jar
– jar -tvf nim.jar la commande est inspiree du tar Unix : permet de voir le contenu
– jar -xvf nim.jar pour extraire les fichiers
– Pour avoir un exemple de manifeste : cree le .jar puis l’extraire, voir ci-dessous un exemple
Manifest -Version: 1.0
Created -By: 1.4.2 _09 (Apple Computer , Inc.)
Main -Class: Main
Figure 3.4 – jar sous Eclipse
La creation d’une archive est plus simple sous Eclipse (ou avec ant).
1. Click droit sur le projet pour ouvrir le menu contextuel
2. Suivre export puis jar file
3. Choisissez les ressources
4. Choisissez les options
5. Et voila ...
44
Pour recharger une archive une solution simple est faire une importation du projet existant a partir de
l’archive (import an existing project).
En general l’operation de creation ou d’extraction se fait tres simplement mais il arrive que cela ne
se passe pas bien. Comme vous aurez besoin de savoir faire cela notamment pour rendre les TPs notes,
je vous conseille de passer un peu de temps la-dessus. Un jar ne contient tres souvent que les classes
binaires mais il est possible d’ajouter les sources : lors de la creation il faut cocher la casse “Export Java
source files and ressources”. Il est aussi possible de mettre la javadoc ce qui est utile quand on delivre
un projet a un tiers : il suffit de la generer dans le projet, elle fait partie des ressources generalement
exportees par defaut.
Il est aussi possible de faire un zip avec les sources et les binaires : il faut proceder comme pour un
“.jar” mais on choisit “General” puis “Archive file”. Vous avez alors la possibilite de selectionner ce que
vous voulez mettre dans l’archive.
Il existe plusieurs facons de recreer un projet depuis une archive. Si il s’agit d’un .jar ou .zip il
suffit de l’importer comme un projet existant, c’est le mieux. Par contre si on importe un .jar comme
une archive il va etre memorise sous un repertoire et surement causer quelques ennuis de compilation.
Il est aussi possible d’extraire le projet depuis le systeme d’exploitation puis de creer un nouveau projet
projet Java mais en cochant la casse “from existing sources”. Mais attention si vous utilisez ceci, le projet
n’existe pas dans votre espace de travail et cela peut vous poser des problemes ulterieurement.
3.4 Organisation et construction du logiciel
3.4.1 Gestion technique d’un projet informatique
La gestion technique d’un projet informatique peut-etre tres complexe, car les developpements peuvent
etre multi-plateformes, multi-langages et multi-developpeurs. Il faut pouvoir generer automatiquement
les executables a jour pour une plate-forme donnee. Il y a donc besoin d’outils de gestion de version :
comme CVS par exemple. Mais egalement de lanceur de compilation (make, ant, ...) ou de generateur de
makefile (imake, qmake, ...), gestion de bibliotheques, etc.
3.4.2 Sequenceur de taches
Par exemple prenons un petit projet tres simple
– avec une organisation propre : trois sous-repertoires (SRC, DOC, BIN),
– une fois les sources modifiees mettre a jour les autres fichiers (executables, documentation, ...),
– verifier que le systeme est correct ou a jour et
– faire le menage si besoin.
Noter la hierarchie proposee ainsi que la place et la nature des differents elements. Penser que vous
avez des fichiers de differentes natures (source, code objet, donnees, ...) et variables suivant les langages.
D’ou l’utilisation des extensions ( .java, .class, .html etc). Des outils sont utiles pour cela, par exemple
la commande Unix file :
jroyer@dhcp97 :~/ Documents/COURS/GLFI2/COURS file test.aux
test.aux: LaTeX auxiliary file
45
Figure 3.5 – Un exemple de structure simple
Le role du sequenceur est d’effectuer des operations (compilation, edition de liens, documentation,
...) sur un ensemble de fichiers (dependances). Il utilise des regles de generation et permet d’automatiser
les suites d’operations et eventuellement optimiser les taches a faire. Le plus classique sous Unix est la
commande make et son fichier Makefile. Dans l’environnement Java on utilise plutot ant ecrit en Java
et pour Java mais qui utilise un fichier en XML qui est assez hermetique.
3.4.3 make
– Travail par defaut sur Makefile
– Definit les dependances et les regles de construction
– Une commande simpliste : make voir ci-dessous
– Les regles
– produit : source indique que produit depends de source
– ‘‘tabulation’’ commande definit comment produire produit
– Les regles sont considerees dans l’ordre naturel du fichier
Les dependances permettent de refaire juste ce qui est necessaire pour realiser la tache et donc ainsi
d’optimiser la production.
# NIM/VP2/Makefile
# exemple de makefile simpliste
# 9/6/2006
all :
clean :
rm -f BIN/*.class
46
cleandoc :
rm -f -r DOC /*.*
compile :
javac -d BIN SRC /*. java
docu :
javadoc -public -d DOC SRC /*. java
Attention aux tabulations devant les commandes ! La compilation est plus facile en Java qu’en C++
car javac gere une partie des dependances lui-meme. Noter que comme ce genre de sport est quand meme
un peu delicat une solution est d’avoir des mecanismes de generation de makefile. Il existe entre autres :
qmake et autoconf.
3.4.4 ant pour Java
Cet outil est plutot delicat a utiliser a cause de sa notation XML assez obscure.
– Sequenceur de travaux pour Java et en Java, http://ant.apache.org
– Assez verbeux a cause de la syntaxe XML
– Positionner les variables JAVA HOME, ANT HOME, PATH
– Taches : activites a realiser
– Target : assemblage de taches a realiser
– Propriete : valeur de configuration
Par defaut ant travaille sur build.xml dont voici le squelette :
<?xml version="1.0" encoding="UTF -8"?>
<project name="monProjet" basedir="." default=’’compile ’’>
<!-- [definitions des proprietes ] -->
<!-- [definitions des chemins et patrons] -->
<!-- [definition de la cible] -->
</project >
Un exemple de build.xml :
<?xml version="1.0" encoding="UTF -8"?>
<project name="nim" basedir="." default="compile">
<property name="src.dir" value="SRC" />
<property name="bin.dir" value="BIN" />
<property name="doc.dir" value="DOC" />
<!-- target qui supprime les classes compile et le JAR -->
<target name="clean">
<delete dir="${bin.dir}" />
<delete dir="${basedir }/${ant.project.name}.jar"/>
</target >
<!-- target qui compile le code Java dans le repertoire bin -->
<target name="compile">
<!-- compilation des sources Java -->
<mkdir dir="${bin.dir}" />
47
<javac srcdir="${src.dir}" destdir="${bin.dir}"/>
</target >
</project >
Explications :
– name : le nom du projet
– basedir : le repertoire de base pour tous les chemins
– default : la cible par defaut
– Une cible possede cinq attributs : name, depends, if, unless, description
– depends : liste de cibles prealables
Creation d’un jar :
<!-- target qui cree le JAR -->
<target name="create -jar" depends="clean ,compile">
<!-- creation du JAR , "nim.jar" -->
<jar destfile="${basedir }/${ant.project.name}.jar" basedir="${bin.dir}">
<manifest >
<!-- on indique la classe principale du JAR -->
<attribute name="Main -Class" value="fr.emn.jroyer.nim.Main"/>
</manifest >
</jar >
</target >
<!-- execution du JAR -->
<target name="run">
<java jar="${basedir }/${ant.project.name}.jar" fork="true"/>
</target >
<!-- les deux -->
<target name="build -and -run" depends="create -jar ,run" />
Exercice : faire le javadoc et build complet.
Utilisation de ant sous Eclipse :
– Deja integrer rien a faire de ce cote la
– Parametres dans les preferences d’Eclipse pour ant
– Dans le projet choisir buildpath > new project source et mettre src par exemple
– Il y a par defaut creation du bin et vous devez deplacer les .java dans src
– New > File > build.xml et CTRL+Espace
– Menu contextuel du fichier et Run as Ant Build
3.5 Gestionnaire de version et de configuration
Ce sont des outils destines a aider la gestion des projets en memorisant les differentes evolutions,
modifications et configurations du logiciel.
48
Figure 3.6 – ant sous Eclipse
3.5.1 Concurrent Version System
C’est un des plus ancien outil de ce type, actuellement les utilisateurs utilisent plutot svn. cvs permet
le controle des versions d’un systeme et dispose d’un mode client-serveur permettant le travail a plusieurs.
Il permet les mises a jour, les detections de conflits et les acces concurrents. Il repose sur le principe d’une
base centralisee le “repository” heberge sur un serveur qui memorise les versions des differents fichiers
et des informations (date, auteur, commentaire) annexes. Les utilisateurs sont des clients qui possedent
une copie personnelle du “repository”. Il existe des tas de versions pour tous les systemes d’exploitation.
L’installation du serveur est un peu technique voir par exemple http://okki666.free.fr/docmaster/
articles/linux102.html.
Les commandes principales :
– Creation initiale (pour les gourous) import
– checkout recuperation par le client d’une copie a jour du “repository”
– commit mise a jour du “repository” depuis un client
– update mise a jour de la copie locale
– add/remove ajout/enleve un element du repository
– diff montre les differences entre les versions
– history
Une bonne pratique est de faire un checkout pour la creation initiale, puis avant chaque modification
faire un update puis un commit. Ceci evite des conflits ; en cas de conflit il faut fusionner manuellement
les fichiers.
CVS sous Eclipse existe par defaut, son utilisation est un peu technique, je renvoie au document sui-
vant : http://www.blognote-info.com/index.php?2005/09/23/256-eclipse-et-le-cvs. Sous cam-
pus j’ai depose un document ecrit par Frederic Lepage et qui explique cela plus en details (https:
//nte.emn.fr/campus/file.php/371/OUTILS/eclipse_cvs_ssh.pdf).
Il est preferable d’utiliser SVN, l’installation du client subclispe pour Eclipse est facile grace a la
mise a jour, voir http://subclipse.tigris.org/.
3.6 Documentation
Produire une bonne documentation n’est pas si simple et est une activite importante dans un projet
informatique. On considere generalement trois niveaux : le manuel utilisateur du systeme, le manuel de
reference et la documentation interne du programme. Bien sur des outils peuvent et doivent aider dans
ces taches. La documentation s’adresse soit a un programmeur soit a un utilisateur final, dans tous les
cas il faut s’adapter au public vise.
49
Le manuel utilisateur est evidemment destine a l’utilisateur final et n’est donc pas forcement redige
uniquement par les programmeurs. Il doit etre precis mais egalement pedagogique et contenir des exemples
illustrant toutes les utilisations du logiciel.
Le manuel de reference est une description en details de toutes les fonctions du systeme : precondition,
postcondition, invariant, parametres, effet de bords etc. Il ne faut pas oublier une syntaxe formelle (gram-
maire). Une partie de ce manuel peut-etre (et sera) extraite automatiquement du code, par exemple avec
javadoc.
La documentation interne doit permettre une comprehension rapide des programmes et expliquer
des choix de conception subtiles ou non classiques. C’est une aide importante pour l’evolution ou la
maintenance. Le probleme souvent rencontre est d’en faire trop ou pas assez. Elle est realisee implicitement
par le choix des noms (variables, fonctions, types, ...) et explicitement par les commentaires dans les
programmes ou des documents specifiques.
3.6.1 javadoc
Noter que la javadoc des classes Java est disponible a http://java.sun.com/j2se/1.5.0/docs/. Il
est souvent plus simple de taper dans google java 5 Maclasse. Permet de produire une documentation
de reference a partir de la documentation interne des programmes. Par exemple javadoc Arbitre.java
construit des donnees HTML decrivant la documentation associee dans un style classique. Les fichiers
sources peuvent contenir des annotations qui seront alors ajoutees a la documentation produite. Pour
pouvoir beneficier de cela des conventions d’ecritures doivent etre respectees. Ci-dessous un exemple de
commentaire pour une fonction.
/**
* Describe getPremier method here.
* @return a Joueur value
*/
Entre les /** ... */ se trouve un commentaire de documentation qui est place juste avant l’entite
commentee et qui contient du texte, des balises HTML et des balises @. Apres la commande javadoc
-public *.java on obtient des donnees HTML que l’on peut visualiser avec un navigateur, voir la
figure 3.7
La structures des commentaires javadoc est constituee de balises dont voici quelques unes :
– @author Jean-Claude Royer
– @version 1.4.2.9 du 21/12/2004
– @param taux d’alcoolemie
– @return la valeur booleenne du retrait de permis
– @exception java.io.FileNotFoundException probleme de fichier inexistant
– @link http ://www.emn.fr/x-info/jroyer/
– @see “Le livre de Flanagan”
– @see <A> http://www.emn.fr </A>
– @see InputStream#read(byte[ ], int, int)
Pour utiliser la documentation Java sous Eclipse, c’est plutot simple et bien integre. Dans l’editeur si
vous tapez /**<RETURN> il y a completion automatique et creation de balises avec un texte par defaut. Il
est possible de definir dans le menu propriete du projet le lieu de destination de la documentation HTML
50
produite. Celle-ci sera produite en suivant Project > Generate Javadoc, des informations apparaissent
dans la console.
3.7 Recherche et correction des erreurs
La recherche et correction des erreurs est une activite importante comme nous l’avons vu dans le
cycle global de developpement. Une solution simple est l’ajout d’instruction de trace, mais c’est mieux
de le faire avec des outils ou des directives du preprocesseur. Il est possible d’aller plus loin et plus
rationnellement avec un debogueur qui permet :
– Un mode d’execution pas a pas
– La pose de point d’arret
– L’observation de l’etat des donnees du contexte
– Une vue symbolique (plutot que niveau machine)
Pour le premier niveau on peut utiliser l’outil Log4J ou un outil similaire.
3.7.1 Log4J
log4J est une API “open source” pour tracer les appels dans un programme. La configuration se fait
de maniere externe par un fichier de proprietes. Une fois les messages places il n’y a plus d’intervention
sur le code source.
Pour l’installation :
– Telechargez le fichier a l’adresse suivante : http://logging.apache.org/site/binindex.cgi?
Preferred=http%3A%2F%2Fapache.crihan.fr%2Fdist.
– Choisissez le fichier logging-log4j-1.2.14.zip.
– decompressez le fichier dans un repertoire quelconque (je vous conseille le repertoire Program Fi-
les/Java sous Windows). Pour simplifier la suite je nomme ce repertoire $CheminLOG4J.
– Lancez Eclipse et choisissez le projet pour lequel vous souhaitez utiliser Log4J.
– Faites clic-droit sur le projet puis soit
– Build Path > Add External Archive
– Properties, choisir la categorie ”Java Build Path”, onglet Libraries, faire ”Add External Jars...”
Les deux alternatives font la meme chose, il vous faut dans les deux cas specifier le fichier .jar
de log4J que vous trouvez dans : $CheminLOG4J/Log4J/logging-log4j-1.2.14/dist/lib/ et qui
s’intitule log4j-1.2.14.jar.
Pour verifier que tout s’est bien passe, allez dans le package explorer de Eclipse et regarder si la librairie
log4J apparaıt bien (generalement en dessous de ”JRE System Library”).
Pour deboguer on souhaite tracer le fonctionnement du programme et on insere des println pour
obtenir diverses informations plus ou moins precises. Cette derniere approche souvent pratiquee (je le
fais !) est fastidieuse et embetante et peu efficace sur de vrais grands projets. Le debogueur donne un
niveau tres fin d’intervention mais qui n’est pas tres souple, il ne permet pas forcement facilement d’avoir
une trace d’un sous-ensemble des informations.
Log4J propose une solution bien plus simple mais basee sur le principe des messages et completement
configurable dynamiquement : un fichier de properties permet de savoir ou et quelles informations seront
memorisees. On peut changer cela sans recompiler l’application.
– Un logger (instance de la classe Logger) est un composant qui prendra en compte les commandes
de trace
– En general un logger par classe
51
– static Logger cat = Logger.getLogger(TestLogging.class);
– Les requetes : cat.debug(‘‘...’’) ou info, warn, error, fatal
– Un appender est le lieu ou seront envoyees les informations
– Generalement un fichier mais ca peut-etre bien d’autres choses
– Une mise en page layout est necessaire pour formater les informations dans l’appender
Un logger possede un niveau par defaut DEBUG, les niveaux du plus faible ou plus strict sont : DEBUG,
INFO, WARN, ERROR, FATAL
import org.apache.log4j .*;
public class TestLogging {
static Logger cat = Logger.getLogger(TestLogging.class );
public static void main(String args []) {
cat.debug("Start of main()");
cat.info("Just testing a log message with priority set to INFO");
}
}
Le fichier de configuration :
– Il s’appelle log4j.properties par defaut et se place avec le TestLogging.class
– Sinon java -Dlog4j.configuration=toto.properties TestLogging
– Permet de definir la priorite globale
– Mais surtout les appender et les layout
– L’exemple qui precede est un des plus simples
log4j.rootCategory=DEBUG , dest1
log4j.appender.dest1=org.apache.log4j.ConsoleAppender
log4j.appender.dest1.layout=org.apache.log4j.PatternLayout
Resultat a la console du java TestLogging :
Start of main()
Just testing a log message with priority set to INFO
Plus complexe dans un fichier
# Log4j configuration file
log4j.rootCategory=DEBUG , A2
# Available levels are DEBUG , INFO , WARN , ERROR , FATAL
52
# A2 is a DailyRollingFileAppender
log4j.appender.A2=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A2.file=logfile.log
log4j.appender.A2.datePattern=’.’yyyy -MM-dd
log4j.appender.A2.append=true
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.ConversionPattern =%-5p %d{ISO8601} [%t] - %m%n
jroyer@dhcp97: more logfile.log
DEBUG 2006 -08 -17 15:23:41 ,663 [main] - Start of main()
INFO 2006 -08 -17 15:23:41 ,664 [main] - Just testing a log message
with priority set to INFO
Pour obtenir cela : juste modifier le .properties et relancer java, pas besoin d’une recompilation. Les
messages :
– debug pour des messages d’erreur qui ne devraient pas apparaıtre pendant l’execution du programme
– info similaire au mode verbeux de beaucoup d’applications, c’est a dire des informations utiles
mais pas essentielles
– warn similaire aux warnings quelque chose de pas normal, d’obsolete, de non recommande etc, mais
l’application est capable de continuer correctement son execution
– error ce sont des erreurs mais l’application fonctionne quand meme eventuellement en mode
degrade
– fatal erreur critique l’application s’arrete de facon anormale
– Le mode global permet de filtrer les messages qui sont de niveau egale ou superieur (DEBUG le defaut
etant le plus liberal).
– Pour en savoir plus http://www.vipan.com/htdocs/log4jhelp.html
Ces messages seront memorises dans un ”Appender” et suivant un format configurable. Il est possible
de signifier le niveau de priorite de l’enregistrement des log dans chaque appender. De cette facon seuls
les messages de priorite au moins egale sont memorises.
Le principe est d’inserer ces commandes et ensuite de compiler les classes. Il faut definir un fichier
log4j.properties (qui remplace celui par defaut).
3.7.2 Le debogueur d’Eclipse
Le debogueur d’Eclipse s’ouvre avec la perspective “debug”. Une manipulation simple est la suivante :
poser des points d’arret (double click dans la colonne bleu de l’editeur) puis lancer run as debug ...
et ensuite observer les variables et continuer en avancant pas a pas. Le debogueur est une application
specifique qui peut-etre lancee a la main ou automatiquement lors d’une erreur. Dans l’utilisation manuelle
il y a generalement trois etapes :
53
1. Insertion d’un ou de plusieurs points d’arret (breakpoint) dans le code source et sur la ligne que
vous voulez observer. Lors de l’utilisation du debogueur le programme s’arretera a cet endroit et
l’utilisateur peut alors faire certaines actions. Les options disponibles sur un breakpoint le sont via
un menu contextuel : suppression, desactivation ou pose d’une condition.
2. Dans un deuxieme temps il faut lancer l’application de debogage. L’acces au mode debug se fait en
selectionnant le point d’entree de l’application a observer et soit par le menu contextuel item debug
soit par la barre d’outils et .
3. Apres l’execution si un point d’arret est atteint alors la vue debug devient active et diverses
operations sont possibles. La figure 3.10 montre :
– La pile des appels courants : i.e. les differentes activites qui ont conduit jusqu’a ce point d’arret.
– La barre contient plusieurs fleches permettant d’executer en mode pas a pas notamment.
– La partie en bas a droite vous montre votre source code.
– La partie en haut a gauche comporte generalement trois onglets :
– Variables permet d’observer les objets et les variables et de poser des conditions d’observation
(watchpoints).
– Breakpoints montre les points d’arret et les points d’observation.
– Expressions est une calculatrice symbolique permettant d’evaluer des expressions dans le
contexte courant.
Un petit essai
1. Vous allez recuperer le fichier Fact.java qui definit une classe simple pour calculer factorielle de 3.
2. Vous l’executez et vous devez constater un “debordement de pile”, bon bref une mechante erreur.
3. Double cliquer dans la colonne de gauche sur la ligne if (this.getValue() == 0) (ligne 25). Si
vous voyez apparaıtre un point bleu, vous avez gagne car vous avez placer un point d’arret, sinon
recommencer !
4. Lancer le mode debug et utiliser plusieurs fois la touche step over .
5. Que constatez vous sur le deroulement dans la pile d’execution et sur la valeur de l’objet this ?
6. En deduire ce qui manque, corriger le programme et reverifier avec le debogueur que le comporte-
ment est acceptable.
Exercice de mise en application
Vous trouverez sur campus une archive Nim.jar. Il s’agit d’une version simple sans interface du
jeu de Nim entre un joueur naıf et un autre plus intelligent. Le principe est : deux joueurs enlevent
alternativement 1, 2 ou 3 allumettes (si possible) d’un tas. Le perdant est celui qui enleve la (ou les)
dernieres allumettes. La conjecture est que le joueur intelligent gagne toujours sauf pour les valeurs 0,2,3.
Mais le resultat n’est pas vraiment conforme aux previsions, je n’arrive pas a trouver mes erreurs help,
help !
1. Recuperer le code du jeu, il s’agit de 3 classes et d’un fichier test.
2. Essayer de trouver ce qui ne vas pas en utilisant le debogueur.
3. Corriger et tester.
4. Completer le fichier README avec votre nom et vos remarques sur les erreurs trouvees.
54
3.8 Generation de tests
La generation de tests est un aspect principal de la recherche des erreurs. Une approche simple est
d’ecrire un main de test dans chaque classe. Une solution qui me semble meilleure est de faire une classe
de test pour chaque classe ou methode et de la mettre dans un repertoire particulier. Il existe quand
meme des outils tres sophistiques pour les tests. Nous presentons ici un outil classique pour Java.
3.8.1 L’API JUnit
JUnit est une API destinee a faciliter et rationaliser les tests en Java, voir http://www.junit.org/
index.htm et http://junit.sourceforge.net/javadoc/.
// la classe de base a tester
class Money {
private int fAmount;
private String fCurrency;
public Money (int amount , String currency ){
fAmount = amount;
fCurrency = currency; }
public int getAmount () {return Amount ;}
public String getCurrency () {return fCurrency ;}
public boolean equals(Object anObject) {
if (anObject instanceof Money) {
Money aMoney= (Money)anObject;
return aMoney.getCurrency (). equals(getCurrency ()) && getAmount () == aMoney.getAmount ();
}
return false;
}
public Money add(Money m) {
return new Money(getAmount ()+m.getAmount(), getCurrency ());
} }
Un exemple de test :
// suite
public void testEquals () {
Assert.assertTrue (! f12CHF.equals(null ));
Assert.assertEquals(f12CHF , f12CHF );
Assert.assertEquals(f12CHF , new Money(12, "CHF"));
Assert.assertTrue (! f12CHF.equals(f14CHF ));
}
}
// La classe pour les tests de Money.java
import junit.framework .*;
public class MoneyTest extends TestCase {
private Money f12CHF;
55
private Money f14CHF;
public void testSimpleAdd () {
Money expected= new Money (26, "CHF");
Money result= f12CHF.add(f14CHF );
Assert.assertTrue(expected.equals(result ));
}
protected void setUp() {
f12CHF= new Money(12, "CHF");
f14CHF= new Money(14, "CHF");
}
// ...
Explications :
– Creer une classe qui herite de TestCase et se nomme *Test
– Un package a part de l’application serait mieux (mais parfois pas possible)
– Le premier cas est un test simple mais en general on utilise ce qui suit
– Une “Fixture” est un ensemble de declaration pour les tests
– La methode setUp() vous permet de les initialiser
– Ensuite ecrire des methodes de test (sans argument) avec des Assert...
– Assert.assertTrue(!f12CHF.equals(null)) c’est clair non ?
– Finalement pour executer il faut un TestRunner
tearDown est la methode symetrique de setUp pour recuperer les objets de la “fixture” a la fin du test.
Quelques exemples de tests sont : assertEquals, assertFalse, assertNull, assertSame, fail,
failNotEquals, ...
Execution des tests :
– Un peu complexe (test simple ou suite, statique ou dynamique)
– Une solution simple et pratique : suppose que les methodes s’appellent test*
// equivalent a la classe contenant un main
import junit.framework .*;
public class SimpleSuite {
public static Test suite () {
return new TestSuite(MoneyTest.class);
}
}
Cette API est integree sous la forme d’un plugin Eclipse, mais il vous faut l’activer pour le projet en
cours. Aller dans Build Path > librairie > add external jar et ajouter
Application/Eclipse/plugins/...junit/junit.jar. Pour la creation d’un test : New > creation
Junit test case puis l’executer run as Junit test. Pour la creation d’une suite de tests new > other
> java > junit > test suite
Cobertura, http://cobertura.sourceforge.net/, est un outil pour calculer la couverture, i.e. le
pourcentage de code qui est couvert par les tests. Il est donc un apport complementaire de JUnit tres
appreciable.
56
3.9 Mesure des performances
Il est souvent utile d’avoir une idee au moins partielle des performances de son code. Par exemple
connaıtre les temps relatifs entre differentes parties. Plusieurs outils de “profiling” “benchmarking”
existent et ce genre d’analyse est indispensable pour optimiser valablement son code. En effet on peut
parfois optimiser radicalement une fonction mais qui etant tres peu utilisee dans le programme le resultat
sur l’execution globale est quasi invisible. Il existe sous Unix : gprof, time, pour Java : option de
jvm : Xprof ou Xrunhprof. Toutefois dans le cadre d’Eclipse le plugin TPTP est tres interessant, voir
http://www.eclipsetotale.com/articles/TPTP.html.
3.10 Qualite du code
Plusieurs qualites peuvent etre attribuees a un code, nous en avons eu un apercu tres grossier dans le
cours general sur le genie logiciel. Nous allons ici avoir un apercu plus precis de la qualite du style Java mais
le lien suivant http://irb.cs.uni-magdeburg.de/sw-eng/us/bibliography/bib_main.shtml donne
une bonne idee de l’ampleur de ce domaine. Par exemple l’outil SourceMonitor par exemple permet ce
genre de mesure (http://www.campwoodsw.com/sourcemonitor.html).
3.10.1 Checkstyle
Il s’agit d’un outil permettant de verifier le respect de regles predefinies de codage http://checkstyle.
sourceforge.net/. Le systeme est configurable, par defaut il utilise les conventions Sun http://java.
sun.com/docs/codeconv/.
3.10.2 Installation
L’installation est tres simple sous Eclipse en utilisant la mise a jour du package.
– Dans le menu help prendre l’option software update > find and install.
– Une boite s’ouvre, cliquer sur next.
– Une nouvelle boite apparaıt vous cliquer alors sur new remote site (j’imagine que vous ne l’avez
pas deja installe ...).
– Donner les informations suivantes : name checkstyle et URL http ://eclipse-cs.sourceforge.net/update
finir avec OK.
– Vous devez voir maintenant une ligne checkstyle cochee et bleu (si ce n’est pas le cas la cocher),
voir figure 3.11.
– Cliquer sur Finish en principe le telechargement et l’installation vont se faire automatiquement
eventuellement avec demande de confirmation.
Une documentation d’installation existe a http://eclipse-cs.sourceforge.net/, la documentation
utilisateur est incluse dans la distribution installee.
Une fois ceci fait si vous voulez utilisez cet outil sur un projet il faut :
– Menu contextuel (clique droit) sur le projet et ouvrir Properties.
– Cliquer ensuite sur checkstyle, activer le et choisir les conventions d’ecriture pour Eclipse,
voir figure 3.12.
– Faite OK, le systeme vous avertira de la recompilation du projet.
– Ensuite regarder vos sources dans votre editeur vous devez voir, a gauche, des loupes bleues comme
cela .
57
– En cliquant dessus vous obtenez les informations a corriger et eventuellement (comme habituelle-
ment avec l’editeur) des options de correction automatiques qu’il suffit de choisir et de valider.
3.10.3 Quelques corrections classiques
La premiere utilisation est une peu deroutante car l’outil propose beaucoup de corrections d’un seul
coup. Par ailleurs certaines de ces corrections ne sont pas toujours faciles a comprendre, faites les plus
simples dans un premier temps.
– Checkstyle va vous obliger a ecrire vos commentaires javadoc et ceci dans un style regulier, par
contre vous devez entrez les informations a la main.
– Il manque souvent des blancs et autres petites decorations, un peu lourd mais une fois l’habitude
prise ca va mieux.
– Utilisation des constantes : il faut les rendre symboliques, en general en faire une information
statique d’une classe ou une enumeration.
– Absence des accesseurs pour un attributs.
– Methode mal-ecrite et donc pas concue pour etre heritee (qualificatif final).
Un autre outil est PMD, http://pmd.sourceforge.net/, qui analyse votre code a la recherche de
defauts. Par exemple des parties vides dans try/catch/finally/switch, du code mort (variables inuti-
lisees), utilisation abusive des String et StringBuffer, expression compliquees comme des if inutiles, et
duplication de code.
3.11 Environnement de developpement
Un environnement de developpement est un ensemble d’outils pour aider au developpement logiciel.
Nous venons de voir qu’Eclipse constitue un bon exemple d’un tel environnement. Eclipse est ecrit en Java
et pour des developpements en Java principalement, mais il supporte maintenant bien d’autres langages.
Il integre de nombreux outils et est extensible. Il est possible d’ajouter de nouveaux modules, le plus
simple est d’utiliser le software update dans le menu window.
3.11.1 Environnement pour UML
Il existe de tres nombreux outils pour aider a l’edition des diagrammes UML. Il existe egalement
des plugins pour Eclipse comme omondo. Nous allons prendre l’exemple d’ArgoUML : http://argouml.
tigris.org/. Il permet :
– Edition des diagrammes
– Generation de code
– Retro-conception
– Free pour Java !
3.12 ArgoUML
Cet outil n’est pas le meilleur mais il est gratuit, open source, facile a installer sur toutes les plates-
formes et supporte Java 1.5, generation de code et retro-conception. C’est pourquoi je conseille de l’utiliser
meme si il n’est pas parfait. Il n’est pas integre a Eclipse, contrairement a d’autres.
Il faut que vous soyez conscient que l’outil est un moyen imparfait et que vous devrez
forcement investir toute votre vie dans des outils. Donc apres l’installation il faut se faire
58
la main sur des exemples plus ou moins simples pour comprendre l’ergonomie (qui n’est
jamais parfaite). Si vous faites une phase d’apprentissage vous eviterez des deboires et aussi de dire a
l’enseignant “cet outil est plein de bugs”, ce qu’il sait deja.
Pour installer ArgoUML il suffit d’aller voir http://argouml-downloads.tigris.org/. Il s’agit d’une
application ecrite en Java et disponible sous forme d’une applet. L’interet est qu’il supporte Java 1.5,
outre les diagrammes UML il permet de faire de la generation de code et de la retro-conception. Par
ailleurs il dispose de pas mal d’autres possibilites que nous ne verrons pas. Evidemment un tel outil va
demander quelques manipulations qui au debut seront surement un peu laborieuses.
1. Telecharger une installation binaire correspondant a votre type de systeme d’exploitation (Windows,
Linux, Mac),
– ou utiliser l’application Java Web Start,
– ou voir sous campus dans l’espace GLCB2 OUTILS il y a des archives recentes.
2. Creer un repertoire et decompresser l’archive.
3. Lancer java -jar argouml.jar ou double cliquer sur l’icone argouml.
L’utilisation de l’application Java Web Start ne provoquera pas d’installation locale et executera la
derniere version. Si vous etes comme moi qui ne sais rien de ce truc, allez lire http://java.com/fr/
download/faq/java_webstart.xml.
3.13 Quelques remarques sur ArgoUML
La figure 3.14 donne une vue generale avec des commentaires. Vous allez travailler sur un seul dia-
gramme a la fois qui se trouve dans le panneau principal. Le panneau du haut contient les outils generaux,
notamment ceux permettant de creer des diagrammes de classes ou de sequences. Le panneau de gauche
contient la liste de tous les elements de votre projet et vous pouvez eventuellement, grace au menu
contextuel, y attacher d’autres diagrammes. Le panneau en bas decrit l’element courant et permet de le
renseigner completement.
ArgoUML est un modeleur UML base sur la notation 1.3 donc inutile de chercher certaines particula-
rites de la notation 2.0. En particulier vous n’avez pas les notations pour les compositions de diagrammes
de sequences ni de diagramme de composants.
Attention pour bien maıtriser un outil il faut experimenter sur des cas plus ou moins simple pour se
faire la main.
“On ne devient pas artiste peintre en lisant la page pinceaux d’un catalogue de bricolage !”
– Cet outil open source est tres pratique mais aussi a une ergonomie un peu inhabituelle.
– Il ne connaıt pas le couper-coller et ceci est bien embetant. Toutefois vous devez sauver regulierement
votre projet et vous pouvez utiliser revert to save dans le menu file.
– Bien qu’il ne connaisse pas le couper-coller vous pouvez referencer des elements existants dans
plusieurs diagrammes. Par exemple si une classe apparaıt dans plusieurs diagrammes de classes :
1. Vous la creez dans le premier diagramme, peu importe lequel.
2. Ensuite dans le second diagramme vous la faites glisser depuis l’explorateur a gauche (ou vous
utilisez add to diagram du menu contextuel).
Vous observerez egalement que dans les menus contextuels vous disposez de deux fonctions de
suppression
59
– remove from model qui supprime dans le modele et donc dans tous les diagrammes. Attention
ceci va entraıner egalement des suppressions d’elements qui seront devenus inconsistants suite a
cette suppression.
– remove from diagram qui supprime uniquement l’element du diagramme courant.
– Eviter d’utiliser des accents ou caractere autres qu’alphanumeriques dans les noms de classes (car
lors de la generation de code plein d’embetements).
– Pour ameliorer la lisibilite vous pouvez utiliser certaines fonctions permettant d’ordonner vos
elements (avant, arriere, alignement, etc), voir le menu Arrange.
Quelques trucs utiles :
Diagramme des classes : vous avez acces a la creation par le menu contextuel dans l’explorateur ou
par le menu general Create ou l’icone de la barre d’outils .
– En general utiliser le panneau du bas pour fournir les informations plutot que par la fenetre
graphique qui vous donnera l’impression que ca marche mais est souvent erronnee.
– Dans la specification des operations utiliser le menu type pour les arguments ou le type de retour.
– Preciser les navigations et les cardinalites des associations vous permettra d’avoir un modele
precis et dont le code genere sera plus facile a comprendre.
Generation de code : choisir votre diagramme de classes (ou alors vous pouvez generer toutes les
classes du projet) et utiliser le menu Generation.
Diagramme de sequences : il y a plusieurs icones pour la creation des messages (envoi, destruction,
creation). Noter que la creation ne suit pas la notation UML mais est representee par un envoi avec
un carre noir sur l’extremite de la fleche.
Image graphique : dans le menu file utiliser l’option exporter les graphiques.
Au debut suite a de mauvaises manipulations vous allez surement planter votre application. Donc
sauvegarder regulerement et si une situation anormale se produit alors ne pas hesiter a relancer l’appli-
cation. Une autre remarque generale est qu’avant de sauver ou de faire une generation de code faites le
menage dans votre modele. Comparer le vue hierarchique de gauche avec la vue graphique et verifier la
presence de tous les elements du modele. Si des elements sont en trop les supprimer.
3.13.1 Aspects avances
– Pas de frontiere du systeme dans les cas d’utilisation mais on peut utiliser le rectangle ou un autre
moyen decoratif.
– new Realization est une association pour : “Realization. Add a realization between a class and an
interface selected using button 1 motion (from the realizing class to the realized interface).” selon
la doc.
– Dans un MSC comment nommer les objets id:Classe ?
60
Figure 3.7 – Javadoc pour Nim
61
Figure 3.8 – La Javadoc sous Eclipse
Figure 3.9 – Un breakpoint
62
Figure 3.10 – La perspective debug
63
Figure 3.11 – Installer checkstyle
64
Figure 3.12 – La configuration du checkstyle
65
Figure 3.13 – Une vue d’ArgoUML
66
Figure 3.14 – La vue commentee d’ArgoUML
67
Annexe A
Annexes
A.1 Regles et consignes de bon sens
Cette section decrit quelques regles elementaires et de bon sens pour ameliorer votre code et votre
pratique.
Le processus de developpement et codage fortement conseille est le suivant :
1. Analyser votre probleme et penser a une architecture, generalement l’utilisation de patrons est
utiles.
2. Utiliser un outil pour concevoir votre architecture, generalement vous avez au moins un diagramme
de classes avec des relations.
3. Utiliser ce meme outil pour generer automatiquement un squelette de vos classes, ensuite tester la
construction de vos entites (new Classe(...)) et une representation externe textuelle (toString).
4. Verifier que chacune de vos classes est operationnelle, c’est a dire qu’elle represente bien ce que vous
voulez et permez de construire correctement les objets voulus. Pour cela la definition d’une methode
toString() et une serie de tests vous permettrons d’avoir une certaine certitude la-dessus. Si vous
ne parvenez pas a franchir correctement cette etape inutile d’aller plus loin.
5. Reflechissez et analysez votre hierarchie de classes. Normalement vous avez une ou des racines qui
contiennent souvent des methodes abstraites et parfois quelques methodes concretes. Les feuilles de
votre hierarchie doivent etre concretes et toutes les methodes des feuilles sont concretes. Les classes
intermediaires de la hierarchie sont souvent abstraites. Vous pouvez aussi ajouter des interfaces
pour representer des types importants dans votre systeme et pour mieux separer l’implementation
de l’utilisation.
6. Organiser le developpement des fonctionnalites : les plus simples d’abord. Pour chaque fonctionna-
lites la definir sur toutes les classes puis la tester.
Au niveau des corrections dans un code :
– Penser a faire des sauvegardes regulieres de votre code (utilisez la gestion de version) surtout si
vous avez atteint un etat qui semble satisfaisant d’un point de vue qualite interne et fonctionnel.
– Lors des corrections toujours proceder par petites unites et s’assurer que vous connaissez et maıtrisez
les repercutions dans le reste du code.
68
– Pour modifier ou corriger un code : decrivez les modifications a faire, evaluer l’impact (sur papier ou
en commentaires dans le code) des corrections dans tout votre code, faire une sauvegarde, realiser
les corrections, compiler et tester.
– Vous pouvez etre amene a restructurer votre code et ceci est assez delicat.
A.2 Quelques regles
Pour les regles de programmation et de presentation de votre code voici quelques elements. Mais
certaines sont integrees dans checkstyle et donc l’utilisation de cet outil est tres interessant.
Les regles dures :
– Ne truffer pas votre code de litteraux (12, “Toto”, etc) mais definir des constantes (static final).
– Les attributs sont prives par defaut et definir des accesseurs en lecture et/ou ecriture suivant les
besoins.
– Eviter les grosses classes ou les grosses methodes, votre code doit etre structure en unite de taille
raisonnable.
– Une procedure avec beaucoup de parametres (+ de 5) ou une classe avec beaucoup d’attributs n’est
pas une bonne pratique : restructurer !
– Utiliser les bons types (par exemple 0/1 pour des booleens !).
– Essayer de rendre vos expressions lisibles (booleennes ou d’acces aux elements d’un tableau) en les
decoupant si besoin.
– Identifier les repetitions de code et en faire des methodes auxiliaires.
– Utiliser les indicateurs final et static ...
– Il est sain de faire de temps en temps des revues de son code, qu’il fonctionne ou non, lire (sur
support papier) son code est utile. En effet vous n’allez pas etre tenter de l’executer et donc reflechir
au pourquoi des choses et de la deceler des erreurs ou des simplifications. Cette activite doit etre
faite regulierement sur tout ou partie de votre code meme si celui-ci semble fonctionner tres bien.
Les regles de documentation, de commentaires et d’indentation sont importantes a appliquer pour
assurer la lisibilite et la perennite de votre code.
Il existe egalement quelques regles “pointues” de presentation, par exemple mettre des blancs autour
des operateurs ... Clairement beaucoup moins essentielles.
Les outils du genre “style checker” sont tres precieux pour vous aider a appliquer ces regles.
69
A.3 Code Java du DigitCode
// -----------------
// JAVA/DIGICODE/Main.java
// 8/6/2006
// main digicode
// -----------------
//
public class Main
{
// le digit code
static private DigitCode code;
static private Boolean pasFini = true;
// main
public static void main(String [] args)
{
code = new DigitCode ();
// boucle de test
while (pasFini) {
System.out.println(" taper la suite des char (A/B/C/D) ");
String str = Clavier.lireString ();
if (str.length () == 3) {
code.decoder(str);
// System.out.println (" etat obtenu : " + code. getCurrentState (). getLabel ());
System.out.println(" etat obtenu : " + code.getCurrentState (). status ());
}
else {
System.out.println(" Je veux une chaine de 3 ! ");
// peut -mieux faire
} // end of else
System.out.println(" autre essai (o/n) ? ");
char r = Clavier.lireChar ();
pasFini = !(r==’n’);
} // end of while (pasFini)
}
} // fin Main
// ----------------------------
// JAVA/DIGICODE/DigitCode .java
// 8/6/2006
// --------------------------------
public class DigitCode{
// les etats 0 est l’initial
protected State [] states;
// l’etat courant
protected State currentState;
public State getCurrentState () { return currentState ;}
// constructeur
public DigitCode () {
// les etats
states = new State [5];
states [0] = new State0 ();
states [1] = new State1 ();
states [2] = new State2 ();
states [3] = new State3 ();
states [4] = new State4 ();
}
// decodage de la chaine
70
// plusieurs facons de representer les transitions
State decoder(String str) {
// etat initial
currentState = states [0];
for (int i = 0; i < 3 ; i++) {
currentState = currentState.handle(str.charAt(i));
} ;
return currentState;
}
} // fin DigitCode
// ----------------------------
// JAVA/DIGICODE/State.java
// 8/6/2006
// --------------------------------
public abstract class State{
protected String label;
// avec nommage explicite
public String getLabel () { return label ;}
//ex de nommage implicite
public String status () {
String s = getClass (). getName ();
return s.substring(s.lastIndexOf(’.’) + 1);
}
// retourne l’etat target en fonction de la cle
// public abstract State handle(char k);
public State handle(char k) {
return new State4 ();
}
} // fin
// ----------------------------
// JAVA/DIGICODE/State0.java
// 8/6/2006
// --------------------------------
public class State0 extends State{
public State0 () {
label = "0";
}
// retourne l’etat target en fonction de la cle
public State handle(char k) {
if (k==’A’) {
return new State1 ();
} // end of if (k==’A ’)
else {
return super.handle(k);
} // end of else
}
} // fin
// ----------------------------
// JAVA/DIGICODE/State1.java
// 8/6/2006
// --------------------------------
public class State1 extends State{
71
public State1 () {
label = "1";
}
// retourne l’etat target en fonction de la cle
public State handle(char k) {
if (k==’B’) {
return new State2 ();
} // end of if (k==’A ’)
else {
return super.handle(k);
} // end of else
}
} // fin
// ----------------------------
// JAVA/DIGICODE/State2.java
// 6/6/2006
// --------------------------------
public class State2 extends State{
public State2 () {
label = "2";
}
// retourne l’etat target en fonction de la cle
public State handle(char k) {
if (k==’C’) {
return new State3 ();
} // end of if (k==’A ’)
else {
return super.handle(k);
} // end of else
}
} // fin Key
// ----------------------------
// JAVA/DIGICODE/State3.java
// 8/6/2006
// --------------------------------
public class State3 extends State{
public State3 () {
label = "3OK";
}
// retourne l’etat target en fonction de la cle
// en principe pas appele
// public State handle(char k) {return new State3 () ;}
} // fin
// ----------------------------
// JAVA/DIGICODE/State4.java
// 6/6/2006
// --------------------------------
public class State4 extends State{
public State4 () {
label = "notOK";
}
72
// retourne l’etat target en fonction de la cle
// public State handle(char k) inutile
} // fin
73
Annexe B
Trucs pour depanner
B.1 Sauvegarde ASCII impossible car le texte contient des ac-
cents
Vous pouvez aussi avoir le probleme suivant sous Eclipse : sauvegarde ASCII impossible car le texte
contient des accents.
Figure B.1 – Probleme de jeu de caracteres sous Eclipse
La solution est d’utiliser UTF-8 partout dans votre espace de travail : Windows > Preferences >
General > Workspace > Text file encoding. C’est la valeur par defaut utilisee pour tout les fichiers
texte du workspace, mais cela peut etre modifie au cas par cas pour chaque projet (clic droit sur le projet
> Properties > section "Info").
B.2 Il manque un caractere NewLine a la fin du programme
Il s’agit d’un erreur qui apparaıt apres l’installation de checkstyle sous Windows. Voici la manipu-
lation pour enlever cette erreur. A noter qu’un caractere NewLine correspond a l’ajout d’une nouvelle
ligne.
– Aller dans le repertoire suivant :
C:\Program Files\eclipse\plugins\com.atlassw.tools.eclipse.checkstyle 4.3.3
– Ouvrez avec le bloc note, le fichier sun checks eclipse.xml
– modifier la ligne : <module name="NewlineAtEndOfFile"> par
<module name="NewlineAtEndOfFile">
74
<property name="lineSeparator" value="lf"/>
</module>
– Sauver le fichier.
– Relancer Eclipse.
Normalement, l’erreur est partie.
B.3 Mise a jour d’un plugin
La solution la plus simple est d’utiliser la mise a jour fournie dans Help > Software Updates >
Find and Install. Pour charger un plugin la solution simple ne marche pas parfois pour des problemes
reseaux et peut-etre que vous avez besoin de parametrer le proxy. Les proxies a utiliser dans Eclipse
(fbi.emn.fr avec le port 3128) dans preference > update > network > proxy > http.
Sinon la solution par site local en telechargeant d’abord le paquet, evite quelques fois des problemes.
Une autre solution plus laborieuse : telecharger, decompresser le zip et repartir les documents features/-
plugins dans les memes repertoires de votre installation Eclipse puis redemarrer.
Il faut aussi jouer quelques fois avec les installation/des-installation Help > Software Updates >
Manage Configuration.
Noter que le processus a change avec la version Ganymede 3.4, nous y avons gagne en simplicite et
en fiabilite.
B.4 Utilisation du patron.jar
Sur campus vous avez dans OUTILS un fichier patron.jar. Ce fichier contient un projet organise d’une
facon assez standard, vous pouvez vous en servir comme point de depart pour vos projets. Il suffit de
l’importer comme un projet existant dans votre espace de travail, eventuellement renommer et completer
les sources.
B.5 Jar rete de poisson
Fabriquer un jar mais ne pas oublier les sources ... Pour verifier le contenu utiliser un extracteur
pour zip (winrar, winzip, 7zip, unzip) et regarder le contenu ... Vous pouvez utiliser une ligne de
commande comme jar -tvf ou certains editeurs comme emacs, xemacs. Au pire vous pouvez recreer
un nouveau projet a partir du jar.
75
Annexe C
Un petit dictionnaire du genie
logiciel
Ce document n’a pas la pretention d’etre complet, voir celui de Henri Habrias ou encore wikipedia.
Juste quelques mots que l’on me demande expressement d’expliquer.
Analyse : Il s’agit d’une phase importante de tout projet d’ingenierie. Elle consiste au tout debut du
projet a essayer de comprendre et de decrire, le plus rigoureusement et fidelement si possible le
probleme pose par le client.
Concatenation : Il s’agit d’une operation elementaire sur les chaınes de caracteres consistant a les
mettre bout a bout (du latin cum ”avec” et catena ”chaıne, liaison”).
Conception : Phase importante d’un projet dont le but est de trouver une solution au probleme pose.
Implementation : C’est la phase consistant a coder, programmer la solution dans un langage informa-
tique. Les puristes peuvent dire “mise en œuvre”.
Logique du premier ordre : ou logique des predicats est une logique extension de la logique booleenne,
autorisant l’emploi des predicats et des quantificateurs universel et existentiel (∀,∃). Voir le bon
article sur wikipedia.
Predicat : un predicat est une expression de type booleen portant sur des variables, par exemple x >=
3,14159.
Pre-post condition : il s’agit de deux conditions complementaires utilises pour formaliser des construc-
tions de programmes. Par exemples pour la fonction plusUn(int x) :
– La precondition peut-etre x >= 0.
– La post-condition peut-etre x = x’ + 1, signifiant la valeur de x apres l’operation est celle d’avant
plus un.
76
Index
Analyse, 76
analyse, 18
API, 39
architecture logicielle, 23
architectures logicielles, 6
associations, 29
Atelier de genie logiciel, 20
besoins du client, 17
cahier des charges, 16, 17
classe, 27, 28
composition, 29, 30
Concatenation, 76
Conception, 76
conception, 19
Correction, 14
Cycle de developpement, 15
cycle de vie, 8
debogage, 19
diagrammes de sequences, 30
Ergonomie, 14
Fiabilite, 14
genie logiciel, 6, 8, 11
gestion de projet, 8
heritage, 29
Implementation, 76
instance, 28
integration, 19
interface, 25
Interoperabilite, 15
Logique du premier ordre, 76
Maintenabilite, 14
maintenance, 20
package, 26
patron etat, 36
patron composite, 34
patron de conception, 32
patron observateur, 38
patron singleton, 33
patron visiteur, 39
Performance, 14
Portabilite, 14
Pre-post condition, 76
Predicat, 76
qualites, 14
Reutilisation, 14
revue de code, 20
Robustesse, 14
specification, 18
specifications fonctionnelles, 17
tests, 19
UML, 7, 9, 18, 25–32, 35–37, 39, 58
Verifiabilite, 14
77
Bibliographie
[1] David Flanagan. Java in a Nutshell. O’Reilly & Associates, 2nd edition, 1997.
[2] Henri Habrias. Dictionnaire encyclopedique du genie logiciel. Masson, 1997.
[3] Kevin Lano, Jose Luiz Fiadeiro, and Luis Andrade. Software Design Using Java 2. Palgrave Macmil-
lan, 2002.
[4] Alfred Strohmeier and Didiers Buchs. Genie logiciel, principes, methodes et techniques. Presses
Polytechniques et Universitaires Romandes, 1996.
78