RNC-CNES-Q-80-527-F
Transcription
RNC-CNES-Q-80-527-F
REFERENTIEL NORMATIF du CNES Référence : Version 4 10 décembre 2005 RNC-CNES-Q-80-527 Méthode et Procédure REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA ACCORD du Bureau de BN n° 24 du 29/05/06 Normalisation APPROBATION Président du CDN Alain CUQUEL _______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 Page 3 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA Version 4 10 décembre 2005 PAGE D'ANALYSE DOCUMENTAIRE TITRE : MOTS CLES : REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA Java ; Applet ; Application ; Règle ; Recommandation. NORME EQUIVALENTE : Néant OBSERVATIONS : Néant RESUME : Ce document présente les règles et recommandations essentielles pour l’utilisation du langage Java. Il est applicable à la spécification, au développement et à la maintenance d’applications et d’applet Java. SITUATION DU DOCUMENT : Ce document fait partie de la collection des Méthodes et Procédures associées au Référentiel Normatif du CNES (ECSS et MPM). Il appartient à la filiation Assurance Produit des Logiciels. NOMBRE DE PAGES : 124 LANGUE : Française Progiciels utilisés / version : Word 2002 SERVICE GESTIONNAIRE : Inspection Générale Direction de la Fonction qualité (IGQ) AUTEUR(S) : DATE : 10/12/05 G. GUILLOT (DCT/AQ/SO) JEAN- CHARLES DAMERY (DCT/AQ/SO) RELECTURE / CONTROLE : M. RENARD P. ARBERET C. PELLIZZONI © CNES 2005 Reproduction strictement réservée à l'usage privé du copiste, non destinée à une utilisation collective (article 41-2 de la loi n°57-298 du 11 Mars 1957). _______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 Page 4 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA Version 4 10 décembre 2005 PAGES DES MODIFICATIONS VERSION DATE PAGES MODIFIEES OBSERVATIONS 0 22/09/97 Création du document Premier Draft élaboré par CAP GEMINI France (M-P. ETIENNE, O. LAGNEAU) PR.1 14/12/97 Toutes Version provisoire soumise à relecture PR.2 18/05/98 Toutes Intégration des remarques des relecteurs CNES PR.3 15/01/99 Toutes Reprise du document par VALTECH et introduction des remarques des relecteurs externes 1.0 03/03/99 Toutes Validation et normalisation du document 2.PR 11/11/99 Toutes Harmonisation avec la MPM “ Démarche de développement objet pour les logiciels ” 2.0 13/03/00 Toutes Changement de codification du RNC 3 01/12/00 Toutes Reprise du document par CRIL INGENIERIE et prise en compte de la version 1.3 du JDK 4 10/12/05 Entêtes et références Modifications pour mise en conformité avec l’évolution du document RNC-ECSS-E-40-1-0 « Software – Part1 : Principles and requirements », et mise en conformité avec RNC-CNES-Q80-529 « Démarche de développement objet pour les logiciels ». Accord du BN n°24 du 29/05/06 (FEB n° 42/2006). _______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 5 Version 4 10 décembre 2005 SOMMAIRE METHODE ET PROCEDURE .......................................................................................... 1 PAGE D'ANALYSE DOCUMENTAIRE......................................................................... 3 PAGES DES MODIFICATIONS .................................................................................... 4 SOMMAIRE................................................................................................................... 5 1. INTRODUCTION ................................................................................................. 7 2. OBJET................................................................................................................. 7 2.1. Les deux types d’utilisation de Java ........................................................................................7 2.2. Applet et application standalone..............................................................................................7 3. DOMAINE D'APPLICATION ............................................................................... 8 4. DOCUMENTS DE REFERENCE......................................................................... 9 4.1. Documents normatifs ................................................................................................................9 4.2. Bibliographie..............................................................................................................................9 5. DOCUMENTS APPLICABLES ........................................................................... 9 6. GLOSSAIRE - TERMINOLOGIE......................................................................... 9 7. PRESENTATION DES REGLES....................................................................... 13 7.1. Rubriques .................................................................................................................................13 7.2. Codification des règles ............................................................................................................14 8. REGLES APPLICABLES EN PHASE DE SPECIFICATION ............................ 15 9. REGLES APPLICABLES EN PHASE DE CONCEPTION................................ 16 9.1. Abstraction de données ...........................................................................................................16 9.2. Interfaces et implémentation (mot clé implements) .............................................................18 10. REGLES APPLICABLES EN PHASE DE REALISATION ............................... 20 10.1. Classes...................................................................................................................................20 10.2. Constructeurs, destructeurs ...............................................................................................28 _______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 6 Version 4 10 décembre 2005 10.3. Gestion de la mémoire et ramasse-miettes ........................................................................31 10.4. Maintenance.........................................................................................................................32 10.5. Méthodes ..............................................................................................................................34 10.6. Attributs, variables, constantes ..........................................................................................37 10.7. Structures de contrôle .........................................................................................................41 10.8. Gestion des exceptions.........................................................................................................45 10.9. Gestion des threads .............................................................................................................49 10.10. JavaBeans.............................................................................................................................53 10.11. Applets..................................................................................................................................55 10.12. Portabilité.............................................................................................................................60 10.13. Sécurité .................................................................................................................................76 10.14. Optimisation.........................................................................................................................80 11. UTILISATION DES LIBRAIRIES JAVA ............................................................ 95 12. INTERFACE AVEC L’EXTERIEUR................................................................... 98 12.1. Interface entre Java et des programmes externes ............................................................98 12.2. Accès à l’environnement .....................................................................................................99 13. ORGANISATION DU CODE ........................................................................... 100 14. DOCUMENTATION ET COMMENTAIRES ..................................................... 101 15. CONVENTIONS DE NOMMAGE .................................................................... 106 15.1. Généralités .........................................................................................................................106 15.2. Règles de nommage ...........................................................................................................106 15.3. Documentation...................................................................................................................110 16. INDEX DES REGLES...................................................................................... 112 16.1. Index des règles par ordre alphabétique .........................................................................112 16.2. Index des règles applicables aux applets .........................................................................116 16.3. Index des règles applicables aux applications standalone .............................................120 _______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 7 Version 4 10 décembre 2005 1. INTRODUCTION Le langage Java est un langage de programmation, défini par Sun Microsystems, orienté objet et indépendant de la plate-forme matérielle et système. Le document “ Règles et recommandations pour l’utilisation du langage Java ” fait partie de la collection des Méthodes et Procédures associées au Référentiel Normatif du CNES. Il appartient à la filiation Assurance Qualité des Logiciels (DR1). En fonction du type d’application Java développée, certaines Méthodes et Procédures doivent être utilisées en complément, notamment en ce qui concerne la mise en œuvre de la méthode de développement et la prise en compte des contraintes de sécurité. 2. OBJET Le but de ce document MPM est de participer à la réutilisation du savoir-faire en établissant des règles d’utilisation du langage Java, afin de concentrer l'effort de réalisation sur l'application et sur le contenu. Ce document est indispensable pour toute utilisation du langage Java dans un projet du CNES. Ce document MPM énonce des règles et des recommandations applicables aux phases de spécification, de conception et de réalisation d’une application écrite en langage Java. Ces règles et ces recommandations doivent être suffisamment précises pour être utilisables et efficaces, sans toutefois être trop restrictives, ce qui serait un obstacle à leur utilisation dans des contextes techniques qui peuvent être très différents les uns des autres. 2.1. LES DEUX TYPES D’UTILISATION DE JAVA On peut attirer l'attention du lecteur sur les deux grandes catégories d'applications Java ; la distinction explicitée ci-dessous a des incidences sur le volume de l'application, les contraintes de sécurité et de portabilité, ainsi que sur les compétences nécessaires aux développeurs. 2.2. APPLET ET APPLICATION STANDALONE Le langage Java doit sa popularité croissante à ses applications dans les techniques associées à Internet. Il permet en effet d'animer des applications clientes interactives sur le Web, le code de l'application étant téléchargé depuis un serveur lui-même connecté au Web, puis exécuté sur le client par la machine virtuelle Java. Cette assimilation de Java à une technologie dédiée au Web tend à masquer le fait que ce langage est un langage orienté objet à part entière, plus simple et plus robuste que C++, portable, fourni avec de nombreuses bibliothèques réutilisables dont la définition fait partie du langage, et accompagné de puissants outils de documentation. Lorsqu’une application Java est activée depuis une page HTML chargée par un navigateur comme Netscape, elle est appelée une applet ; dans ce cas le code Java correspondant est téléchargé du serveur où il réside vers le poste client au moment de l’appel de la page ; puis ce code est interprété sur le client par l’interpréteur Java, avec des contrôles poussés et des droits réduits afin d’empêcher le code importé de corrompre l’environnement local. D’autre part, une application Java peut être lancée comme une application standalone (ou autonome) en invoquant directement l’interpréteur Java sur la machine cible. L’application n’est pas alors soumise aux règles de sécurité qui restreignent l’accès des applets aux ressources système. Dans ce qui suit, les règles sont, sauf mention contraire, applicables à la fois aux applets et aux ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 8 Version 4 10 décembre 2005 applications standalones. 3. DOMAINE D'APPLICATION Ce document est destiné à plusieurs types de lecteurs : • le chef de projet qui doit spécifier correctement l’application Java à développer, • le chef de projet et/ou l’ingénieur qualité qui doit valider les règles relatives à la réalisation, extraire les recommandations pertinentes pour son projet et éventuellement adapter et compléter les règles en fonction du contexte de réalisation, • les personnes chargées de la réalisation du projet : elles doivent appliquer les règles et les recommandations retenues pour chaque étape du cycle de vie du logiciel. Ce document n'est ni un cours ni un manuel de référence Java. Il s'adresse à des lecteurs qui, sans être experts, ont une bonne connaissance du langage et des bibliothèques de classes associées. Les règles et recommandations définies ici visent à faciliter pour chaque projet la mise en œuvre des techniques Java ; elles forment un ensemble de principes de base qui permettent de capitaliser l'expérience acquise sur les projets en évitant d'engager systématiquement une réflexion approfondie sur des sujets consensuels. Cependant de nombreuses règles laissent aux utilisateurs un certain degré de liberté quant à leur application. Chaque projet devra donc compléter les règles de cette MPM de façon à les adapter à la taille et à la nature de l'application, ainsi qu'aux contraintes associées au contexte d'utilisation de la technologie. Le développement d’une applet Java est la plupart du temps considéré comme une partie du développement d’un serveur Web qui doit respecter les règles énoncées dans le document DR3 (Règles et recommandations pour la réalisation d’un serveur WEB). ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA Page 9 Version 4 10 décembre 2005 4. DOCUMENTS DE REFERENCE 4.1. DOCUMENTS NORMATIFS (DR1) : Assurance Produit des Logiciels - RNC-ECSS-Q-80 (DR2) : Règles et recommandations pour l’utilisation du formalisme UML – RNC-CNES-E-40-509 (DR3) : Règles et recommandations pour la réalisation d’un serveur WEB RNC-CNES-E-40-505 4.2. BIBLIOGRAPHIE (DR4) : Programmation Java (J-F Macary, C. Nicolas - Eyrolles) (DR5) : Java in a Nutshell (David Flanagan - O’Reilly & Associates, Inc.) (DR6) : Livre d’Or Java (Patrick Longuet - Sybex) (DR7) : Thinking in Java (Bruce Eckel - Prentice Hall) (DR8) : Practical Java (Peter Haggar - Addison-Wesley) (DR9) : http://java.sun.com (DR10) : http://www.ibm.com/developer/java (DR11) : http://gamelan.earthweb.com 5. DOCUMENTS APPLICABLES (DA1) : Démarche de développement objet pour les logiciels - RNC-CNES-E-40-508 6. GLOSSAIRE - TERMINOLOGIE Les termes utilisés dans ce document et relatifs au développement orienté objet sont définis dans le document DA1. API Application Programming Interface : interface de programmation pour le développement d’une application (attributs et méthodes accessibles). Applet / Appliquette Composant applicatif téléchargeable, qui est inclus dans une page HTML et qui s’exécute au sein d’un navigateur Web intégrant une machine virtuelle Java. De tels composants peuvent par exemple être des composants de l'interface utilisateur ou bien des composants pouvant communiquer avec d'autres applications distantes. Les applets sont écrits en Java. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA Bean RNC-CNES-Q-80-527 Page 10 Version 4 10 décembre 2005 Les JavaBeans permettent de créer des composants logiciels réutilisables qui peuvent être assemblés en utilisant un outil visuel d’assemblage. Ils sont basés sur une spécification permettant leur découverte automatique (capacité d’introspection) et leur interopérabilité. final : attribut finalisé On ne peut pas modifier la valeur de cet attribut. C’est ainsi que l’on définit les constantes en Java. final : classe finalisée Une classe final est une classe dont on ne peut pas hériter. final : méthode finalisée Une méthode final est une méthode qui ne peut pas être redéfinie dans une sous-classe. finalize Nom de la méthode appelée à la libération d'un objet, à l'appel de la méthode System.runFinalization() et éventuellement à la terminaison d’une application Java. Cette méthode peut être redéfinie. HTML HyperText Markup Language. Langage de balisage dérivé de SGML, utilisé pour formater les documents publiés sur le Web. HTML repose sur l'utilisation de balises (“ tags ”) de formatage permettant également l'inclusion de liens hypertextes et d'éléments externes tels que des images et des documents multimédias. HTTP HyperText Transfer Protocol. Protocole de communication utilisé pour transporter des documents hypertextes et d'autres documents, entre un serveur et un navigateur Web. IDE Integrated Development Environment. développement complet (exemple : JBuilder). IIOP Internet Inter-ORB Protocol. Protocole de communication développé par l'OMG (Object Management Group) pour l’interopérabilité d’applications au travers du standard CORBA. Internet Le réseau Internet est un ensemble mondial de réseaux interconnectés reposant sur le protocole de communication TCP/IP. Ce réseau maillé, relativement tolérant aux pannes, permet le routage dynamique des informations. Environnement de Le terme Internet est aussi fréquemment utilisé pour désigner les technologies reposant sur TCP/IP, telles que le Web, le courrier électronique, les groupes de discussion,... Java Plugin Composant développé par Sun Microsystems, installable dans un navigateur Web et permettant de disposer d’une nouvelle version de machine virtuelle Java. Son utilisation permet de régler les problèmes de compatibilité entre les différentes versions de machines virtuelles fournies avec les navigateurs Web. Le Java Plugin peut être installé dans les navigateurs Netscape et Microsoft à partir de leur version 3.0. Il est disponible pour toutes les versions du JDK à partir de la 1.1.4. JDK Java Development Kit. Environnement fourni par Sun Microsystems permettant le développement d’applications Java. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 11 Version 4 10 décembre 2005 JNI Java Native Interface. Voir native. JVM Java Virtual Machine. Interpréteur de programme Java, compilé dans du byte-code, généralement stocké dans un fichier .class. Lae principe de la JVM permet de concevoir des applications par essence portables. Machine virtuelle Voir JVM. native Une méthode native est une méthode Java dont l’implémentation est faite dans un autre langage (C, C++,…), au travers d’une API normalisée basée sur C appelée JNI depuis le JDK 1.1. Navigateur Web Application utilisée pour localiser et afficher des pages Web et permettant la navigation de page en page en suivant les liens hypertextes. package Unité d’organisation des programmes Java, dont la structure de nommage est hiérarchique. Les packages permettent de gérer les visibilités des noms et les unités de compilation. Ramasse-miettes Mécanisme chargé de détecter les objets qui ne sont plus utilisés par le programme et de libérer la mémoire correspondante. Le ramasse-miettes (garbage collector) est activé dans un thread de bas niveau de type démon. Script (JavaScript et VBScript) Portions exécutables d'un fichier HTML, à la différence des balises qui commandent la présentation des informations. Ces portions utilisent un langage interprété par le navigateur. JavaScript est d'origine Netscape, tandis que VBScript est d'origine Microsoft. SandBox (Bac à sable) Architecture permettant d’enfermer le code Java (utilisé en particulier dans les navigateurs Web). La SandBox isole un programme Java des ressources de la machine sur laquelle il s’exécute et des ressources réseau. Serveur Web Ordinateur ou application faisant office de serveur et proposant des services Web. Le rôle principal d'un serveur Web est de renvoyer des pages Web en réponse aux requêtes HTTP des navigateurs Web. Un serveur Web est le contenant d’un site Web. Les règles et recommandations pour un serveur Web appartiennent au domaine du génie logiciel. standalone Qualifie une application autonome pouvant fonctionner indépendamment, en particulier sans navigateur Web ou appletviewer (contrairement aux applets). SSL Protocole au-dessus du protocole IP qui fournit authentification, cryptage et intégrité. (Secured Socket Layer définit par Netscape). Sérialisation La sérialisation est un mécanisme offert par Java depuis le JDK 1.1 permettant de transformer un objet (ou plutôt un graphe d’objet) en un flux d’octets représentant son état. Ce mécanisme peut être utilisé pour gérer la persistance des objets, le passage d’objets sur le réseau, … super Mot clé permettant d'accéder à l'objet courant en tant que représentant de la classe de niveau supérieur dans l'arbre d'héritage (classe “ mère ”). ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA synchronized RNC-CNES-Q-80-527 Page 12 Version 4 10 décembre 2005 Le mot clé synchronized permet de définir des portions de code ou des méthodes comme étant non accessibles simultanément par deux threads sur un même objet ou une même classe (dans le cas de méthodes static synchronized). Ce mécanisme s’appuie sur la manipulation d’un moniteur disponible pour chaque objet ou classe Java. Lorsqu'un thread exécute un bloc synchronized sur un objet, il est impossible à un autre thread d'exécuter une méthode synchronized (la même ou une autre) sur le même objet. transient Le mot clé transient permet de définir un attribut dans une classe comme non pris en compte par le mécanisme de sérialisation par défaut de Java. URL Uniform Resource Locator. Adresse d'un document, d'un élément inclus ou de toute autre ressource sur le Web. L'URL est formée de plusieurs parties, précisant notamment le protocole utilisé, l'adresse du serveur et la référence de l'élément sur ce serveur (par exemple, http://www.company.com/index.html). volatile Le mot clé volatile permet d’identifier les attributs dans une classe qui peuvent être modifiés de manière asynchrone (i.e. par un autre thread pouvant ou non s’exécuter sur un autre processeur) pour lesquels le compilateur ne devra pas effectuer d’optimisation, pour éviter des problèmes d’incohérence lors de l’utilisation de machines multiprocesseurs, ou dans le cas d’optimisation faite par le compilateur dans un contexte multi-thread (recopie dans la pile locale d’un thread d’une valeur d’attribut par exemple). World Wide Web / Web / WWW Le World Wide Web est un réseau global de services HTTP, FTP, GOPHER, WAIS, faisant partie du réseau Internet. Le World Wide Web est composé principalement de serveurs HTTP d'informations hypertextes accédés par des clients, les navigateurs Web. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 13 Version 4 10 décembre 2005 7. PRESENTATION DES REGLES 7.1. RUBRIQUES Pour chaque règle, la description fait apparaître les rubriques suivantes : la référence de la règle, l'énoncé de la règle, consistant en une ou deux phrases synthétiques, le degré d'applicabilité de la règle dans les contextes suivants : • application activée depuis un navigateur (applet ou appliquette) • application directement activée depuis l'interpréteur Java (application standalone) Dans chacun de ces contextes la règle peut être : • une exigence ; dans ce cas la mention Exigé figure pour ce contexte. Les exigences sont imposées par l'application de ce standard. • une recommandation ; dans ce cas la mention Recom. figure pour ce contexte. Il est conseillé de suivre les recommandations de ce standard. • sans objet ; dans ce cas est portée la mention Sans Objet. la description de la règle (si nécessaire), pour préciser l’énoncé de la règle et les différentes circonstances d’application de la règle, la justification de la règle (si nécessaire), pour rappeler l’objectif poursuivi et évaluer les avantages et inconvénients de la règle ainsi que des possibilités alternatives qui n’ont pas été retenues, un ou plusieurs exemple(s) (si nécessaire), pour illustrer les applications de la règle, sans que cela constitue une manière obligatoire d’appliquer la règle. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 14 Version 4 10 décembre 2005 7.2. CODIFICATION DES REGLES La codification utilisée pour référencer les règles est la suivante : <DOMAINE>-<Règle> avec : <DOMAINE> est un terme suffisamment explicite indiquant le domaine d'application de la règle APPLET BEANS CLASSE CONCEP CONSTR CONTR DESTR DOC EXCEP FORMA : : : : : : : : : : MAINT MEM METH NOM OPTIM ORGANI PORTAB : : : : : : : SECUR SPECS STYLE THREAD VARLOC : : : : : Règles concernant les applets Règles concernant les JavaBeans Règles concernant la gestion des classes Règles concernant la conception orientée objet Règles concernant les constructeurs Règles concernant les instructions de contrôle Règles concernant le destructeur Règles concernant la documentation du code Règles concernant la levée et le traitement des erreurs Règles concernant la formation des personnes impliquées dans le développement du programme Java Règles concernant la maintenance Règles concernant la gestion de la mémoire et le ramasse-miettes Règles concernant les méthodes Règles concernant le nommage Règles concernant l’optimisation Règles concernant l’organisation du code Règles concernant la portabilité vis à vis du système d’exploitation et de la version du JDK Règles à adopter pour améliorer la sécurité Règles concernant la phase de spécification du programme Java Règles concernant le style de codage Règles concernant le multi-thread Règles concernant les variables locales <Règle> est un terme suffisamment explicite qui référence la règle dans son domaine. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 15 Version 4 10 décembre 2005 8. REGLES APPLICABLES EN PHASE DE SPECIFICATION SPECS-Version Il faut s’assurer que la version des navigateurs utilisés supporte le JDK utilisé. Applet : Exigé Standalone : Sans Objet Description Une applet Java est interprétée par l’interpréteur Java intégré dans le navigateur. Cet interpréteur doit être compatible avec le JDK utilisé (Java Development Kit). Le navigateur peut-être compatible de façon native ou le devenir par l’ajout d’un Plugin permettant d’utiliser une version spécifique du JDK. Justification Une applet ne peut fonctionner que si le navigateur est compatible avec la version du JDK utilisée ! L’utilisation du Java Plugin permet de garantir la version de machine virtuelle utilisée. Exemple Netscape Navigator 3.0 et Internet Explorer 3.0 ne supportent pas le JDK 1.1.4. Toutes les versions de Netscape Navigator 4.05 ne supportent pas le JDK 1.1.4. Netscape Navigator 4.5 supporte le JDK 1.1.5. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 16 Version 4 10 décembre 2005 9. REGLES APPLICABLES EN PHASE DE CONCEPTION 9.1. ABSTRACTION DE DONNEES CONCEP-IntInstance Une classe de base dont on veut interdire l’instanciation doit être définie comme une classe abstraite. Applet : Exigé Standalone : Exigé Description Une classe abstraite en Java est une classe qui ne peut pas être instanciée car elle a été déclarée abstract. Une classe peut être déclarée abstract sans posséder de méthode abstraite. Par contre, toute classe possédant au moins une méthode abstract devra être déclarée abstract. De plus, toute classe héritant d’une classe abstraite contenant une ou plusieurs méthodes abstraites devra-t-elle aussi être déclarée abstraite si cette sous-classe ne donne pas une implémentation à chacune des méthodes abstraites de la super-classe. Justification Le compilateur empêche toute création d'instance à partir d'une classe abstraite. Exemple Supposons que l’on manipule différentes classes représentant des formes : Cercle, Rectangle, Triangle. Chacune de ces classes comporte deux méthodes permettant de trouver l’aire et la circonférence d’une instance. Pour pouvoir manipuler un tableau de ces formes et obtenir de façon indifférenciée leur aire, on définit une super-classe, Forme, dont héritent Cercle, Rectangle et Triangle, et qui définit la signature de la méthode getAire(). Cependant cette méthode ne peut être définie au niveau de la classe Forme qui ne représente en elle-même aucune forme : cette méthode est une méthode abstraite. Aucune instance de Forme ne peut être créée : cette classe est une classe abstraite. // Classe abstraite. public abstract class Forme { // Methode abstraite. public abstract double getAire(); } // Premiere classe derivee. public class Cercle extends Forme { private double rayon; private static final double PI = 3.141598; public Cercle() { rayon = 1.0; } public Cercle(double r) { rayon = r; } } // Calcul de l’aire d’un cercle. public double getAire() { return PI*rayon*rayon; } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 17 Version 4 10 décembre 2005 // Autre classe derivee. public class Rectangle extends Forme { private double largeur; private double hauteur; public Rectangle() { largeur = 0.0; hauteur = 0.0; } public Rectangle(double l, double h) { largeur = l; hauteur = h; } } // Calcul de l’aire d’un rectangle. public double getAire() { return largeur*hauteur; } CONCEP-InterfEstUn La notion d’interface doit implémenter une relation conceptuelle “ est un ” ou la relation conceptuelle “ est une implémentation de ”. Applet : Exigé Standalone : Exigé Description Une interface est un regroupement d’opérations définissant un comportement pour toute classe qui l'implémente. Cette notion d’interface se retrouve dans des systèmes comme CORBA ou DCOM. Une classe peut implémenter plusieurs interfaces, et une interface peut hériter de plusieurs autres interfaces. Lorsqu’une classe implémente une interface, elle doit donner une implémentation à toutes les méthodes de cette interface pour être instanciable (condition vérifiée par le compilateur). La notion d’interface correspond donc à une notion de conception par contrat. Exemple // // // // // Definition de l’interface d’un vehicule Seule la signature des methodes est donnée On pourrait prefixer les methodes du mot-cle abstract mais ce n’est pas necessaire, les methodes des interfaces étant par definition abstraites. interface Vehicule { boolean demarrerMoteur(); void arreterMoteur(); float accelerer(float acc); boolean tourner(Direction dir); } // Definition de la classe Automobile qui definit toutes // les methodes de l’interface : elle implemente l’interface. class Automobile implements Vehicule { ... boolean demarrerMoteur() { if (pasTropFroid) { moteurDemarre = true; } ... } void arreterMoteur() { moteurDemarre = false; } float accelerer(float acc) { ... } boolean tourner(Direction dir) { ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA } } ... RNC-CNES-Q-80-527 Page 18 Version 4 10 décembre 2005 ... // Definition d’une autre classe qui // la classe Camion. Les methodes de // de façon tout a fait independante // Automobile. class Camion implements Vehicule { ... boolean demarrerMoteur() { ... } void arreterMoteur() { ... } float accelerer(float acc) { ... boolean tourner(Direction dir) { ... // Methodes specifiques. void releverBenne() { ... } } implemente l’interface : l’interface sont definies de leur implementation dans } ... } // Utilisation de ces classes. Automobile auto = new Automobile(); Camion camion = new Camion(); Vehicule vehicule; // auto implemente Vehicule et peut etre considere de ce type. vehicule = auto; vehicule.demarrerMoteur(); vehicule.arreterMoteur(); ... // camion implemente Vehicule et peut etre considere de ce type. vehicule = camion; vehicule.demarrerMoteur(); vehicule.arreterMoteur(); 9.2. INTERFACES ET IMPLEMENTATION (MOT CLE IMPLEMENTS) CONCEP-Interface La notion d’interface Java doit être utilisée à bon escient Applet : Exigé Standalone : Exigé Description Il ne faut pas abuser des interfaces. Justification Les interfaces permettent d’établir des relations transversales dans les arbres d’héritage de l’application. Ces “ râteaux ” sont pratiques et souvent nécessaires, par exemple pour mettre en œuvre des “ callbacks ” ou pour accéder à des données applicatives dans le code d’une IHM. Ils portent cependant atteinte à la pureté de la conception objet de l’application. Une classe peut implémenter plusieurs interfaces. Le code peut rapidement devenir difficile à comprendre et à maintenir si on abuse de cette possibilité. Exemple L’utilisation d’une interface est particulièrement intéressante pour définir un “ service ” commun à plusieurs objets de conception différente. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 19 Version 4 10 décembre 2005 Considérons par exemple deux classes : une classe Affichage faisant partie d’une IHM et permettant d’afficher du texte, et une classe Source générant le texte à afficher. Source est un fournisseur de texte ; cette classe pourrait stocker une référence à un objet de type Affichage, mais cela empêcherait Source d’envoyer du texte à un objet d’un autre type (par exemple à une Imprimante) ; il faudrait alors avoir une sous-classe de Source pour chaque type de destinataire pour pouvoir les gérer. Une solution plus élégante consiste à définir une interface utilisable par Affichage et par toute autre classe manipulant du texte, et à stocker une référence à cette interface dans Source. L’interface se nomme TexteModifiable et est implémentée dans la classe Affichage (et dans d’autres classes comme Imprimante). Un objet de type Affichage peut alors être utilisé partout où l’on a besoin d’un TexteModifiable. // Definition de l’interface. interface TexteModifiable { recevoirTexte(String texte); } // Implementation de l’interface. class Affichage implements TexteModifiable { ... public recevoirTexte(String texte) { scrollText(texte); } ... } // Utilisation de l’interface. class Source { TexteModifiable destinataire; Source(TexteModifiable dest) { destinataire = dest; } } private envoyerTexte(String texte) { destinataire.recevoirTexte(texte); } ... Du point de vue fonctionnel, la seule chose qui importe pour la classe Source est d’avoir accès à une méthode pour envoyer du texte. L’objectif de l’interface est ici de garantir que tout type d’objet l’implémentant fournira cette méthode (recevoirTexte). ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 20 Version 4 10 décembre 2005 10. REGLES APPLICABLES EN PHASE DE REALISATION 10.1. CLASSES CLASSE-MéthAbstr Il faut préférer les méthodes abstraites aux méthodes de corps vide. Applet : Exigé Standalone : Exigé Description Une méthode pour laquelle on ne peut pas définir d’implémentation valide doit être déclarée abstraite plutôt que d’être définie avec un corps vide (renvoyant une valeur par défaut). A noter que certaines méthodes peuvent avoir de façon légitime un corps vide lorsque leur sémantique est “ ne rien faire ” (par exemple, une rotation d’un cercle autour de son centre). Justification Il vaut mieux définir la méthode comme abstraite car cela impose de réfléchir à nouveau à sa mise en œuvre lors de la définition d’une classe dérivée. Exemple incorrect Dans l’exemple de la règle CONCEP-IntInstance, si on ne définit pas de classe abstraite Forme mais une classe de base avec une méthode vide on a : // Classe de base. public class Forme { // Methode vide. public double getAire() { return 0.0; } } // Forme derivee. public class Cercle extends Forme { ... // Surcharge de la methode getAire. public double getAire() { return PI*rayon*rayon; } } // Autre Forme derivee. public class Rectangle extends Forme { ... // La methode getAire n’est pas redefinie // celle de la classe Forme s’applique ! } On peut instancier Forme (contraire à la règle CONCEP-IntInstance) et décrire une classe dérivée qui oublie de définir une méthode getAire() correcte. Exemple correct Dans certains cas, il peut être nécessaire de définir des méthodes vides. Dans l’exemple suivant, la classe Cercle qui hérite de la classe Figure doit fournir une implémentation de la méthode rotation() (puisque cette méthode est déclarée dans Figure). Cette méthode possède légitimement un corps vide. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 21 Version 4 10 décembre 2005 // Classe de base. public class Figure { ... public abstract void rotation(double angle); ... } // Classe dérivée. public class Cercle extends Figure { ... // Methode vide. public void rotation(double angle) {} } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA CLASSE-ProtégerDon RNC-CNES-Q-80-527 Page 22 Version 4 10 décembre 2005 Il ne faut pas déclarer des données membres public, sauf pour définir des constantes (public final static). Applet : Exigé Standalone : Exigé Description Les données membres font partie de la représentation interne de la classe : elles ne doivent donc pas figurer dans la partie publique. Elles devront si besoin être accédées par l’intermédiaire de méthodes de la classe. La partie publique d'une classe ne doit comprendre que des fonctions qui fournissent le service offert par la classe. Elle peut comprendre notamment des fonctions d'accès en lecture aux données membres et des fonctions de modification des données membres. Néanmoins : • Les attributs constants peuvent être public final static (si l’accès direct à ces informations est nécessaire à l’extérieur de la classe). On peut cependant aussi les déclarer private et définir pour chacun d’eux une méthode d’accès en lecture de façon à rendre homogène l’accès aux attributs. • Un attribut peut exceptionnellement être protected s’il doit être lu ou modifié dans les sous-classes de la classe dans laquelle il est défini (et que l’accès direct à cet attribut est justifié). Une méthode spécifique de lecture ou d'écriture pourra dans la majorité des cas être créée (avec une portée protected). Justification L'intérêt de définir une classe comme une abstraction de données est multiple : • L’implémentation de la classe peut être modifiée sans conséquence sur les classes utilisatrices qui ne dépendent que du service offert. • Les références à une donnée membre sont homogènes dans tout le code utilisateur puisque la notation fonctionnelle doit être nécessairement utilisée. • L’accès à une donnée membre peut être contrôlé ce qui permet : 1. Sur la mise à jour d’un attribut, de vérifier que les invariants devant être respectés par la classe ne sont pas violés. La cohérence des données de la classe peut être assurée. 2. De faciliter la mise au point et la maintenance (on peut par exemple tracer toutes les mises à jour d’une donnée via sa fonction d’accès en écriture). Remarquons que la définition de données membres dans la partie protégée n'est pas interdite. Les classes dérivées ont la possibilité d'accéder directement aux données protégées. Cela peut être justifié par les relations très fortes entre une classe de base et ses sous-classes. Exemple incorrect public class Cercle extends Forme { public double rayon; public Cercle() { rayon = 1.0; } public Cercle(double r) { rayon = r; } // Calcul de l’aire d’un cercle. public double getAire() { ... } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA } RNC-CNES-Q-80-527 Page 23 Version 4 10 décembre 2005 // Dessin du cercle. public void dessiner() { ... } // Utilisation de la classe Cercle. Cercle cercle = new Cercle(5.0); cercle.dessiner(); // Affichage du cercle de rayon 5. cercle.rayon = 6; // Modification du rayon stocke. // L’aire affichee ci-dessous est incoherente avec l’objet dessine. System.out.println(cercle.getAire()); Exemple correct public class Cercle extends Forme { private double rayon; public Cercle() { rayon = 1.0; } public Cercle(double r) { rayon = r; } // Accesseurs aux attributs. public double getRayon() { return rayon; } public void setRayon(double r) { rayon = r; // Cette fois-ci on redessine le cercle si la largeur // est modifiee. dessiner(); } // Calcul de l’aire d’un cercle. public double getAire() { ... } } // Dessin du cercle. public void dessiner() { ... } // Utilisation de la classe Cercle. Cercle cercle = new Cercle(5.0); cercle.dessiner(); // Affichage d’un cercle de rayon 5. cercle.setRayon(6.0); // Modification de la largeur et dessin. // L’aire affichee ci-dessous est coherente avec l’objet dessine. System.out.println(cercle.getAire()); ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA CLASSEMembreStatic RNC-CNES-Q-80-527 Page 24 Version 4 10 décembre 2005 Il est recommandé de ne pas abuser des classes ou interfaces membres statiques. Applet : Recom. Standalone : Recom. Description Java permet de définir une classe à l’intérieur d’une autre classe et de lui associer le mot clé static ; il s’agit d’une classe interne statique (static inner class). De la même façon on peut définir une interface à l’intérieur d’une classe (static inner interface); le mot clé static est alors implicite. Les inner classes peuvent être définies comme static lorsqu’elles sont déclarées dans le corps de la classe imbriquante – c’est à dire ni dans une méthode ni imbriquée, comme le JDK le permet, dans une autre inner class –. Leur portée peut être précisée à l’aide des mots clés public, private, protected. Les classes ou interfaces internes statiques déclarées private peuvent être utilisées pour rendre plus lisible l’implémentation d’une classe complexe. Les classes internes statiques non private (i.e. public, “ visibilité package ” ou protected) doivent être utilisées avec plus de réserve. On pourra notamment les utiliser pour coder les énumérations en Java. Justification L’utilisation de classes internes statiques déclarées private (comme celle des classes internes non statiques) permet de structurer le code d’implémentation d’une classe complexe, ce qui le rend plus lisible (voir CLASSE-Inner). L’intérêt des classes ou interfaces internes statiques déclarées non private est simplement de pouvoir regrouper des classes proches sémantiquement. Bien que la notion de package réponde déjà à ce besoin, il est parfois nécessaire d’avoir des rapprochements entre classes à un niveau plus bas que celui des packages. C’est notamment le cas pour la définition de constantes énumérées (voir exemple). Le cas des constantes énumérées mis à part, il faut veiller à limiter le plus possible l’utilisation de classes imbriquées non privées. En effet, le code source résultant est moins lisible car apparaît au niveau de la structure des classes une imbrication qui ne correspond à aucune imbrication des services ni à aucune coopération particulière entre la classe incluse et la classe imbriquante. Exemple incorrect // La classe ComportementSocial est une classe incluse // definie comme statique. class Animal { static public class ComportementSocial { ... } ... } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 25 Version 4 10 décembre 2005 La classe ComportementSocial se comporte exactement comme une classe de niveau supérieur et de nom Animal.ComportementSocial. On peut en créer une instance de la façon suivante : Animal.ComportementSocial meute = new Animal.ComportementSocial(); Il vaut mieux définir la classe ComportementSocial de façon indépendante. Exemple correct // La classe Frequence est une classe incluse definie comme statique // qui permet de definir une constante enumeree typee. class Journal { static public class Frequence { // Permet de limiter l’utilisation du constructeur. private Frequence() {} } ... public final static Frequence MENSUEL = new Frequence(); public final static Frequence TRIMESTRIEL = new Frequence(); } public Journal(Frequence frequence) { ... } La classe Frequence permet de définir une constante énumérée que l’on peut utiliser de la façon suivante : Journal j = new Journal(Journal.MENSUEL); CLASSE-Inner Il est recommandé de ne pas abuser des classes incluses non statiques. Applet : Recom. Standalone : Recom. Description Java permet de définir des classes à l’intérieur d’une autre classe, et même à l’intérieur de n’importe quel bloc de code. Ces classes sont appelées inner classes (classes incluses ou internes). Dans le cas où la classe incluse est définie au niveau des attributs de la classe imbriquante, on dit qu’il s’agit d’une classe membre (member class). Dans le cas où la classe incluse est définie dans un bloc de code on dit qu’il s’agit d’une classe locale (local class). Dans le cas où une classe membre n’est pas définie comme statique (voir règle CLASSEMembreStatic), l’imbrication de la classe membre dans la classe imbriquante signifie : • l'accès aux membres de la classe imbriquante par la classe membre ; • qu’à une instance d’une classe imbriquante correspond une instance de la classe membre. On peut même définir les classes membre et les classes locales de façon anonyme (anonymous inner classes). Il faut utiliser cette facilité à bon escient. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 26 Version 4 10 décembre 2005 Justification Les classes incluses permettent dans certains cas de rendre le code bien plus synthétique, et plus lisible, en permettant d’éviter la définition d’une classe externe si elle ne doit être utilisée qu’une seule fois ; les classes internes anonymes sont très utiles dans la gestion des événements graphiques du JDK. Cependant si la classe incluse est de taille importante on obtient l’effet inverse (code illisible) ; le fait que la classe hôte et la classe imbriquée peuvent réciproquement utiliser les services qu’elles définissent, suggère plutôt une coopération entre classes du même package. Exemple 1 (member class) // // // // La classe Cerveau est incluse dans la classe Animal. On fait l’hypothese que seuls les animaux possedent un Cerveau et que les services rendus par une instance de la classe Cerveau ne peuvent pas etre utilises en dehors du contexte de l’instance d’Animal qui possede ce Cerveau. // Tous les objets de type Cerveau sont crees dans une instance de la classe // Animal, le constructeur de Cerveau n’etant accessible que depuis Animal. Class Animal { Class Cerveau { ... } // Definition d’une methode accessible depuis Animal et Cerveau. void protegerTerritoire() { ... } } Exemple 2 (local class) // La classe Cerveau est incluse dans la methode protegerTerritoire // Il faut bien sur que le Cerveau ne serve qu’a proteger son // Territoire, sinon il va falloir redefinir le Cerveau ailleurs. Class Animal { void protegerTerritoire() { Class Cerveau { ... } } } Exemple 3 (anonymous inner class) L’exemple suivant montre la définition d’une classe interne anonyme à l’intérieur de la méthode getEnumeration(). La classe interne est définie en même temps que l’instance dans l’instruction return. Cette classe interne implémente l’interface Enumeration et à ce titre définit les méthodes abstraites hasMoreElement et nextElement. L’instance renvoyée est la seule instance existante de cette nouvelle classe non nommée ; le type de retour déclaré pour la méthode getEnumeration() est le type Enumeration qu’implémente la classe non nommée – on serait bien en peine de déclarer que la méthode renvoie une instance de la nouvelle classe car elle n’a pas de nom, mais cela n’empêche pas d’accéder aux services de cette nouvelle classe qui sont l’implémentation des méthodes abstraites de l’interface. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA Page 27 Version 4 10 décembre 2005 ... Enumeration getEnumeration() { } return new Enumeration() { int element = 0; boolean hasMoreElements() { return element < employees.length; } Object nextElement() { if (hasMoreElements()) { return employees[element++]; } else { throw new NoSuchElementException(); } } }; On remarque que ce code est peu lisible, ce qui est imputable à la taille de la classe incluse. Exemple 4 (anonymous inner class) L’exemple suivant est plus judicieux et montre l’utilisation des classes incluses dans la gestion des événements graphiques ; on note la concision du code. // La classe anonyme est une classe derivee de la classe MouseAdapter // et surcharge la methode mouseClicked en assignant a l’evenement // clic souris l’action pertinente – dans ce cas handleClicks. addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { handleClicks(e); } }); CLASSE-MembreVis Il est interdit de modifier la visibilité des classes membre. Applet : Exigé Standalone : Exigé Description La visibilité par défaut d’une classe membre est celle du paquetage. Java permet d’associer un indicateur de visibilité à la définition d’une classe membre (public, protected, private), ce qui suppose une modification de la visibilité par défaut de cette classe. Il ne faut pas modifier la visibilité par défaut des classes membre. Justification Donner une portée public à une classe incluse n’est pas naturel (pourquoi l’inclure ?). De plus les classes incluses déclarées comme protected sont en fait traitées par le JDK comme des classes de portée public ce qui rend particulièrement pernicieux l’utilisation de protected dans ce cas. Enfin les classes incluses déclarées comme private sont en fait traitées par le JDK comme des classes de la portée du paquetage : il faut là encore éviter cette ambiguïté. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA Page 28 Version 4 10 décembre 2005 10.2. CONSTRUCTEURS, DESTRUCTEURS CONSTR-But Il faut réserver les constructeurs aux tâches d’initialisation. Applet : Recom. Standalone : Recom. Justification Assigner aux constructeurs d'autres tâches que celles d'initialisation nuirait à la compréhension du programme et peut amener des pertes de performance : le constructeur est par définition la méthode appelée à la création de l'objet. CONSTR-Retour Il ne faut pas définir de “ constructeur ” avec une valeur de retour. Applet : Exigé Standalone : Exigé Description Java permet de définir une méthode de même nom que la classe et avec une valeur de retour ; mais attention : ce n'est alors pas un constructeur ! Justification C'est à éviter car cela peut conduire à des erreurs de programmation pendant le développement et à une mauvaise compréhension du code pendant la maintenance. Exemple Incorrect public class ClasseSansConstructeur { // Attributs. private static int compteur; // Methode de nom ClasseSansConstructeur. public int ClasseSansConstructeur(int increment){ compteur = compteur + increment; return compteur; } } // Autres methodes. ... ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA DESTR-Finalize RNC-CNES-Q-80-527 Page 29 Version 4 10 décembre 2005 Il est recommandé de ne pas redéfinir la méthode finalize(). Applet : Recom. Standalone : Recom. Description Le langage Java ne permet pas de définir de destructeur. C’est le système de ramasse-miettes qui permet de libérer la mémoire allouée pour les objets qui ne sont plus utilisés. Cependant certains objets utilisent d’autres ressources, qui ne sont pas traitées par le ramasse-miettes : descripteurs de fichiers, identifiants de sockets, etc. On peut coder la libération de ces ressources dans la méthode finalize(), qui sera exécutée soit implicitement à la libération de l’objet, juste avant que le traitement ramasse-miettes ne soit effectué, soit par l’appel explicite à la méthode System.runFinalization(). Cependant la redéfinition de la méthode finalize() pour libérer des ressources est fortement déconseillée. Il vaut mieux gérer explicitement la libération des ressources en utilisant par exemple le bloc finally de la série try/catch/finally, pour être sûr que même en cas d’exception les ressources sont libérées. Justification Les libérations de ressources seront effectuées lors du prochain ramassage de miettes ; un seul ennui : on ne sait pas lorsque celui-ci aura lieu, on n’est même pas sûr qu’il y en aura un avant que l’interpréteur ne se termine. Cette incertitude rend le code non déterministe ! Exemple Prenons le cas où la ressource libérée dans la méthode finalize() est un descripteur de fichier. La méthode finalize() est appelée. Un peu plus loin dans le code on essaie de supprimer le répertoire contenant le fichier. C’est l’échec car le ramasse-miettes n’a pas été appelé entre-temps, le fichier n’est donc pas fermé, le répertoire ne peut pas être supprimé. DESTR-SuperFinalize En cas de redéfinition de la méthode finalize() on doit appeler super.finalize(). Applet : Exigé Standalone : Exigé Description Il n’y a pas de chaînage automatique des appels à la méthode finalize(), comme c’est le cas pour les constructeurs par défaut. Si on définit la méthode finalize(), il faut appeler explicitement celle de la super-classe à la fin de cette méthode. Justification Les traitements de terminaison de la classe de plus haut niveau, s’ils existent, doivent être appelés. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 30 Version 4 10 décembre 2005 Exemple // Destructeur de la classe FileOutputStream. // Ferme le stream quand le ramasse-miettes est invoque. // Verifie qu’il n’est pas deja ferme. protected void finalize() throws IOException { if (fd != null) { close(); } } // Classe MaClasseFichier. public class MaClasseFichier extends FileOutputStream { } protected void finalize() throws IOException { // Traitements specifiques a MaClasseFichier. ... // Appel au destructeur de la super classe. super.finalize(); } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 31 Version 4 10 décembre 2005 10.3. GESTION DE LA MEMOIRE ET RAMASSE-MIETTES MEM-TempsRéel Il ne faut pas utiliser Java pour les applications à forte contrainte temps réel. Applet : Sans Objet Standalone : Exigé Justification Même s’il est possible de désactiver le ramasse miettes qui risque de rendre l’exécution du code non déterministe au niveau de son temps de réponse, il est préférable d’utiliser des environnements Java spécifiques (comme par exemple implémentant la Real-Time Specification for Java) qui sortent du cadre de ce document. MEM-RazRéférence Il faut remettre à null les références aux objets volumineux comme les tableaux. Applet : Recom. Standalone : Recom. Description null représente en Java une référence non établie. Lorsqu’un objet de grande taille (par exemple, un tableau) n’est plus utilisé par une application, on peut permettre sa destruction en déréférençant l’objet. Ceci est réalisé en forçant toutes les références sur l'objet à null ou à tout autre objet). Justification Cela permet de libérer plus vite (au prochain lancement du ramasse miettes) des ressources mémoire qui ne servent plus. Exemple // Declaration d’un tableau de grande taille. int[] tableau = new int[100000]; // Utilisation de ce tableau. int resultat = calculsDivers(tableau); // On n’a plus besoin du tableau. Apres l’instruction suivante // comme le tableau n’est plus reference nulle part la // prochaine activation du ramasse miette liberera la memoire allouee. tableau = null; ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 32 Version 4 10 décembre 2005 10.4. MAINTENANCE MAINT-AffectMask Aucune affectation ne doit être masquée par une autre opération. Applet : Exigé Standalone : Exigé Description Il ne faut pas effectuer une affectation en même temps qu’un appel de fonction et au sein d’une condition ou d’une expression. Justification Le cumul d’opération sur une même ligne d’instruction nuit fortement à la lisibilité des programmes et risque de masquer des opérations. Exemple incorrect ... if (resultat = calculValeur(increment++)) { nbResultatsNonNuls++; } ... Exemple correct ... resultat = calculValeur(increment); increment++; if (resultat != 0) { nbResultatsNonNuls++; } ... MAINT-Debug Il est conseillé d’introduire dans les classes développées les méthodes main() et toString(). Applet : Recom. Standalone : Recom. Description main() contiendra le code des tests unitaires et toString() fournira un affichage pertinent de l’état d’un objet de cette classe. De plus, la méthode main() fournira à terme un exemple opérationnel d’utilisation de la classe. Justification Pour faciliter le test et le debuggage des classes. Notons qu’il est d’usage en Java de pouvoir, à l’aide de la méthode toString(), afficher sous forme de chaîne de caractère l’état (informations pertinentes issues des valeurs des membres) d’un objet (même si ce n’est pas la finalité de ce dernier). Le code de main() doit rester raisonnable ; il contiendra les tests unitaires surtout pour les classes de base de l’application et non des tests de niveau intégration pour les autres classes. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA Page 33 Version 4 10 décembre 2005 Exemple public class Cercle extends Forme { private double rayon; private static final double PI = 3.141598; public Cercle() { rayon = 1.0; } public Cercle(double r) { rayon = r; } // Calcul de l’aire d’un cercle. public double getAire() { return PI*rayon*rayon; } // Affichage de l’etat d’un objet cercle. public String toString() { return "Cercle de rayon : " + rayon; } // Exemple d’utilisation utilise pour la validation de la classe. public static void main(String[] args) { Cercle cercleRayon1 = new cercle(); Cercle cercleRayonPI = new cercle(PI); } } MAINT-Outil System.out.println(cercleRayon1); System.out.println("Aire = " + cercleRayon1.getAire()); System.out.println(cercleRayonPI); System.out.println("Aire = " + cercleRayonPI.getAire()); Il est fortement conseillé d’utiliser un outil de test du code. Applet : Recom. Standalone : Recom. Description Il existe en Java, des outils permettant de tester de manière automatique, le code des logiciels développés. Ces outils permettent de vérifier à la fois les règles de codage et la robustesse des méthodes. Ils doivent être utilisés tout au long du projet. Justification Un tel outil garanti le respect des règles de codage du projet et permet simplement d’éliminer un grand nombre d’erreurs potentielles. Pour permettre une bonne interprétation des résultats d’audit, l’outil choisi doit être utilisé régulièrement. Exemple • Le logiciel Jtest de la société ParaSoft : http://www.parasoft.com • Le logiciel Robot for Java de la société Rational : http://www.rational.com • Le logiciel JavaTest de la société Panorama : http://www.softwareautomation.com/ ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 34 Version 4 10 décembre 2005 10.5. METHODES METH-Public Une méthode ne doit être public que si elle doit être utilisée depuis au moins une classe définie dans un autre package. Applet : Exigé Standalone : Exigé Description La portée d’une méthode doit par défaut être la portée private. Dans une classe, on ne définira public une méthode que si elle est utilisée dans une autre classe non dérivée. Attention cependant à ne pas aller à l’encontre de la réutilisation. Une méthode ne doit pas être déclarée private si elle correspond à un service fourni par la classe (même si ce service n’est pas utilisé dans la version courante du projet). Justification Dans un souci de clarté, d’efficacité et de facilité de maintenance il faut limiter au maximum l’interface de programmation de chaque classe. METH-Protected Une méthode ne doit être protected que si elle doit être utilisée depuis au moins une méthode définie dans une autre classe de la sous-hiérarchie. Applet : Exigé Standalone : Exigé Description La portée d’une méthode doit par défaut être la portée private. Une méthode ne doit être protected que si elle est utilisée par une classe qui dérive de celle où elle est définie. Justification Voir règle METH-Public. METH-Redéfinie Les définitions d’une fonction membre redéfinie entre une classe de base et une classe dérivée doivent comporter les mêmes noms de paramètres. Applet : Exigé Standalone : Exigé Justification Cela assure une meilleure lisibilité des programmes. Exemple public class Voiture { // Methode permettant de dessiner une voiture. public void dessiner(String couleur) { // Dessiner la voiture } } public class Formule1 extends Voiture { ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 35 Version 4 10 décembre 2005 // Methode dessiner redefinie pour la classe Formule1. // Le parametre definissant la couleur porte le même nom // que dans la classe de base. public void dessiner(String couleur) { // Appel a la methode dessiner de la classe Voiture. super.dessiner(couleur); } } METH-Final Il faut préfixer du mot clé final les méthodes dont on veut interdire la redéfinition. Applet : Exigé Standalone : Exigé Description On peut vouloir interdire la redéfinition d’une méthode sur de nombreux critères : • elle est très utilisée, • elle a un fort niveau de complexité fonctionnelle et/ou algorithmique, • elle utilise des ressources critiques, • ses performances sont critiques, • elle n’a pas, sémantiquement, de raison d’être redéfinie. Associer le mot clé final à cette méthode en interdit la redéfinition. Justification La méthode redéfinie risque d’être de moindre utilité ou de moindre qualité que la méthode initiale ; il faut absolument éviter que les utilisateurs de classes dérivées n’utilisent la méthode redéfinie en pensant utiliser la méthode de la classe de base. Il vaut donc mieux créer une nouvelle méthode. METH-Surcharge Les différentes surcharges d’une fonction doivent offrir des services ayant la même sémantique. Applet : Exigé Standalone : Exigé Justification Il s’agit d’être cohérent avec la notion de service associé à une méthode. Exemple incorrect public class Voiture { // Definir la puissance de la voiture. public void definir(Cheval chevaux) { ... } // Definir la couleur de la voiture. public void definir(Couleur couleur) { ... } } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA Page 36 Version 4 10 décembre 2005 Les deux méthodes de l’exemple ci-dessus ne devraient pas porter le même nom car elle n’ont apparemment pas la même sémantique et sûrement pas les mêmes répercussions sur l’objet. Exemple correct public class Voiture { // Dessin a partir du nom de la couleur. public void dessiner(String couleur) { ... } // Dessin a partir du triplet RGB. public void dessiner(int rouge, int vert, int bleu) { ... } } METH-Retour Il ne faut pas utiliser le retour fonctionnel pour la gestion des erreurs. Applet : Exigé Standalone : Exigé Description Une valeur de retour ne doit être définie pour une méthode que lorsque la sémantique de cette méthode le justifie ; c'est par exemple le cas des méthodes d'accès aux attributs (get...() et is...()). Justification C'est le mécanisme des exceptions qui doit être utilisé pour gérer les erreurs. Il ne faut absolument pas mixer retour de fonction et retour de code d’erreur. Exemple incorrect // Methode de dessin d’un logo. public int dessinerLogo(String sponsor) { File image = new File(REPERTOIRE-LOGOS, sponsor + ".gif"); if (!image.exists()) { return -1; } else { // Affichage de l’image. } } Exemple correct // Methode de dessin d’un logo avec levee d’une exception si echec. public void dessinerLogo(String sponsor) throws PasDeLogoException { File image = new File(REPERTOIRE-LOGOS, sponsor + ".gif"); if (!image.exists()) { throw new pasDeLogoException(sponsor); } // Affichage de l’image. } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 37 Version 4 10 décembre 2005 10.6. ATTRIBUTS, VARIABLES, CONSTANTES CLASSE-This Il faut utiliser la référence this à l’objet courant avec parcimonie. Applet : Exigé Standalone : Exigé Description this doit être utilisé : • lorsque l’on souhaite passer une référence à l’objet courant à un autre objet, • lors de l’appel d’un constructeur depuis un autre constructeur de la même classe, • pour lever une ambiguïté de portée de variable ou de méthode. Il ne doit pas être utilisé pour l’appel de méthodes de l’objet courant. Justification Pour appeler une méthode de la classe courante la syntaxe habituelle est de ne pas préfixer le nom de la méthode par this afin de ne pas alourdir le code. Exemple class Enfant { private String nomEcole; private String prenom; private String nom; public Enfant(String prenom, String nom, String ecole) { // Appel de l’autre constructeur. this(prenom, nom); nomEcole = ecole; } public Enfant(String prenom, String nom) { // Le mot cle this permet de differencier le parametre de la methode // et l’attribut sans pour autant avoir a utiliser des noms de // parametres moins explicites. this.prenom = prenom; this.nom = nom; } } public void passerObjet() { // Le mot cle this est utilise pour passer une reference // a l’objet courant. fournirAcces(this); } VARLOC-Ligne Il faut dédier une ligne de code à chaque déclaration de variable locale. Applet : Exigé Standalone : Exigé Justification Chaque déclaration peut ainsi être commentée. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA Page 38 Version 4 10 décembre 2005 Exemple incorrect float vIni, vFin, vMoyenne; // Variables de calcul de la vitesse. Exemple correct float vIni; float vFin; float vMoyenne; VARLOC-Proximité // Vitesse en debut d’acceleration. // Vitesse en fin d’acceleration. // Vitesse moyenne. Il est recommandé d’utiliser des déclarations de proximité. Applet : Recom. Standalone : Recom. Description Les méthodes doivent généralement être suffisamment courtes et peu complexes pour que la plupart des déclarations de variables locales figurent en tête de fonction ; néanmoins dans le cas d’une fonction à structure plus complexe, on rapprochera la déclaration de certaines variables locales de leur utilisation par l’intermédiaire de déclarations de blocs. Justification Le code est ainsi plus lisible. Dans le cas de déclarations de blocs, le code est plus efficace car il n’y a pas d'allocation si cette portion de code n'est pas accédée. VARLOC-Utilisation Il faut réserver chaque variable locale à une utilisation unique. Applet : Exigé Standalone : Exigé Justification Le code est plus cohérent. Cela diminue le risque d'effets de bord dus à une initialisation antérieure de la variable. Exception Cette règle peut dans certains cas entraîner un surcoût en termes de ressources mémoire. VARLOC-Initialisation Il est recommandé d’initialiser les variables locales lors de leur déclaration. Applet : Recom. Standalone : Recom. Description Le compilateur Java impose d’initialiser les variables locales avant de les utiliser. Cette initialisation devrait être faite au moment de leur déclaration dans la mesure où l’on a les moyens d’initialiser la variable avec une valeur significative. Justification Le code est plus synthétique donc plus lisible. Voir aussi règle VARLOC-Proximité. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA MAINT-Const RNC-CNES-Q-80-527 Page 39 Version 4 10 décembre 2005 Il est recommandé d’utiliser des constantes pour représenter les nombres et les chaînes de caractères. Applet : Recom. Standalone : Recom. Description On évitera d’utiliser des nombres et des chaînes de caractères directement dans le code. On utilisera de préférence des constantes ou des variables convenablement nommées. Justification L’utilisation de constantes pour les nombres améliore la lisibilité et facilite la maintenance du code. La définition de constantes pour les chaînes de caractères a les mêmes avantages et peut faciliter la mise en œuvre d’une politique de traduction des applications. Exemple incorrect valeurIncrementee = valeur + 10; System.out.println("Le resultat du calcul est " + valeurIncrementee); Exemple correct static int INCREMENT = 10; static String RESULTAT = "Le resultat du calcul est "; ... valeurIncrementee = valeur + INCREMENT; System.out.println(RESULTAT + valeurIncrementee); STYLE-Tableau Il faut déclarer les tableaux de façon uniforme. Applet : Exigé Standalone : Exigé Description Il faut déclarer les tableaux en associant les crochets au type de la façon suivante : int[] tableau; plutôt que : int tableau[]; Il ne faut surtout pas mélanger les notations. Remarque : la notation Java (int[] tableau) améliore la lisibilité du code. Justification Le code est plus homogène donc plus lisible. Il est aussi plus satisfaisant de regrouper les indicateurs de type avant la variable : on note ainsi int[] le type tableau d’entiers. Exemple incorrect // rangee et colonne sont des tableaux d’octets. // matrice est un tableau de tableau d’octets. byte[] rangee, colonne, matrice[]; ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 40 Version 4 10 décembre 2005 // Cette methode prend en parametre un tableau d’octets et un // tableau de tableaux d’octets. public void exemple(byte[] colonne, byte[] matrice[]) { ... } Exemple correct byte[] rangee; byte[] colonne; byte[][] matrice; public void exemple(byte[] colonne, byte[][] matrice) { ... } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA Page 41 Version 4 10 décembre 2005 10.7. STRUCTURES DE CONTROLE CONTR-Break Tout branchement d’un choix multiple doit se terminer par l’instruction break. Applet : Exigé Standalone : Exigé Description Une instruction permettant de sortir de la structure switch doit être utilisée à la fin de chaque branchement (on utilisera généralement break et parfois return ou continue). Justification Un branchement à choix multiple ne doit normalement conduire qu’à l’exécution d’un seul bloc d’instruction. L’absence de break conduit en Java à l’exécution de toutes les instructions suivant l’entrée validée en pratique, cette absence résulte donc très majoritairement d’une erreur de codage. Exemple switch (choix) { case 1: traitement_1(); break; case 2: traitement_2(); traitement_3(); break; default: throw new Exception("traitement d’un choix non prévu"); } CONTR-Default Il faut prévoir le cas default dans un choix multiple switch. Applet : Exigé Standalone : Exigé Description Le cas AUTRES CAS (default) d'une instruction de choix multiple switch est obligatoire. Si aucun traitement n'est prévu, il faudra produire un message ou commentaire approprié. Justification Le traitement des autres cas d'une instruction de choix multiple permet de se prémunir contre les oublis et de traiter les cas par défaut. Cela facilite grandement la maintenance. Exemple Voir exemple de la règle CONTR-Break. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA CONTR-ConditionFor RNC-CNES-Q-80-527 Page 42 Version 4 10 décembre 2005 Il ne faut pas modifier la valeur de la condition de boucle for dans la boucle. Applet : Recom. Standalone : Recom. Description Le test de sortie de boucle for doit être une comparaison de la valeur du paramètre de boucle avec une valeur connue à l'entrée de la boucle et indépendante du traitement du corps de la boucle. Justification Si la valeur de sortie dépend du traitement du corps de la boucle il faut utiliser une structure de type while. Exemple // Incorrect. for (i = 0; i <= max; i++) { max = max - 1; } // Correct. for (i = 0; i <= max; i++) { valeur = i - 1; ... } CONTR-ParamFor Il ne faut pas modifier le paramètre de boucle for dans la boucle. Applet : Exigé Standalone : Exigé Description La valeur du paramètre de boucle ne doit pas être modifiée par le traitement du corps de la boucle. Justification La modification du paramètre de boucle conduit à modifier le nombre d'itérations prévu. Si le besoin existe, il faut utiliser une structure de type while. Exemple // Incorrect. for (i = 0; i <= max; i++) { i = i - 1; } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA STYLE-Blocs RNC-CNES-Q-80-527 Page 43 Version 4 10 décembre 2005 Tous les blocs d’une instruction de contrôle doivent être délimités par des accolades. Applet : Exigé Standalone : Exigé Description Pour délimiter les lignes de code liées aux instructions if, for, while et do, on utilisera systématiquement les accolades ouvrantes et fermantes. Cette règle doit être appliquée même si le bloc ne contient qu’une seule instruction. Justification Cette règle simplifie la maintenance du code en facilitant l’ajout d’opérations dans les instructions de contrôle, elle assure une meilleure lisibilité en uniformisant les syntaxes. Notons également que le fait d’ouvrir systématiquement une accolade après une instruction de contrôle prévient de l’apparition d’un point virgule parasite (bug particulièrement fréquent et délicat à détecter). Exemple incorrect for (noImage = 0; noImage < nombreImages; noImage++) for (noColonne = 0; noColonne < nombreColonnes; noColonne++) for (noLigne = 0; noLigne < nombreLignes; noLigne++) tableauImages[noImage].pixels[noColonne][noLigne] = noImage; Exemple correct for (noImage = 0; noImage < nombreImages; noImage++) { for (noColonne = 0; noColonne < nombreColonnes; noColonne++) { for (noLigne = 0; noLigne < nombreLignes; noLigne++) { tableauImages[noImage].pixels[noColonne][noLigne] = noImage; } } } // Une instruction peut etre ajoutee sans risque. for (noImage = 0; noImage < nombreImages; noImage++) { int valeurPixel = noImage + 1; for (noColonne = 0; noColonne < nombreColonnes; noColonne++) { for (noLigne = 0; noLigne < nombreLignes; noLigne++) { tableauImages[noImage].pixels[noColonne][noLigne] = valeurPixel; } } } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA CLASSE-InstanceOf RNC-CNES-Q-80-527 Page 44 Version 4 10 décembre 2005 Il est conseillé d’utiliser l’opérateur instanceOf avec parcimonie. Applet : Recom. Standalone : Recom. Description L’opérateur instanceOf peut être appliqué à tout objet. Il permet de tester si une instance est bien une instance de la classe qui est le deuxième opérande de instanceOf. Il peut être utilisé pour effectuer des traitements différents selon la classe ou la sous-classe d’un objet. Cependant, ce type d’aiguillage qui rappelle les instructions switch() sur un champ définissant le type en langage C doit être évité au maximum. Justification Cela peut nécessiter des modifications de code si l’arbre d’héritage est enrichi; supposons qu’on ait au départ une classe de base M et des classes dérivées F1, F2, F3 ; un objet de classe effective F1, F2 ou F3 peut être référencé comme un objet de classe M et dans un cas particulier testé grâce à l’opérateur instanceOf pour introduire des traitements spécifiques. Si on ajoute une classe F4 dérivée de la classe M, il faut ajouter du code pour traiter le cas F4 même si aucun traitement nouveau n’est à définir ; ce code est externe à la nouvelle classe ; ceci augmente de façon inutile le couplage entre les classes. Ceci peut être utilisé à la place du mécanisme de surcharge pour effectuer dans une classe de base des traitements différents suivant la sous-classe effective d’un objet donné. Dans ce cas cela relève d’une mauvaise compréhension des mécanismes d’héritage et de surcharge des méthodes : on ne tire pas parti de la puissance du langage orienté objet. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 45 Version 4 10 décembre 2005 10.8. GESTION DES EXCEPTIONS EXCEP-SousClasse Les exceptions du projet doivent être des sous-classes de la classe Exception. Applet : Exigé Standalone : Exigé Description Les trois classes de base prédéfinies pour les exceptions sont : • java.lang.Error Cette classe sert à décrire les problèmes d’édition de liens dynamique, les problèmes de la machine virtuelle comme le manque de mémoire, etc. • java.lang.RuntimeException Cette classe décrit des erreurs d’exécution susceptibles d’être générées par toute portion de code, comme ArrayOutOfBoundException. • java.lang.Exception Cette classe sert de base à toutes les autres descriptions d’erreur, en particulier pour les erreurs applicatives. Les classes qui servent à décrire les exceptions du projet doivent être dérivées de la classe java.lang.Exception. De plus, une documentation exhaustive des exceptions levées est indispensable. Justification Il est plus lisible de réserver les classes java.lang.Error et java.lang.RuntimeException aux erreurs “ système ”. Cela peut permettre de traiter de façon spécifique ces erreurs. Exemple // Definition d’une exception utilisee pour les // erreurs de saisie. public class SaisieException extends Exception { public void afficher(Frame f) { FenetreErreur fenetre = new FenetreErreur(f); fenetre.afficher(getMessage()); } } // Exemple de generation de l’exception // par la methode saisieValeur. public int saisieValeur() throws SaisieException { int saisie = 0; // Valeur saisie par l’operateur. ... if (saisie > 100) { throw new SaisieException("Saisir une valeur entre 1 et 100"); } return saisie; } // Exemple de traitement de l’exception. ... try { ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 46 Version 4 10 décembre 2005 int valeur = saisieValeur(); } catch (SaisieException e) { e.afficher(frame_courant); } EXCEP-Specifique Il ne faut pas manipuler directement les classes Exception et RunTimeException. Applet : Exigé Standalone : Exigé Description On ne doit jamais utiliser les instructions catch et throws avec les types de base Exception et RunTimeException. Ces types peuvent par contre être dérivés et utilisés dans le respect de la règle EXCEP-SousClasse. Justification Le fait de capter une exception de type Exception est beaucoup trop général et masque irrémédiablement la spécificité de toutes les classes dérivées. Il ne faut donc traiter que les classes dérivées et ne jamais présumer de l’existence d’exceptions étrangères au module algorithmique courant. Exemple incorrect // Utilisation de l’exception et de la methode de la regle // "EXCEP-SousClasse". try { int valeur = saisieValeur(); } catch (Exception e) { if (e instanceOf SaisieException) { (SaisieException)e.afficher(frameCourant); } else { System.err.println("Exception inconnue !"); System.exit(1); } } Exemple correct // Utilisation de l’exception et de la methode de la regle // "EXCEP-SousClasse". try { int valeur = saisieValeur(); } catch (SaisieException e) { e.afficher(frameCourant); } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA EXCEP-Error RNC-CNES-Q-80-527 Page 47 Version 4 10 décembre 2005 Il ne faut pas capter les exceptions de la classe Error. Applet : Recom. Standalone : Recom. Description Il faut laisser ces exceptions se propager jusqu’au plus haut niveau ; l’interpréteur Java imprime alors un message d’erreur sur la sortie standard et se termine. Justification Ces exceptions sont levées suite à des erreurs en général considérées comme irrattrapables. Exemples InternalError : erreur interne d’un (mauvais) interpréteur Java. NoSuchMethodError : appel d’une méthode qui n’existe pas dans la version chargée de la classe. EXCEP-RuntimeExcep Il est recommandé de ne pas explicitement propager les exceptions de la classe RuntimeException. Applet : Recom. Standalone : Recom. Description Il faut parfois traiter les RuntimeExceptions explicitement. Les exceptions de cette classe n’ont pas besoin d’être déclarées avec la méthode qui les génère pour se propager, éventuellement jusqu’au plus haut niveau, ce qui peut amener la machine virtuelle à les traiter elle-même. Le traitement par défaut de la machine virtuelle d’une exception de ce type est d’interrompre le thread qui l’a généré (par exemple, dans le cas d’une application mono-thread, l’application sera interrompue !). Les portions de code réellement susceptibles de renvoyer ce type d’exception devront être gérées par des blocs try/catch/finally. Justification Ces exceptions sont susceptibles d’être générées par n’importe quelle portion de code Java. Les traiter toutes explicitement alourdirait énormément le code. Par contre, pour certaines parties sensibles du code (qui manipulent les tableaux, les cast, les entrées-sorties,…, qui mettent en cause des interactions de l’utilisateur, ou qui font appel à des portions de code en cours d’écriture), il est judicieux de traiter ces exceptions. Exemple incorrect System.out.println(" Entrer une valeur numérique "); String s = br.readLine(); int i = Integer.parseInt(s); Exemple correct System.out.println(" Entrer une valeur entière "); try { String s = br.readLine(); int i = Integer.parseInt(s); ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 48 Version 4 10 décembre 2005 } catch(NumberFormatException e) { System.out.println(" Votre valeur n’est pas entière, désolé "); System.exit(0); } EXCEP-CatchUtil Une exception ne doit pas être récupérée par une fonction qui n’a pas les moyens de la traiter. Applet : Exigé Standalone : Exigé Justification Cela alourdit le code pour rien et le programmeur risque d’oublier de remonter l’exception au niveau au-dessus, où il est peut-être possible de la traiter. Exemple incorrect // methode1 peut envoyer l’exception MonException. void methode1() throws MonException { if (...) { throw new MonException(); } } // methode2 appelle methode1 mais ne sait pas traiter // MonException. void methode2() { try { methode1(); } catch (MonException e) { // Simple trace, pas de traitement de l’erreur. } } Exemple correct void methode1() throws MonException { if (...) { throw new MonException(); } } // On declare que methode2 peut renvoyer l’exception. void methode2() throws MonException { // Si methode1 leve l’exception MonException // elle est propagee a l’appelant de methode2. methode1(); } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA Page 49 Version 4 10 décembre 2005 10.9. GESTION DES THREADS THREAD-Encapsuler Il est recommandé d’encapsuler la création d’un thread. Applet : Recom. Standalone : Recom. Description On appellera la méthode start() à l’intérieur de la classe. Justification Un objet n’a ainsi pas à s’occuper de l’instanciation et la gestion des threads. Exemple incorrect // Implémentation de l’interface Runnable. class Affichage implements Runnable { ... public void run() { while (true) { // Dessiner. ... repaint(); } } } // Dans une autre classe, création de l’interface. Affichage dessin = new Affichage("Arbre de Noël"); // Création de l’objet Thread. Thread myThread = new Thread(dessin); // Activation du thread. myThread.start(); ... // pas d’encapsulation // pas d’encapsulation Exemple correct // Implémentation de l’interface Runnable. class Animation implements Runnable { // Attribut private utilisé pour stocker l’identifiant // du thread. private Thread myThread; } // Création de l’objet Thread et activation du thread. // Initialisations dans le constructeur. Animation(String name) { // On ne spécifie pas la portée // du constructeur. myThread = new Thread(this); // Création de l’objet Thread myThread.start(); // activation du thread. } ... // Création de l’animation. // De l’extérieur la façon dont l’objet Animation est mis en oeuvre // n’apparaît pas. Animation coucou = new Animation("Coucou"); ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA THREAD-Création RNC-CNES-Q-80-527 Page 50 Version 4 10 décembre 2005 Il est recommandé d’utiliser l’interface java.lang.Runnable pour créer un thread. Applet : Exigé Standalone : Exigé Description On préférera créer une implémentation de l’interface java.lang.Runnable plutôt que de créer une sous-classe de java.lang.Thread. Justification Dans l’acception purement objet de la dérivation de classes, créer une sous-classe de java.lang.Thread signifierait créer un nouveau type de Thread, ce qui n’est pas du tout ce que l’on fait lorsqu’on dit qu’une classe permet de créer un thread. De plus la méthode de création de threads utilisant les interfaces permet une meilleure conception orientée objet ; en effet Java ne permet pas l’héritage multiple mais permet l’implémentation d’interfaces multiple, donc implémenter l’interface Runnable, ce qui est du domaine de la mise en œuvre technique, n’a pas de conséquence sur le reste du design. La méthode run() a de toutes façons toutes les chances d’être sémantiquement très liée à l’une des classes de l’application ; choisir la mise en œuvre par implémentation d’interface permet à la méthode run() d’accéder à des membres privés ou protégés de cette classe. Exemple incorrect class Dessin extends Object { public void rafraichir() { ... } } class Animation extends Thread { // Animation ne peut pas dériver de Dessin. ... // Redéfinition de la méthode run(). public void run() { while (true) { // Dessin. ... repaint(); } } } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA THREAD-Daemon RNC-CNES-Q-80-527 Page 51 Version 4 10 décembre 2005 Les threads effectuant des traitements de fond doivent être définis comme des “ démons ”. Applet : Sans Objet Standalone : Exigé Description On appelle ici traitement de fond un traitement qui rend des services techniques de base qui ne correspondent pas à des spécifications fonctionnelles applicatives (l’interpréteur Java en fournit un exemple avec le ramasse-miettes). On indique qu’un thread est un “ démon ” en utilisant la méthode setDaemon(). Un thread “ démon ” est tué par Java lorsque les autres threads de l’application se terminent. Justification On n’a pas à se préoccuper de gérer la fin de ces threads ce qui simplifie le code. Les threads sont surtout utilisables pour les applications Java standalone, ainsi que pour le système Java lui-même (exemple du ramasse-miettes), mais pas pour les applets. Comme toute applet est créée à l’intérieur d’une autre application Java, les threads “ démons ” qu’elle est susceptible d’activer continueraient à vivre tant que l’application qui contrôle l’applet existe, ce qui n’est probablement pas l’effet désiré. Exemple // // // // Exemple ou la classe Demon derive de la classe Thread, ce qui enfreint la regle THREAD-Creation, mais simplifie l’exemple. Le demon est un thread dedie a la gestion des connexions de nouveaux clients sur un socket de connexion. class Demon extends Thread { Demon() { setDaemon(true); // Le thread est un "démon". start(); } public void run() { while (true) { // Attente de connexion sur un socket dedie. // Si connexion Alors // Creation d’un socket pour gerer le nouveau client // Activation d’un autre thread // pour gerer les entrees-sorties sur ce socket. // Finsi } // La tâche est désactivée par Java. } } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 Page 52 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA THREAD-SystemExit Il faut fermer les System.exit(). Applet : Exigé threads non “ démons ” Version 4 10 décembre 2005 avant d’appeler Standalone : Exigé Description La méthode System.exit() doit être appelée uniquement après avoir stoppé ou terminé les threads importants de l’application. Justification Cette méthode force l’interruption de tous les threads en cours de l’application, sans terminer ceux-ci de manière normale. Dans un cas d’erreur, l’utilisateur n’aurait donc aucune chance de rétablir la situation ou plus simplement de ne pas perdre son travail. Il faut donc toujours traiter le cas d’erreur en cours avant d’appeler cette méthode. Exemple On peut utiliser System.exit() si le cas d’erreur est irrécupérable et si on a tenté de la décrire clairement dans un message informant l’utilisateur. Cette méthode peut également être utilisée pour de petits programmes se comportant comme des commandes du système d’exploitation destinés à être utilisé dans des scripts de commandes. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA Page 53 Version 4 10 décembre 2005 10.10. JAVABEANS BEANS-Choix Il convient de choisir les composants que l’on désire transformer en JavaBeans. Applet : Recom. Standalone : Recom. Description Il faut définir des règles permettant de déterminer les composants susceptibles de devenir des JavaBeans. On pourra par exemple se poser les trois questions suivantes : • Le composant est-il prévu pour être réutilisé ? • Le composant doit-il être utilisé avec d’autres composants réutilisables ? • Vais-je utiliser un outil de développement IDE ? Justification Le développement de JavaBeans entraîne un surcoût et une surcharge du code (si aucun outil n’est utilisé) qu’il ne faut pas généraliser à tous les composants d’un projet. On prendra tout de même soin grâce à l’application des règles de nommage de faciliter la transformation ultérieure de tous les objets (Cf. NOM-AccèsAttribut). BEANS-Transient Toutes les données dont la sauvegarde n’est pas nécessaire doivent être déclarées transient. Applet : Exigé Standalone : Exigé Description La sérialisation Java permet aux objets implémentant l’interface Serializable d’être transformés en une séquence binaire pouvant être sauvegardée et restaurée de manière à conserver un objet dans son état courant. Les types de base Java ainsi que les classes du JDK sont Serializable. Dans le cadre des JavaBeans, la sérialisation est appliquée par défaut à toutes les données non statiques. Lors de la création de composants JavaBeans, on doit définir par défaut tous les éléments comme transient. Seuls les éléments à sauvegarder devront être sérialisables. On prêtera une attention particulière aux listeners des évènements générés par le composant en déclarant transient les vecteurs de listeners. La sérialisation d’un vecteur de listeners pourrait entraîner la sauvegarde de l’arborescence d’objets associés aux évènements d’un Bean de plus, la gestion des relations entre composants (et donc des listeners) ne doit être réalisée que par les composants de type containers. Justification La sérialisation automatique peut ainsi entraîner la sauvegarde de beaucoup d’informations superflues. Il convient donc d’identifier correctement les éléments strictement nécessaires à la restauration d’un Bean. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA BEANS-Notification RNC-CNES-Q-80-527 Page 54 Version 4 10 décembre 2005 Un composant JavaBean doit générer un événement lié à tout changement significatif de son aspect. Applet : Exigé Standalone : Exigé Description Les évènements générés par un Bean doivent prendre en compte deux points de vue : • ils doivent être adaptés à l’usage des auditeurs potentiels, • tous les changements significatifs doivent être notifiés. Justification Les composants “ encapsulant ” un Bean doivent pouvoir prendre en compte les modifications du Bean (notamment les changements d’aspect). Il faut toutefois faire très attention à ne pas créer des composants “ bruyants ” (générant trop d’évènements). Il faut donc éviter de regrouper toutes les modifications d’un composant dans un même événement (pour ne pas notifier inutilement tous les auditeurs et ainsi risquer de fortes baisses de performances). Exemple Si un composant représente une valeur numérique sous forme d’un champ de texte, d’un ascenseur et d’un graphique, il peut-être judicieux de ne générer qu’un seul événement lié à la modification de l’un des trois éléments. Par contre, si ces trois mêmes éléments graphiques représentent 3 valeurs différentes, on utilisera de préférence 3 évènements distincts (tout en prenant soin de vérifier que l’usage de ces évènements est bien lié à 3 types d’auditeurs distincts). ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 55 Version 4 10 décembre 2005 10.11. APPLETS APPLET-AppletAppli Il est recommandé de fournir les applets également sous forme d’application. Applet : Recom. Standalone : Sans Objet Description On doit fournir une méthode main dans toute applet de manière à pouvoir la faire fonctionner également comme application standalone. Justification Java permet de manipuler les applets en tant qu’application de façon aisée (voir exemple cidessous). Ceci permet alors un double fonctionnement des applets, en remarquant toutefois que l’inverse n’est pas vrai : toute application ne peut être transformée en applet, ne serait ce que pour des raisons de sécurité. On remarquera de plus que le déboguage des applications dans des outils IDE ou avec le JDK standard de Sun est plus facile qu’avec des applets, d’où l’intérêt de disposer en permanence d’une version “ applicative ” de l’applet. Enfin on disposera d’un meilleur contrôle du code en phase de développement. Ceci ne devra pas cependant faire oublier les règles élémentaires et indispensables de sécurité concernant les applets. L’intérêt de cette manière d’opérer dans le cas général est de pouvoir développer l’applet avec toute la liberté et la puissance de développement possible. Exemple import java.applet.*; import java.awt.*; public class StandaloneApplet extends Applet { public static void main(String args[]) { Applet applet = new StandaloneApplet(); Frame frame = new AppletFrame("myApplet", applet, 300, 300); } } class AppletFrame extends Frame { public AppletFrame(String title, Applet applet, int width, int height) { super(title); // Ajout du code spécifique à la fenêtre utilisateur. ... this.resize(width, height); this.show(); } // Démarrage de l’applet. applet.init(); applet.start(); On remarquera ici le découpage de la partie fabrication de fenêtre qui permet l’affichage de l’applet en tant qu’application (classe AppletFrame). Cette classe démarre l’applet comme le ferait un appletviewer avec bien moins de possibilité cependant (la classe AppletContext n’est pas prise en compte dans cet exemple et toute méthode afférente sera inutilisable). On pourra étendre cette manière de travailler en construisant une classe AppletViewer ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 56 Version 4 10 décembre 2005 personnalisée imposant seulement les contraintes de sécurité désirées pour les applications standalone. APPLET-StartStop On doit démarrer et arrêter les tâches de fond d’une applet dans les méthodes start() stop() respectivement. Applet : Exigé Standalone : Sans Objet Description Toute tâche de fond d’une applet (animation, activité permanente) doit être démarrée dans la méthode start() de l’applet et arrêtée dans la méthode stop() de l’applet. Attention cependant au comportement de ces méthodes dans certains navigateurs. Elles peuvent être déclenchées dans d’autres cas que lorsque le navigateur quitte/revient sur l’applet (cf. Netscape qui appelle ces méthodes lorsque la fenêtre du navigateur est retaillée). On prendra toutes les précautions nécessaires pour obtenir des fonctionnements similaires quel que soit le navigateur utilisé au niveau des méthodes start(), stop(), init(), … Remarque : des informations sur ce sujet peuvent être trouvées sur le site JavaWorld. Justification Les méthodes init et destroy d’une applet sont appelées à la création et à la destruction de l’applet par l’appletviewer ou le navigateur la visualisant. Toute tâche de fond qui est active pendant toute la durée de vie de l’applet doit commencer et finir dans ces deux méthodes Par contre, dans beaucoup de cas, on voudrait que ces tâches de fond (comme les animations par exemple) ne soient actives que quand l’applet est visible. Dans ce cas, pour diminuer la charge du processeur et pour une meilleure architecture, on démarrera ces activités uniquement dans les méthodes start et stop qui sont activées respectivement quand l’applet devient visible ou invisible à l’utilisateur. Exemple Dans le cas des applets fournissant une petite animation, on spécifiera que l’applet implémente l’interface Runnable et on démarrera dans la méthode start() de l’applet une instance de Thread pointant sur l’applet instanciée, grâce à l’appel Thread.start(). Ainsi la méthode run() de l’applet sera appelée par ce thread, découplant de ce fait la mécanique de fonctionnement des applets dans un navigateur des contrôles et calculs nécessaires à l’animation. On appellera la méthode Thread.stop() pour stopper ce thread d’animation dans la méthode stop() de l’applet. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA APPLET-Animation RNC-CNES-Q-80-527 Page 57 Version 4 10 décembre 2005 Il est recommandé d’utiliser des threads dédiés pour réaliser des animations dans des applets. Applet : Recom Standalone : Sans Objet Description Toute tâche de fond d’une applet (animation, activité permanente) doit être prise en charge par un thread dédié à cette activité. Justification C’est nécessaire pour éviter le blocage permanent de l’application sur la tâche de fond. Cela permet aussi de synchroniser le passage de données inter-applets au sein de leur navigateur ou appletviewer. Exemple public class Animation extends Applet implements Runnable { // Thread de support d’animation, avec redefinition // des methodes start et stop pour démarrer et arrêter. private Thread animatorThread = null; ... public void init() { // Instanciation et initialisation de l’applet. } public void start() { if (animatorThread == null) { animatorThread = new Thread(this); animatorThread.start(); } } public void stop() { if ((animatorThread != null) && animatorThread.isAlive()) { animatorThread.stop(); animatorThread = null; } } } // Lancement de l’animation. public void run() { while(true) { .... try { Thread.sleep(200); } catch (InterruptedException e) {; } } } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA APPLET-Debugging RNC-CNES-Q-80-527 Page 58 Version 4 10 décembre 2005 Il est recommandé de déboguer les fonctionnalités d’une applet dans un appletviewer plutôt que dans un navigateur. Applet : Recom. Standalone : Sans Objet Description En phase de développement ou d’évolution d’une applet, on s’efforcera de la faire fonctionner à l’aide d’un appletviewer plutôt que d’un navigateur. Justification Les appletviewers permettent de visualiser des applets contenus dans un fichier HTML, et seulement les applets. Lorsque plusieurs applets sont référencés dans le fichier, l’appletviewer ouvre une fenêtre d’applet pour chacune d’entre elles. Le développeur se préoccupe donc uniquement du bon fonctionnement de l’applet et pas des aspects ergonomiques de son insertion dans la page HTML. Les navigateurs affichent quant à eux tous les composants visualisables du fichier HTML. Ceci peut ralentir et perturber la productivité du développeur, d’autant qu’à chaque nouvelle version d’applet il faut redémarrer un nouveau navigateur. L’utilisation d’un appletviewer permet de tirer partie du relâchement des contraintes de sécurité imposées par les navigateurs, ce qui autorise l’utilisation de mécanismes de déboguage via jdb ou par lecture-écriture de fichiers sur la machine locale, ou le profiling., ou de spécifier des paramètres particuliers à l’interpréteur Java. On utilisera par contre régulièrement les navigateurs pour visualiser les applets en cours de développement, lorsque l’on voudra “ faire le point ” sur l’état courant de l’applet ou un test en vraie grandeur, lorsque l’on voudra tester ponctuellement les aspects sécurité, lorsque l’on sera en phase finale de développement. APPLET-TagName Il faut toujours renseigner le paramètre NAME de la balise APPLET des fichiers HTML contenant une applet Java. Applet : Exigé Standalone : Sans Objet Description Ce paramètre NAME désigne l’applet chargée par un nom. Justification Le paramètre NAME de la balise APPLET permet de désigner nommément une applet à l’intérieur d’une page HTML visualisée par un navigateur ou un appletviewer. Elle permet au navigateur, lors des communications inter-applets dans une page, de retrouver une applet visualisée en appelant la méthode getApplet() de la classe AppletContext. La balise OBJECT est conseillée dans les dernières versions d’HTML à la place d’APPLET. Néanmoins ce tag est encore très utilisé (y compris dans les exemples du dernier JDK). Exemple <applet codebase="http://my.domain.fr/" code="NervousText.class" width=400 height=75 name = ″monApplet″> </applet> ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA APPLET-TagParam RNC-CNES-Q-80-527 Page 59 Version 4 10 décembre 2005 Il faut utiliser la balise PARAM pour paramétrer les applets. Applet : Exigé Standalone : Sans Objet Description Dans les fichiers HTML chargeant des applets Java, on s’efforcera de paramétrer le plus possible les applets avec les variables spécifiées par la balise PARAM. Justification La balise PARAM permet de donner une valeur à un paramètre nommé de l’application. Moins pratique que les arguments d’une ligne de commande, cette balise permet cependant de configurer le comportement d’une applet par l’intermédiaire du fichier HTML le contenant. A charge au serveur suivant les cas de donner une valeur différente à ce paramètre. Exemple <applet codebase="http://my.domain.fr/applets" code="monApplet.class" width=400 height=75> <param name="niveau" value="expert"> </applet> APPLET-MultiSynchro Ne pas s’appuyer sur un ordre de chargement a priori des différentes applets contenues dans une page HTML. Applet : Recom. Standalone : Sans Objet Description Lorsqu’un fichier HTML faisant référence à plusieurs applets Java est chargé, on ne peut pas faire d’hypothèse sur l’ordre dans lequel les applets sont chargées, et notamment sur l’ordre dans lequel leurs méthodes init seront appelées. Si on souhaite que les applets communiquent entre elles, on fera en sorte qu’un mécanisme de synchronisation charge les applets dans un certain ordre ou en assure le fonctionnement synchronisé. Ce mécanisme de synchronisation doit être défini dans le code Java et n’existe pas pour l’instant en standard. Justification Le chargement des applets et des classes utilisées par celles-ci est effectué de manière asynchrone par les navigateurs. Ainsi on ne peut prévoir d’avance quelle applet sera la première chargée et active, et on ne peut donc pas s’appuyer sur un ordonnancement de chargement à priori. D’autre part des applets chargées par des pages HTML différentes (à l’aide de “ frame ” par exemple) peuvent être amenées à communiquer ensemble. Pour réaliser cette communication, il est recommandé d’implémenter des mécanismes qui en assurent le bon fonctionnement, par exemple en s’assurant de l’existence et de la disponibilité de l’applet distant. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 60 Version 4 10 décembre 2005 Exemple Si les applets sont dans une même page HTML, on pourra s’appuyer sur l’AppletContext fourni par le browser. On l’interrogera (getApplet(name) ou getApplets()) pour récupérer une référence à l’applet distante, qu’on pourra ensuite interroger au travers d’appels de méthodes. Si les applets sont situées dans des pages HTML différentes, on pourra utiliser des variables statiques d’une classe commune permettant de savoir quelles sont les applets actuellement chargées et disponibles pour communiquer. 10.12. PORTABILITE PORTAB-Native On ne doit utiliser des méthodes natives qu’en cas de force majeure. Applet : Exigé Standalone : Exigé Description On ne doit jamais utiliser de méthode native (code externe écrit en C ou autre) dans un programme, sauf s’il n’y aucun autre moyen technique possible de réaliser la fonctionnalité voulue. Autre dérogation possible : la réutilisation justifiée de composants logiciels non Java (eg. d’un code serveur d’une application client/serveur) ou un problème crucial de performance (ponctuel). On devra utiliser des librairies de classes Java fournissant cette fonctionnalité, ou on réécrira celle-ci avec les librairies standard de l’API Java. Justification L’utilisation de méthode native implique par nature l’abandon d’un grand nombre des bénéfices de l’utilisation du langage Java : sécurité, indépendance vis à vis de la plate-forme matérielle, ramasse-miettes (garbage collection), chargement automatique de classes via le réseau,... De plus, un programme qui mixe du code Java et des méthodes natives introduit des trous dans le système de sécurité Java. Il n’y en effet aucune garantie que le code ainsi écrit n’introduise pas de virus, et si un problème de référence mémoire existe dans ce code, comme l’accès à une zone protégée de mémoire, cela provoquera certainement une erreur irrécupérable dans l’interpréteur Java, et stoppera donc le programme. Exemple Si l’on ne dispose pas des fonctions voulues, on peut les réécrire en Java. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA PORTAB-DependAPI RNC-CNES-Q-80-527 Page 61 Version 4 10 décembre 2005 Il est recommandé de n’utiliser que les APIs Java officielles. Applet : Recom. Standalone : Recom. Description Pour toutes les plates-formes cibles, il faut vérifier que les fonctionnalités attendues ne font pas déjà partie des packages standards Java et qu’elles ne figurent pas dans les packages non standard mais déjà spécifiés pas Javasoft. Justification Les spécifications des APIs Java fournissent les services de base à la fabrication de programmes et d’applets Java : structures de base, utilitaires, fabrication d’interface graphique, entréessorties, fonctions réseaux. De plus, des groupes de travail internationaux coordonnés par Sun travaillent en permanence sur des domaines de fonctions précis : GUI 2D, fonctions 3D, objets commerciaux et financiers. Ces groupes de travail définissent ainsi des spécifications ‘Java Core’ pour des paquetages de classes orientées métier. En plus du fait que ces APIs fournissent une référence solide garantissant la pérennité des applications, elles sont le résultat de groupes de travail spécialisés très matures vis à vis des technologies abordées et qui ont mûrement réfléchit à leur intégration dans les librairies de classes Java. Ces spécifications sont donc le reflet de l’état de l’art dans la fonctionnalité abordée et s’intègrent au mieux avec les classes de base Java. Il faut utiliser ces paquetages et ces spécifications afin de garantir à la fois la portabilité et la pérennité de l’application. Exemple Utiliser les packages JFCs - Java Fundation Class - de Sun, qui contiennent entre autres les classes d’interface graphique Swing et une implémentation de l’API Java 2D. PORTAB-JavaOfficiel On ne doit utiliser que la partie officielle des APIs utilisées. Applet : Exigé Standalone : Exigé Description Lorsque l’on utilise une API Java de base ou spécialisée (comme Java 2D), on ne doit se servir que des classes et interfaces documentées, c’est à dire celles qui font partie de la spécification officielle. La spécification officielle est celle dont la documentation javadoc est fournie avec les paquetages ; certains services fournis par les classes des paquetages de base ou spécialisés sont accessibles depuis l’extérieur mais non documentés ; il ne faut pas les utiliser. Justification Toute implémentation d’une API Java contient certainement des particularités qui ne sont pas décrites dans les spécifications officielles, voire utilise des spécificités de la plate-forme cible. Les programmes Java ne doivent donc en aucun cas se baser sur ces API pour des raisons de portabilité. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 62 Version 4 10 décembre 2005 Tout ce qui n’est pas documenté officiellement n’est pas fiable en ce qui concerne la portabilité. S’y fier peut introduire des différences de comportements entre plate-forme qui sont dangereuses et souvent difficiles à détecter. Exemple 1. Ne pas définir de sous-classe à l’intérieur d’un package d’une API Java, mais toujours à l’extérieur, sinon celle-ci a de fortes chances d’être dépendante de l’implémentation. 2. Ne jamais utiliser directement les classes peer du package java.awt.peer car elles dépendent de la plate-forme matérielle GUI de la machine cible. PORTAB-SystemCall Il est recommandé de ne pas appeler de méthode ouverte au système. Applet : Recom. Standalone : Recom. Description La classe java.lang.Runtime fournit des méthodes permettant d’accéder à la plate-forme matérielle de la machine. On ne doit se servir de ces méthodes qu’en respectant des règles précises de portabilité (à définir dans chaque cas). Cette règle est applicable pour toutes les méthodes donnant au programme la possibilité d’accéder à des particularités spécifiques à la machine cible. Cette règle est applicable aux applets car leur environnement d’exécution peut contenir un SecurityManager plus permissif que celui installé par défaut avec les navigateurs classiques. Justification Bien que ces méthodes soient portables, elles offrent la possibilité au programmeur peu scrupuleux d’utiliser des caractéristiques de la machine qui ne sont pas portables, rendant du même coup l’application non portable. Il faut donc garantir une norme d’utilisation de ces méthodes, qui sont par ailleurs peu nombreuses. La plus connue est la méthode exec() de la classe Runtime. Exemple Dans le cas de la méthode exec() de la classe java.lang.Runtime, on ne doit pas l’utiliser exclusivement par commodité. On pourra par exemple autoriser son usage si et seulement si : • l’invocation est activée le plus directement possible par l’utilisateur et celui-ci doit en être averti. • l’utilisateur a la possibilité de préciser avec l’application les commandes (ou programmes) qui vont être exécutés. • tout dysfonctionnement de cette méthode est géré de la manière la plus rigoureuse possible, par exemple avec l’utilisation d’un traitement d’exception adapté. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA PORTAB-ConstPlat RNC-CNES-Q-80-527 Page 63 Version 4 10 décembre 2005 Il ne faut pas définir en dur des constantes dépendantes de la plate-forme. Applet : Exigé Standalone : Exigé Description Certaines classes peuvent être utilisées de manière non portable par les programmeurs, en particulier concernant des constantes qui peuvent être interprétées de manière variable suivant les systèmes d’exploitation. On n’utilisera jamais ces constantes d’une manière dépendante du système. Justification Il faut être très vigilant lorsque l’on utilise ces particularités. On devra s’assurer que l’interprétation des méthodes ou des constantes par le programme est totalement indépendante de la plate-forme matérielle. C’est pourquoi les constantes dont la valeur dépend de la plateforme ne doivent pas être utilisées. Exemple incorrect Prenons le cas de la classe java.io.File qui permet d’accéder à des fichiers ou à des répertoires ; cette classe définit les constantes pathSeparator, pathSeparatorChar, separator, separatorChar, dont la valeur, qui dépend du système d’exploitation, représente le séparateur de fichier ou de chemin d’accès à un répertoire. On peut utiliser le constructeur public File(String path) et créer des fichiers de manière non portable en définissant le paramètre path sans utiliser les constantes ci-dessus, par exemple sous Unix : File fichier = new File("/users/chris/mon_fichier"); Exemple correct On évitera soigneusement de définir des chemins d’accès absolus, on utilisera de préférence les méthodes réalisant elles même la concaténation des noms de fichiers (ex : méthode public File(String path, String name)) et on utilisera les constantes indépendantes du système pour séparer les répertoires. String relativePath = "users" + File.separator + "chris"; File fichier = new File(relativePath, "mon_fichier"); Autre exemple De manière similaire, les inputStream et outputStream autorisent l’insertion directe de caractères fin de ligne dépendant du système. Il faut dans ce cas utiliser la constante LINE_SEPARATOR de la classe java.lang.Character ou la propriété line.separator que l’on obtiendra avec la méthode System.getProperty(String key). ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA PORTAB-GetProperty RNC-CNES-Q-80-527 Page 64 Version 4 10 décembre 2005 Il est recommandé d’utiliser les propriétés portables de la plate-forme si besoin. Applet : Recom. Standalone : Recom. Description La classe java.lang.System fournit les méthodes getProperty et getProperties pour accéder aux constantes dépendantes du système. On les utilisera le plus souvent possible, à moins que des constantes existant dans les classes utilisées n’en fournissent déjà la valeur. Le JDK 1.3 fournit les propriétés suivantes : java.version java.vendor java.vendor.url java.home java.vm.specification.version java.vm.specification.vendor java.vm.specification.name java.vm.version java.vm.vendor java.vm.name java.specification.version java.specification.vendor java.specification.name java.class.version java.class.path os.name os.arch os.version file.separator path.separator line.separator user.name user.home user.dir Numéro de version de Java Nom de “ l’éditeur ” URL de “ l’éditeur ” Répertoire d’installation de Java Version de la spécification de la machine virtuelle “ Editeur ” de la spécification de la machine virtuelle Nom de la spécification de la machine virtuelle Version de la machine virtuelle (implémentation) “ Editeur ” de la machine virtuelle Nom de la machine virtuelle Version de l’environnement d’exécution Java “ Editeur ” de l’environnement d’exécution Java Nom de l’environnement d’exécution Java Numéro de version du format des classes Java Chemin d’accès aux classes de base de Java Nom du système d’exploitation Architecture du système d’exploitation Version du système d’exploitation Séparateur de fichier ("/" sous UNIX) Séparateur du Path (":" sous UNIX) Séparateur des lignes ("\n" sous UNIX) Nom du compte de l’utilisateur courant Répertoire “ home ” de l’utilisateur courant Répertoire de travail courant Remarque : pour des raisons de sécurité les applets ne peuvent pas lire les propriétés suivantes : java.home, java.class.path, user.name, user.home, et user.dir. Justification Ces valeurs ont été définies par les concepteurs du langage Java, afin de permettre au programmeur de paramétrer dynamiquement le code suivant la plate-forme matérielle, le système d’exploitation, et la machine virtuelle Java utilisée. Utiliser ces méthodes pour obtenir les propriétés dépendantes de la machine garantit avec certitude la valeur de ces constantes, ainsi que leur portabilité. Exemple System.getProperty("line.separator"); ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 65 Version 4 10 décembre 2005 PORTAB-AppProperty Il ne faut jamais redéfinir des propriétés de l’application dépendantes de la plate-forme. Applet : Exigé Standalone : Exigé Description Java permet aux applications de définir leur propres propriétés (qui s’ajoutent à celles définies par la classe java.lang.System). On ne définira jamais de propriété de l’application qui dépendrait de la plate-forme matérielle, sauf si cette propriété n’est pas définie par la plateforme Java de base. Justification Le mécanisme de propriété (property) défini par Java permet aux applications de définir un fichier d’initialisation ou de paramétrage utilisé par celles-ci pour adapter dynamiquement leur fonctionnement. Utiliser cette possibilité pour introduire une dépendance vis à vis de la plateforme ne doit pas recouvrir des définitions de propriétés déjà fournies par l’environnement de base Java, sinon il en résulterait des incohérences potentielles entre ces deux types de propriétés. Les propriétés de l’application ne doivent donc concerner que sa partie spécifique et ne jamais occulter, même indirectement, les propriétés fournies en standard. PORTAB-InOutErr On ne doit pas dépendre des fichiers standards in, out et err. Applet : Exigé Standalone : Exigé Description Il ne faut jamais utiliser les fichiers System.in, System.out, et System.err dans une fonction de l’application. Justification En effet toutes les plates-formes ne disposent pas de ces concepts. Les applications ne peuvent donc pas s’appuyer sur ces fichiers prédéfinis. Par contre, on pourra toujours les utiliser dans le cadre d’une trace ou d’un déboguage sur une plate-forme donnée. Exemple Les programmes Java destinés à être utilisés comme commandes système à l’intérieur d’un script ne doivent pas se baser sur ces sorties standard. Ils peuvent par contre utiliser les paramètres de commande de la méthode main(String args[]) de la classe principale, ou fournir une partie GUI élémentaire permettant de récupérer les informations désirées. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA PORTAB-GUISize RNC-CNES-Q-80-527 Page 66 Version 4 10 décembre 2005 On ne doit jamais fixer en dur la taille et/ou la position des widgets. Applet : Exigé Standalone : Exigé Description Lorsque l’on crée une interface graphique en Java, il ne faut jamais assigner de manière statique la taille ou la position des composants graphiques. Justification Bâtir la présentation d’une interface sur des valeurs fixes ou assignées de manière impérative par le programme n’est pas portable. On devra plutôt mixer de façon judicieuse des classes de LayoutManager adaptées au type de fenêtre à afficher, en s’arrangeant pour que les tailles et positions des composants soient calculées dynamiquement par ces LayoutManagers lors de l’instanciation des fenêtres. Le positionnement absolu d’un composant graphique n’est accessible que par une utilisation détournée des classes du JDK. Il est cependant parfois utilisé par des environnements de développement. Malgré leur apparente complexité, les politiques de placement du JDK sont prévues pour faciliter l’adaptation des IHM aux différentes résolutions des stations hôtes. Exemple incorrect public void init() { myFrame = new JFrame(); myFrame.resize(100, 100); JButton myButton = new JButton(″Ok″); myButton.reshape(25, 50, 0, 0); ... } Exemple correct public void init() { myFrame = new JFrame(); myFrame.resize(100, 100); myFrame.setlayout(new BorderLayout()); JButton myButton = new JButton(″Ok″); myFrame.add(″West″, myButton); ... } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA PORTAB-GUIFonts RNC-CNES-Q-80-527 Page 67 Version 4 10 décembre 2005 Il ne faut pas coder en dur les polices de caractères utilisées. Applet : Exigé Standalone : Exigé Description Dans la construction d’une interface graphique on ne doit jamais fixer en dur la police de caractères utilisée ni la taille des caractères. Justification Sur deux machines différentes, et même sur une seule machine, la taille et la disponibilité des polices peuvent varier entre deux sessions. On utilisera donc les utilitaires fournis par le toolkit Java pour déterminer les polices disponibles ainsi que leur taille. Exemple Pour déterminer la liste des polices de caractères disponibles, utiliser : java.awt.Toolkit.getFontList() Pour déterminer la taille d’une police de caractères, utiliser : Font.getFontMetrics() Graphics.getFontMetrics() Par exemple : String fontCourier = ... // Pas en dur. titleFont = new java.awt.Font(fontCourier, Font.BOLD, 12); titleFontMetrics = getFontMetrics(titleFont); PORTAB-GUICapa On ne doit pas présumer des capacités graphiques des machines cibles. Applet : Exigé Standalone : Exigé Description Dans la construction d’une interface graphique on ne fixera jamais les valeurs d’attributs graphiques de la plate-forme matérielle. Justification Les caractéristiques graphiques des machines cibles sur lesquelles on fera tourner des programmes Java sont susceptibles d’être très différentes d’une machine à l’autre et même pour une machine donnée entre deux sessions. Il ne faut donc en aucun cas bâtir des interfaces graphiques sur des attributs aussi versatiles. Exemple On pourra adapter dynamiquement la taille des polices de caractères et/ou des fenêtres suivant la taille courante de l’écran : Toolkit tk = java.awt.Toolkit.getDefaultToolkit(); int screen_res = tk.getScreenResolution(); ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 68 Version 4 10 décembre 2005 Il est certainement sage pour les applets d’utiliser la police de caractère par défaut, car elle peut être choisie par l’utilisateur au travers de son navigateur. Pour une application, il sera certainement plus judicieux d’offrir à l’utilisateur l’opportunité de décider lui-même les caractéristiques graphiques de sa machine (avec une boîte de dialogue), de manière à ce qu’il adapte lui-même l’interface graphique à ses besoins. Ne pas se servir de la possibilité de préciser des couleurs avec des triplets RGB, sachant que le résultat varie singulièrement suivant les configurations matérielles. Le JDK fournit la classe java.awt.SystemColor qui se calibre dynamiquement sur les paramètres couleurs d’une session donnée sur la machine cible. PORTAB-GUIPaintGC Il ne faut pas enregistrer de Graphics à l’intérieur d’une instance. Applet : Exigé Standalone : Exigé Description Bien souvent, les applications ou applets utilisant des fonctions purement graphiques (éditeur d’image ou de dessin, animation dans une applet) ont besoin de l’instance d’objet java.awt.Graphics associé à un composant ; cette instance est une version native de l’objet graphique sous Windows, Motif,... Or les instances de java.awt.Graphics ont une durée de vie gérée par des mécanismes dont le programmeur n’a pas la visibilité. En particulier l’instance de Graphics créée pour une instance de composant peut être supprimée de la mémoire si le composant n’est plus affiché, puis recréée si besoin (par exemple lorsqu’on fait défiler une liste de composants). Il ne faut pas mémoriser dans une variable de classe ou d’instance un tel objet de type Graphics. Par contre certaines méthodes comme la méthode paint() des composants graphiques, fréquemment redéfinie dans les classes applicatives, garantissent la pérennité d’un Graphics pendant la durée de leur exécution. Justification Les instances de ces objets ont une durée de vie très variable à l’intérieur d’un programme, non seulement suivant la plate-forme graphique, mais également suivant le déroulement du programme. Il y a donc beaucoup de risques qu’un tel objet n’existe pas ou soit incomplètement défini, ou simplement invalide lorsqu’on voudra le réutiliser. Il vaudra mieux s’attacher à récupérer dans une variable locale à une méthode cette instance de Graphics et l’utiliser exclusivement quand on en a besoin. On sait d’autre part que lorsqu’un composant graphique a été construit et est visible, l’instance de Graphics associée est disponible. On aura donc plutôt intérêt à conserver à disposition une référence sur ce composant et lui demander quel est son Graphics courant. De façon plus précise, la disponibilité des objets Graphics, qui sont vus dans les programmes comme des instances de la classe abstraite Graphics, mais qui sont en fait des instances de classes concrètes dépendantes de la plate-forme graphique, est limitée à la fois dans le temps et suivant les composants de la façon suivante: • La plate-forme graphique qui pour des raisons d’économie en ressource matérielle graphique ou simplement technique en limite la disponibilité à tout instant – Windows95 n’autorise au maximum l’existence que de quatre instances de Graphics –. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA Page 69 Version 4 10 décembre 2005 • Seuls les composants Canvas et Container disposent à coup sûr d’un Graphics associé (également Button dans les futures implémentations du JDK), Il n’existe aucune garantie de la disponibilité d’un tel objet pour les autres composants de l’AWT ; chaque fournisseur d’implémentation de la machine virtuelle est libre de son choix de réalisation des couches basses de l’AWT. • Seules les méthodes Component.paint() et Component.update() permettent de disposer d’un Graphics valide associé si le composant est une instance de Canvas ou Container. C’est donc uniquement dans ces méthodes que l’on disposera d’un Graphics associé au composant qui soit valide. • Une cascade d’appels à l’intérieur des méthodes paint() ou update() peut amener à une saturation des ressources graphiques (en terme de validité des Graphics) de la plateforme, en particulier si des threads indépendants sont démarrés dans ces méthodes. • L’instance de Graphics associée à un composant graphique est disponible seulement si celui-ci est visible. Il y a donc des risques qu’une référence à un Graphics soit invalide si on la mémorise dans une variable d’instance. On s’attachera donc à appeler explicitement la méthode Component.getGraphics() sur les composants du type Canvas ou Container qui sont visibles, ou à mémoriser la référence au Graphics passée en paramètre de la méthode paint() ou update() seulement à l’intérieur de celle-ci. Ceci assure la validité de l’instance de Graphics utilisée. Exemple Redéfinition de la méthode paint() dans un composant graphique dérivé : Graphics myGraphics = null; void paint(Graphics g) { if (myGraphics == null) { myGraphics = g.create; } // Suit le code pour la methode paint. } PORTAB-GUIEvent On ne doit jamais utiliser le modèle événementiel du JDK 1.0.*. Applet : Exigé Standalone : Exigé Description On utilisera toujours le modèle événementiel introduit depuis la version 1.1 du JDK et jamais celui du JDK 1.0. Les méthodes handleEvent, action, mouseDown,... sont proscrites. Il faudra instancier des EventListener adaptés à chaque événement. Justification Le modèle événementiel du JDK 1.0 est condamné à disparaître et présente de nombreux inconvénients qu’on ne présentera pas ici. Exemple incorrect public boolean handleEvent(Event event) { // On peut sortir de l’application. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA } Page 70 Version 4 10 décembre 2005 if (event.id == Event.WINDOW_DESTROY) { System.exit(0); } return super.handleEvent(event); Exemple correct public class Fenetre extends JFrame implements WindowListener { Fenetre() { ... this.addWindowListener(this); ... } } public void windowClosed(WindowEvent event) { System.exit(0); } PORTAB-Deprecated Il ne faut pas utiliser les méthodes marquées comme Deprecated dans le JDK. Applet : Exigé Standalone : Exigé Description Parmi les évolutions du JDK, on doit noter qu’un certain nombre d’entre elles sont signalées comme deprecated. On n’utilisera pas ces méthodes dans les programmes Java. Justification Toutes ces méthodes sont vouées à la disparition dans les versions futures du JDK. Elles présentaient des problèmes de portabilité, d’internationalisation ou de performance. Elles ont été remplacées par des méthodes plus puissantes ou mieux conçues, soit dans les mêmes classes, soit dans des classes spécialisées. Notons que tant qu’une méthode appartient à une API Java officielle et qu’elle n’est pas marquée comme deprecated, elle sera obligatoirement maintenue dans la prochaine version du JDK. A partir du moment ou une méthode est notée deprecated, elle peut à tout moment disparaître du JDK. Exemple incorrect Date maDate = new Date(97, 09, 25); Exemple correct SimpleDateFormat df = new SimpleDateFormat("yyyy,MM,dd"); try { Date maDate = df.parse(value); } catch (java.text.ParseException e) { ... } Il faut noter qu’il existe toujours une alternative pour suppléer aux méthodes deprecated mentionnée dans la documentation du JDK. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA PORTAB-Swing RNC-CNES-Q-80-527 Page 71 Version 4 10 décembre 2005 Les classes swing doivent toujours être utilisées en priorité par rapport aux classes awt. Applet : Exigé Standalone : Exigé Description Dans les premières versions du JDK, un ensemble de classes graphiques a été mis au point en utilisant les composants présents sur toutes les plates-formes cibles. Ces classes, regroupées dans les sous-packages du package java.awt, se sont avérées rapidement insuffisantes. Elles ne garantissaient en outre pas complètement la portabilité des interfaces créées. Depuis Java 2, de nouvelles classes graphiques ont été ajoutées au JDK. Ces classes sont regroupées dans les nombreux sous-packages du package javax.swing. Les classes swing garantissent la création d’interfaces 100% pur Java. Elles sont bien plus riches que les classes awt et assurent une bien meilleure stabilité de l’aspect des IHM multi-plates-formes. Il est donc nécessaire d’utiliser systématiquement les classes swing pour créer des interfaces graphiques. Justification L’utilisation des classes swing garantit la pérennité de l’application développée et facilite grandement le portabilité de ces dernières. Rappelons que tous les composants awt possèdent un équivalent swing et que les classes swing sont facilement différentiables par leur préfixe “ J ” (Frame Æ JFrame, Applet Æ Japplet, etc.). Exemple incorrect // Panel de demonstration contenant 2 boutons. import java.awt.*; public class Panel2Boutons extends Panel { Button premierBouton = new Button("Bouton No1"); Button secondBouton = new Button("Bouton No2"); } public Panel2Boutons() { setLayout(new FlowLayout()); add(premierBouton); add(secondBouton); } Exemple correct // Panel de demonstration contenant 2 boutons. // Import des classes swing et du composant awt necessaires. import javax.swing.*; import java.awt.FlowLayout; public class Panel2Boutons extends JPanel { JButton premierBouton = new JButton("Bouton No1"); JButton secondBouton = new JButton("Bouton No2"); public Panel2Bouton() { setLayout(new FlowLayout()); add(premierBouton); ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA } } Page 72 Version 4 10 décembre 2005 add(secondBouton); PORTAB-IHMStable1 Une classe graphique doit être “ stable ”. Applet : Recom. Standalone : Recom. Description La stabilité d’un composant graphique est garantie par le fait qu’il ne lève pas d’exception lors de sa création et qu’il ne nécessite pas de nettoyage lors de sa destruction (pas besoin de redéfinir la méthode finalize()). De manière à assurer la stabilité d’un composant graphique, il convient en outre qu’il hérite d’un composant stable et qu’il ne soit composé que de composants stables. Notons que toutes les classes swing présentes dans le JDK peuvent être qualifiées de composants stables. Justification La création (composition) et la destruction des interfaces utilisateurs sont des phases qui ne sont pas censées nécessiter d’opérations particulières. Un utilisateur de classe graphique doit par exemple pouvoir assembler des composants avant d’en avoir défini le contenu. Le problème des constructeurs stables est particulièrement visible lorsqu’un module IHM visualisant des données, nécessite une initialisation des ces dernières (le composant graphique doit pouvoir être créé avant les données). Le respect de cette règle facilite notamment la création de JavaBeans. Exemple incorrect public class VisuInfoScene3D extends JTextArea { private Scene3D scene; // Attention, l’objet Scene3D doit etre initialise avant la // construction du visualisateur pour permettre l’execution // de la methode informationGenerales(). public VisuInfoScene3D(Scene3D scene) { this.scene = scene; setText(scene.informationGenerales()); } ... } Exemple correct public class VisuInfoScene3D extends JTextArea { private Scene3D scene; private static final String manqueInfo = "-- Scene Non Initialisée --"; } public VisuInfoScene3D(Scene3D scene) { this.scene = scene; if ((scene != null) && (scene.isInit() == true)) { setText(scene.informationGenerales()); } else { setText(manqueInfo); } } ... ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA PORTAB-IHMStable2 RNC-CNES-Q-80-527 Page 73 Version 4 10 décembre 2005 Si le constructeur d’une classe graphique peut être amené à échouer, une exception doit être levée. Applet : Exigé Standalone : Exigé Description Bien que cela représente une transgression de la règle PORTAB-IHMStable1, si la création d’un composant graphique peut être amenée à échouer, cet échec doit être notifié par une exception. Justification Cette règle doit être respectée pour empêcher l’utilisateur du composant de continuer à construire son IHM en pensant que l’initialisation est correcte. Exemple Si l’exemple incorrect de la règle PORTAB-IHMStable1 ne peut être rendu correct en testant l’état de l’objet de type Scene3D passé au constructeur (et que l’on ne veut ou ne peut pas modifier la classe Scene3D), le constructeur de la classe VisuInfoScene3D peut être amené à échouer. // NoDataException est une Exception definie dans la librairie 3D utilisee. // EchecInitException est une Exception "maison". public class VisuInfoScene3D extends JTextArea { private Scene3D scene; // Attention, l’objet Scene3D doit etre initialise avant la // construction du visualisateur pour permettre l’execution // de la methode informationGenerales(). Le cas echeant, une // exception sera levee. public VisuInfoScene3D(Scene3D scene) throws EchecInitException { try { setText(scene.informationGenerales()); this.scene = scene; } catch (NoDataException ndException) { throw new EchecInitException(); } } ... } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA PORTAB-Limit Page 74 Version 4 10 décembre 2005 Les fonctionnalités non portables doivent être localisées dans une classe spécifique. Applet : Exigé Standalone : Exigé Description Si une application doit comporter des fonctionnalités non portables, il faut les isoler dans une classe spécifique. Cette règle doit être appliquée quitte à subdiviser une classe homogène dans le seul but d’en extraire les fonctionnalités non portables. Justification Ce mode de fonctionnement facilite l’identification des problèmes potentiels de portabilité et évite de propager la non portabilité par héritage (c’est un principe contenu dans le pattern “bridge”). Exemple incorrect // Classe utilitaire de conversion de format de fichier image. public class ConversionFichierImage { // Conversion d’une image bmp en image gif (format 87a). public void bmp2gif(File bmpFile, File gifFile) { // Algorithme de conversion 100% Java. ... } } // Conversion d’une image bmp en image tiff. // Attention : cette methode utilise le logiciel "bmp2tiff". public void bmp2tiff(File bmpFile, File tiffFile) { Process convertisseur; convertisseur = RunTime.exec("bmp2tiff.exe" + bmpFile + " " + tiffFile); convertisseur.waitFor(); } Exemple correct // Classe specifique contenant les algorithmes de conversion NON PORTABLES. // Les methodes implementees utilisent des logiciels systemes developpes // sur plate-forme PC. public class ConversionNativeFichierImage { // Conversion bmp -> tiff a l’aide du logiciel "bmp2tiff.exe". static public void bmp2tiff(File bmpFile, File tiffFile) { Process convertisseur; convertisseur = RunTime.exec("bmp2tiff.exe" + bmpFile + " " + tiffFile); convertisseur.waitFor(); } } // Classe utilitaire de conversion de format de fichier image. public class ConversionFichierImage { // Conversion d’une image bmp en image gif (format 87a). public bmp2gif(File bmpFile, File gifFile) { // Algorithme de conversion 100% Java. ... } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA } RNC-CNES-Q-80-527 Page 75 Version 4 10 décembre 2005 // Conversion d’une image bmp en image tiff. // Attention : utilisation de la classe "ConversionNativeFichierImage". public bmp2tiff(File bmpFile, File tiffFile) { ConversionNativeFichierImage.bmp2tiff(bmpFile, tiffFile); } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 76 Version 4 10 décembre 2005 10.13. SÉCURITÉ SECUR-Applet On doit sécuriser les applets Java. Applet : Exigé Standalone : Sans Objet Description Dans tout développement d’applets Java, on doit définir les contraintes de sécurité. On doit vérifier que le comportement sécuritaire associé par défaut au navigateur utilisé est compatible avec ces contraintes de sécurité en ne perdant pas de vue leur impact sur les fonctionnalités de l’application ainsi que sur l’efficacité du développement. Au besoin il faut définir un autre SecurityManager de permissivité compatible avec les contraintes de sécurité et de faisabilité pour ce navigateur. Ceci ne pourra être réalisé qu’en utilisant une applet signée (dans le cas contraire, il n’est pas possible de remplacer le SecurityManager standard). Remarque : Lorsque l’applet est signée, il n’est pas toujours nécessaire de créer un nouveau SecurityManager pour modifier ses droits. Certains navigateurs permettent de modifier ces droits par simple configuration. SECUR-Application On doit sécuriser les applications Java standalone. Applet : Sans Objet Standalone : Exigé Description Dans toute application Java “ Standalone ”, on doit définir et implémenter des règles de sécurité. Justification Java n’impose aucune contrainte de sécurité sur les applications “ standalone ”, c’est à dire les applications qui ne sont pas censées être lancées à partir d’un navigateur. Lorsque ces applications ne s’exécutent que sur une seule machine sans faire aucune connexion réseau, on peut considérer qu’a priori elles ne sont pas hostiles, du moins tant que l’utilisateur s’impose des règles de sécurité suffisantes. Par contre, dès qu’une telle application doit se connecter à un serveur, les risques d’agression et d’infection existent au même titre que pour une applet dans un navigateur. Il faut donc dans ce cas définir des règles de sécurité réseau en amont de la réalisation proprement dite. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 77 Version 4 10 décembre 2005 Exemple On pourra par exemple se définir un SecurityManager spécialisé pour l’application, et adapter les ClassLoader et BytecodeVerifier standard. Mais attention, les appels au SecurityManager, dans le cas d’une application “ Standalone ”, doivent être faits explicitement par le programme, rien n’est pris en charge par la machine virtuelle Java dans ce cas, comme c’est le cas pour les applets. On pourra protéger l’accès au jar ou aux classes de l’application pour empêcher toute falsification. Remarque : l’utilisation d’un SecurityManager peut engendrer une perte importante des performances de l’application. Dans le cas où les performances sont critiques, on pourra implémenter manuellement la sécurité dans l’application en vue de faire certifier son application. Pour ce type d'application la sécurité se gère à un autre niveau par des ACL (Access Control List), de l'authentification, avec JCE... SECUR-AppletTest On doit toujours tester les applets dans un navigateur. Applet : Exigé Standalone : Sans Objet Description Toute applet, en plus de tests standards de fonctionnement, par exemple avec un appletviewer, doit être testée également à l’intérieur d’un navigateur. Justification Les contraintes de sécurité appliquées aux applets dans le cas d’un chargement avec un appletviewer sont beaucoup moins restrictives que dans un navigateur. En particulier, les règles de manipulation des fichiers par les applets peuvent être très différentes : les appletviewers permettent souvent de manipuler des fichiers en local et sur le serveur (lecture et écriture). Il est impératif de tester les applets en environnement réel, ne serait-ce que pour s’assurer en permanence qu’elles ne violent pas de règle de sécurité. Exemple En général, on interdit aux applets de manipuler des fichiers locaux et de se connecter à d’autres serveurs que celui d’origine, dans le cas d’une connexion à un serveur distant à l’intérieur d’un navigateur. Cela peut néanmoins être nécessaire fonctionnellement. On devra dans tous les cas s’assurer que toutes les contraintes de sécurité sont respectées. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA SECUR-Obfuscator Page 78 Version 4 10 décembre 2005 Encrypter le bytecode des applications ou des applets contenant du code “ confidentiel ”. Applet : Recom. Standalone : Recom. Description Le bytecode des applications “ sensibles ” téléchargées sur le réseau, en particulier celui des applets, doit être rendu illisible ou incompréhensible, par exemple en utilisant un “ obfuscator ”. Remarque : l’utilisation de ce type d’outils rendra très difficile, voire impossible l’utilisation des mécanismes dynamiques de découvertes (introspection) et d’invocation de méthodes du langage Java. Justification Le bytecode Java généré par un compilateur Java standard peut maintenant être facilement décompilé (car c’est un “ assembleur ” de haut niveau qui a été conçu pour être vérifiable par le Verifier). Toute personne ayant téléchargé une applet Java peut récupérer les bytecodes dans le cache du navigateur et désassembler le code avec javap (du JDK) ou le décompiler avec d’autres outils comme Jasmine ou Mocha. On a alors le code source des classes importées presque identique à l’original, en tout cas récupérable et modifiable à loisir… Il existe cependant au moins un moyen de crypter partiellement les bytecodes : rendre la lecture du code incompréhensible en changeant les identificateurs du programme. L’algorithme luimême reste lisible, mais extrêmement difficile à déchiffrer. Il existe des programmes qu’on appelle obfuscators qui parsent le code source et rendent illisibles et incompréhensibles les programmes (en théorie). Citons Zipper, HashJava, Crema, Macho par exemple. Le seul moyen de cryptage complet du bytecode réside dans l’utilisation d’algorithmes de chiffrement. Ce cryptage peut être fait à deux niveaux : • au niveau des connexions réseau en utilisant SSL (Secure Socket Layer) ; • au niveau du bytecode : le bytecode doit être crypté avant d’être stocké puis décrypté par le ClassLoader au moment de son chargement. Toutes les technologies nécessaires pour réaliser ces cryptage/décryptage sont présentes dans le JDK. On pourra dans les cas très sensibles compléter le travail des obfuscators en modifiant les algorithmes des méthodes pour les rendre moins compréhensibles, sans en abuser car ceci introduit souvent des bogues supplémentaires. SECUR-CLASSPATH Il faut protéger particulièrement les packages standard Java. Applet : Exigé Standalone : Exigé Description Il est indispensable de protéger l’accès aux classes standard de l’API Java. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 Page 79 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA Version 4 10 décembre 2005 Justification Les classes de base de l’API Java et des browsers Web intégrant des machines virtuelles Java sont stockées dans des fichiers installés sur les postes clients. Ces fichiers contiennent notamment les classes ClassLoader et SecurityManager qui pourraient être modifiés (par un virus classique, i.e. non Java) pour permettre à des applets de violer les mécanismes de sécurité. Il faut protéger (autant que l’on peut le faire) ces classes de bases par des mécanismes classiques de protection des fichiers (droit d’écriture) ou des mécanismes supplémentaires de vérification des classes utilisées. Rendre les bytecodes incompréhensibles (par l’homme) et ajouter des systèmes de vérification supplémentaires dans l’application elle-même rendra la tâche du client malveillant plus difficile. On peut noter que les classes de base de Netscape Communicator 4.5 sont signées : elles sont donc protégées contre les attaques évoquées plus haut puisque cette signature garantie leur intégrité. Exemple Inclure un mécanisme interne de vérification de version ou de “ checksum ” sur les bytecodes, si possible disséminé dans plusieurs classes pour protéger un peu plus le code de l’application et le serveur lui-même. SECUR-JavaFlaws Il faut connaître les problèmes de sécurité des outils Java utilisés. Applet : Exigé Standalone : Exigé Description On doit toujours se tenir informé des problèmes de sécurité existant dans les outils Java utilisés. Justification Bien que Java dispose de modèles et mécanismes de sécurité parmi les meilleurs qui soient, il existe pour chaque version d’outil Java utilisé un certain nombre de lacunes. On peut espérer à terme disposer de mécanismes de sécurité presque inviolables, mais ce n’est pas le cas actuellement, essentiellement en ce qui concerne les clients malveillants. Pour pouvoir parer à toute éventualité d’attaque des serveurs, il faut connaître ces lacunes de sécurité concernant les outils utilisés. Exemple Visiter régulièrement les sites Internet http://www.rstcorp.com/javasecurity/links.html suivants : http://java.sun.com/security, ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 80 Version 4 10 décembre 2005 10.14. OPTIMISATION OPTIM-9010 Il faut d’abord déterminer correctement les parties à optimiser. Applet : Exigé Standalone : Exigé Description Les “ profilers ” permettent de tracer l’exécution d’une application. En Java, l’option prof de l’interpréteur crée un fichier profile dans le répertoire courant : ./java.prof. On peut ensuite utiliser des outils d’analyse pour examiner les parties de l’application qui sont les plus gourmandes en ressources (mémoire ou temps d’exécution). Certains logiciels permettent également d’effectuer ces analyses de manière automatique en assurant le suivi des processus distribués. Justification Dans la majorité des cas, 90% du temps d’exécution est consommé par 10% seulement d’un programme, et ceci le plus souvent en des endroits où l’on ne s’y attend pas a priori. C’est donc ici qu’il faut concentrer ses efforts d’optimisation. Pour ce faire, il faut analyser le fonctionnement du programme pour déterminer exactement où le programme coûte le plus cher en ressources. On s’appuiera dans la mesure du possible sur des outils adaptés (cf. exemple). Exemple Les sociétés suivantes fournissent de très bons logiciels d’optimisation de code respectant le principe de cette règle : • Intuitive Systems Opimize it ! : http://www.optimizeit.com • KL JProbe Profiler : http://www.klg.com/jprobe • Rational Quantify (NT) : http://www.rational.com • Javix Program Analyzer : http://www.javix.com ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA OPTIM-AlgoStructs RNC-CNES-Q-80-527 Page 81 Version 4 10 décembre 2005 Il est recommandé de réfléchir à l’optimisation de façon globale en termes d’algorithmes et de structures de données. Applet : Recom. Standalone : Recom. Description En amont de la réalisation et surtout au commencement de celle-ci, le choix de bons algorithmes associés à de bonnes structures de données est déterminant pour les performances d’un programme. Cette règle s’applique essentiellement aux parties du programme qui nécessitent une algorithmie spécialisée (c’est à dire sortant de l’ordinaire). Justification Donald Knuth disait déjà dans les années 70 : ‘We should forget about small efficiencies, .... premature optimization is the root of all evil’. Cette affirmation n’a pas perdu de sa pertinence aujourd’hui. Il ne sert à rien de chercher à optimiser systématiquement au niveau le plus bas du code alors que l’algorithme utilisé est déficient. De même, utiliser des structures de données inadéquates (même si faciles à implémenter) dégradera systématiquement les performances et augmentera la consommation mémoire dans bien des cas. C’est d’ailleurs souvent en changeant d’algorithme ou en choisissant de meilleures structures de données que l’on réalise les plus importantes optimisations. Exemple 1 Ne jamais utiliser un algorithme de tri à bulles dont la complexité est en O(n2). L’algorithme du QuickSort a fait ses preuves. Exemple 2 Plutôt que d’utiliser des tableaux à plusieurs dimensions ou des listes (Vector), l’emploi d’une classe implémentant la notion d’arbre binaire ne serait elle pas plus opportune ? La classe HashMap fournie dans l’API Java est très souple et performante, ne pas hésiter à l’utiliser. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA OPTIM-Productivité1 RNC-CNES-Q-80-527 Page 82 Version 4 10 décembre 2005 Il est recommandé d’utiliser de bons outils de développement. Applet : Recom. Standalone : Recom. Description Les outils de développement intégrés (IDEs) distribués par les constructeurs de logiciels tels que IBM VisualAge for Java, Inprise JBuilder, WebGain Visual Café, Sun Forte for Java augmentent nettement la productivité des développeurs. Il faut les utiliser le plus systématiquement possible, c’est à dire les préférer à des solutions maison basés sur des éditeurs de texte de bas niveau combinés aux outils de base (java, javac, jdb, appletviewer) du kit de développement Java (JDK). L’utilisation de ces outils de base ne doit pas cependant être proscrite. En effet, dans certains cas, il peut être nécessaire ou judicieux d’utiliser ces outils lorsqu’il y a par exemple une incompatibilité technique des IDEs avec une bibliothèque de classes Java. Attention en règle générale à l’inclusion de classes “ maison ” développées par chaque éditeur. Il ne faut utiliser ces classes que si elles apportent un valeur ajoutée certaine au programme à développer (Cf. PORTAB-dependAPI). Cette recommandation est valable pour tous les environnements de développement et particulièrement pour Microsoft Visual J++. Cet outil offre un environnement de développement très convivial mais n’est pas destiné à développer des applications Java portables. Il est par contre très bien adapté au développement de composants COM en Java. Justification Les IDEs, profitant d’une grande expérience (plus de vingt ans pour Visual AGE qui reprend en partie le fameux environnement de développement Smalltalk), sont constitués d’une palette d’outils modernes et très utiles qui manquent dans le JDK : Débogueur puissant, compilation incrémentale avec optimisation de code, outil de construction d’interface ou de JavaBeans, programmation visuelle, butineur de classes et de packages,... Au contraire, les outils de base du JDK fournissent une infrastructure minimale pour le développement qui n’est pas adaptée à la construction d’applications orientées objet à grande échelle. De plus ils ne disposent pas d’une interface graphique. OPTIM-Productivité2 Il faut utiliser la documentation de base fournie avec le JDK ou les IDEs pour améliorer la productivité de développement. Applet : Exigé Standalone : Exigé Description On doit utiliser le ‘tutorial’ et la documentation hypertexte des API fournies avec le JDK, ou sinon ceux mis à disposition avec l’IDE utilisé. Justification A la différence des documents papiers, l’utilisation de ces documents hypertextes permet un accès rapide et efficace à une information à jour et pertinente. L’exploitation du temps du développeur et sa formation s’en trouvent rapidement améliorées. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 83 Version 4 10 décembre 2005 Exemple Tutorial Java en ligne et documentation hypertexte des API Java. OPTIM-Compilation Il est recommandé d’utiliser l’option de compilation optimisée de Java. Applet : Recom. Standalone : Recom. Description L’option de compilation ‘ -o ’ du compilateur Java doit être utilisée, au moins en version d’exploitation. Justification Cette option de compilation permet au compilateur de remplacer les expressions calculables par des constantes, de gérer des bytecodes plus efficace pour les boucles, de supprimer dans une moindre mesure le code mort comme if (false) i = 1. Ces optimisations sont minimales, en tout cas en regard des compilateurs FORTRAN ou C modernes. Cependant les versions successives des compilateurs s’améliorent sans cesse, et il vaut mieux prendre immédiatement l’habitude d’utiliser cette option, qui déjà permet une amélioration minimale des bytecodes Java générés. Exemple java -o Myclass.java OPTIM-InvBoucle Il faut sortir des boucles leurs invariants. Applet : Recom. Standalone : Recom. Description Les expressions invariantes situées à l’intérieur des boucles doivent être extraites et situées séquentiellement en amont de celles-ci. On créera pour cela une variable temporaire qui sera ensuite utilisée dans la boucle. Bien que l’application de cette règle permette d’optimiser sensiblement le code généré, il ne faut pas perdre de vue que toute optimisation des performances d’un logiciel nuit à la lisibilité et donc à la maintenance des sources. Cette recommandation doit donc être mise en œuvre dans le respect de la règle OPTIM-9010. Justification Ces expressions invariantes sont recalculées à chaque tour de boucle (perte de temps) et génèrent des bytecodes supplémentaires. Les compilateurs Java actuels ne savent pas réaliser eux-mêmes ces optimisations. Exemple incorrect for (i = 0; i < tableauEntree.length; i++) { tableauSortie[i] = tableauEntree[i] + alpha * beta; } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 84 Version 4 10 décembre 2005 Exemple correct float produitAlphaBeta = alpha * beta; for (i = 0; i < tableauEntree.length; i++) { tableauSortie[i] = tableauEntree[i] + produitAlphaBeta; } OPTIM-SousExpr Il faut éliminer les sous-expressions communes coûteuses en temps. Applet : Recom. Standalone : Recom. Description Les expressions gourmandes en temps de calcul (comme les appels de méthodes) situées à l’intérieur d’un bloc de code ne doivent être calculées qu’une seule fois dans ce bloc. Bien que l’application de cette règle permette d’optimiser sensiblement le code généré, il ne faut pas perdre de vue que toute optimisation des performances d’un logiciel nuit à la lisibilité et donc à la maintenance des sources. Cette recommandation doit donc être mise en œuvre dans le respect de la règle OPTIM-9010. Justification Ceci améliore significativement les performances, en particulier pour des expressions impliquant des calculs ou des méthodes complexes. De plus, cela force le programmeur à mieux structurer le code de ce bloc. Exemple incorrect double gamma double lambda = alpha * Math.sqrt(beta); = epsilon * Math.sqrt(beta); Exemple correct double racineBeta = Math.sqrt(beta); double gamma = alpha * racineBeta; double lambda = epsilon * racineBeta; OPTIM-AccesVars Il faut utiliser des variables locales quand on le peut. Applet : Recom. Standalone : Recom. Description Dans le corps des méthodes, il vaut mieux utiliser des variables locales plutôt que des variables d’instance ou des éléments de tableau. Ceci est particulièrement vrai pour les types de base int, float, double, boolean, char, ... Justification Les bytecodes générés en utilisant une variable locale sont plus efficaces et moins volumineux. En effet les variables d’instance nécessitent un accès de champ supplémentaire et les éléments de tableau subissent des vérifications coûteuses de dépassement de bornes. De plus, l’introduction de variables locales (convenablement nommées) améliore la lisibilité des sources. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 85 Version 4 10 décembre 2005 Exemple incorrect public ClasseSpecifique extend ClasseGenerale { int variableEntiere; float variableReelle; Calculateur calculateur = new Calculateur(); int i; float premierCalcul(int min, int max, float facteur) { variableEntiere = max – min; variableReelle = facteur * max + min; for (i = 0; i < variableEntiere; i++) { calculateur.ajouteIteration(variableReelle, i); } return calcutateur.resultatGlobal(); } int secondCalcul(float alpha) { ... // Autre utilisation du calculateur et des variables. } Exemple correct public ClasseSpecifique extend ClasseGenerale { float premierCalcul(int min, int max, float facteur) { float constanteG; // Constante de Grosberg. int borne; // Limite superieure. int rang; // Rang du calcul iteratif. Calculateur calculGrosberg; // Calcutateur general utilise // pour l’algorithme de Grosberg // Initialisation des variables locales. constanteG = facteur * max + min; borne = max – min; calculGrosberg = new Calculateur(); } // Boucle de calcul. for (rang = 0; rang < borne; rang++) { calculGrosberg.ajouteIteration(constanteG, rang); } // Calcul (et retour) du resultat global. return calculGrosberg.resultatGlobal(); int secondCalcul(float alpha) { ... // Autre declaration locale du calculateur et des variables. } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA OPTIM-Strings RNC-CNES-Q-80-527 Page 86 Version 4 10 décembre 2005 Si une optimisation des performances sur la gestion des strings est nécessaire, il est recommandé d’utiliser la méthode append plutôt que l’opérateur +. Applet : Recom. Standalone : Recom. Description Le langage Java fournit la classe String, assurant une gestion simple et pratique des chaînes de caractères par les programmeurs. En particulier, on peut réaliser la concaténation de deux strings avec l’opérateur + de la classe String au lieu d’avoir à utiliser la méthode append de la classe StringBuffer. Dans le cas où une optimisation est nécessaire, on préférera cependant la méthode append fournie par l’API à l’opérateur + du langage. Ceci est également vrai pour l’opérateur +=. Justification Les objets de la classe String sont des invariants : une fois instanciés, on ne peut plus les modifier. Pour réaliser la concaténation de deux chaînes de caractères en utilisant l’opérateur +, le compilateur Java passe par l’utilisation d’instances de la classe StringBuffer, qui elles ne sont pas invariables. Par exemple, String s = "toto"; est en réalité traduit par : String s = new StringBuffer().append("toto").toString(); le tableau de caractères toto étant passé en paramètre à la méthode append. Lors de l’utilisation de l’opérateur +, le compilateur crée une instance StringBuffer et concatène les deux tableaux de caractères de par et d’autres de l’opérateur. Par exemple : String s = s1 + "toto"; se traduit en fait par : String s = new StringBuffer().append(s1.toCharArray()). append("toto").toString(); Cette particularité du compilateur simplifie le travail du programmeur, mais on voit ici que le compilateur crée non seulement un objet intermédiaire (un StringBuffer), ce qui est coûteux en soi, mais doit de plus convertir la chaîne s1 en tableau de caractères. De ce fait les expressions concaténant des chaînes de caractères à l’aide de l’opérateur + sont peu efficaces. On préférera donc utiliser judicieusement la classe StringBuffer et sa méthode append à l’opérateur +. Exemple non optimisé String chaine = "hello"; for (int i = 0; i < 10000; i++) { chaine += ″World″; } Exemple optimisé StringBuffer chaine = new StringBuffer(″hello″); ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 87 Version 4 10 décembre 2005 for (int i = 0; i < 10000; i++) { chaine.append(″World″); } Les benchmarks mettent en évidence un temps d’exécution supérieur d’un facteur proche de 100 pour l’opérateur +. OPTIM-Synchro Il est recommandé de n’utiliser le mot-clef synchronized que si nécessaire. Applet : Recom. Standalone : Recom. Description Le mot-clef synchronized en Java sert à empêcher des threads d'accéder simultanément aux mêmes données. Il peut être appliqué à des méthodes ou à des blocs de code. On n'utilisera pas ce mot-clef de manière abusive pour essayer de garantir que le code est “ thread-safe ”. Justification La synchronisation est extrêmement coûteuse. Chaque synchronisation entraîne un surcroît de contrôles, d’appels de méthodes, et de changements de contexte qui dégrade considérablement les performances du programme. Les benchmarks référencés rapportent un facteur de ralentissement de 10 à 50 si l’on marque une méthode comme synchronisée. Pour une meilleure efficacité, il ne faudra donc marquer des méthodes comme synchronisées uniquement si nécessaire. Attention : il faut toutefois veiller à synchroniser toutes les sections critiques dans les programmes multi-thread, sous peine d'avoir un programme ne s'exécutant pas correctement. Exemple incorrect public synchronized float calculerMoyenne() { int nbElems = valeurs.length; for (int i = 0; i < nbElems; i++) { moyenne += valeurs[i]; } return (float) moyenne / (float) nbElems; } Exemple correct public float calculerMoyenne() { int nbElems = valeurs.length; // Cette methode ne change pas l’etat du recepteur : // Les données sont en lecture seulement. for (int i = 0; i < nbElems; i++) { moyenne += valeurs[i]; } return (float) moyenne / (float) nbElems; } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA OPTIM-Null RNC-CNES-Q-80-527 Page 88 Version 4 10 décembre 2005 Il est inutile de tester l’allocation des objets. Applet : Exigé Standalone : Exigé Description En Java, il n’est pas nécessaire de tester que le retour d’une création d’objet est un pointeur NULL. Justification Cette habitude provenant des développeurs C++ n’est pas nécessaire en Java et surcharge inutilement les applications. Si une allocation n’est pas possible, c’est la machine virtuelle qui se charge de lever une exception. Au besoin, cette exception peut être traitée localement ou globalement par l’application. OPTIM-List Il faut éviter d’utiliser la classe Vector et choisir le type de classe “liste” le plus adapté en fonction de l’algorithme. Applet : Recom. Standalone : Recom. Description Quatre types d’implémentation de liste sont présents dans le JDK : ArrayList, LinkedList, Vector et le tableau d'éléments (array). De manière à optimiser les performances, il est souhaitable d’effectuer les choix suivants : • Si la taille du tableau est fixe, on utilisera un tableau simple (array). Le tableau possède en outre l’avantage de contenir des données typées et d’éviter ainsi les transtypages intempestifs. • Pour une liste classique, il faut utiliser par défaut la classe ArrayList. Cette dernière fournit en effet les meilleures performances d’accès aux données. • Dans le cas particulier où l’algorithme nécessite un grand nombre d’insertions et de suppressions, la classe LinkedList pourra être employée. On évitera donc l’utilisation de la classe Vector qui fournit les mêmes services que la classe Arraylist mais avec des performances amoindries (sa présence dans le JDK est historique et son utilisation ne doit être envisagée que pour des raisons de compatibilité antérieure à Java 2). Justification Obtenir une implémentation adaptée aux performances souhaitées et garantir la pérennité de l’application développée. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 Page 89 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA Version 4 10 décembre 2005 Exemple Exemple de performances obtenues avec les différentes implémentations d’une liste : Type Get Iteration Insert Remove array 1430 3850 --- --- ArrayList 3070 12200 500 46850 16320 9110 110 60 4890 16250 550 46850 LinkedList Vector Le tableau ci-dessus représente le temps nécessaire (en ms) à l’exécution de 50 000 opérations. Ces performances ne sont données qu'à titre indicatif et peuvent bien évidemment varier en fonction de la plate-forme et de la machine virtuelle utilisées. OPTIM-Set Il faut adapter le type de classe “ ensemble ” implémenté en fonction de l’application visée. Applet : Recom. Standalone : Recom. Description Deux implémentations d’ensembles sont présentes dans le JDK : TreeSet et HashSet. Les ensembles gérés par la classe HashSet ont en général des performances meilleures que ceux gérés par la classe TreeSet (particulièrement pour les ajouts et les recherches). Il est donc préférable d’utiliser HashSet. La seule raison pouvant entraîner le choix de la classe TreeSet est la nécessité d’avoir constamment des données triées. Justification Obtenir une implémentation adaptée aux performances souhaitées. Exemple Exemple de performances obtenues avec les différentes implémentations d’un ensemble : Type TreeSet HashSet Taille Ajout Recherche Itération 10 138.00 115.00 187.0 100 189.50 151.10 206.50 1000 150.60 177.40 40.04 10 55.00 82.00 192.00 100 45.60 90.00 202.20 1000 36.14 106.50 39.39 Le tableau ci-dessus représente le temps nécessaire (en ms) à l’exécution de 50 000 opérations sur 10 éléments en fonction en de la taille des ensembles. Ces performances ne sont données qu'à titre indicatif et peuvent bien évidemment varier en fonction de la plate-forme et de la machine virtuelle utilisées. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 Page 90 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA OPTIM-Map Version 4 10 décembre 2005 Il faut éviter d’utiliser la classe Hashtable et choisir le type de classe “ données indexées ” en fonction de l’application visée. Applet : Recom. Standalone : Recom. Description Le JDK fournit 3 implémentations d’ensembles de données indexées : Hashtable, HashMap et TreeMap. De manière à optimiser les performances, il est souhaitable d’effectuer les choix suivants : • utiliser par défaut la classe HashMap ; • n’utiliser TreeMap que dans le cas exceptionnel où les données doivent être constamment triées ; • limiter l’utilisation de la classe Hashtable à la résolution de problèmes de compatibilité antérieure à Java 2. Les performances des classes Hashtable et HashMap sont quasiment équivalentes en général. On préférera cependant HashMap car ses performances sont légèrement supérieures et son architecture, introduite avec Java 2, est amenée à perdurer. Justification Obtenir une implémentation adaptée aux performances souhaitées et garantir la pérennité de l’application développée. Exemple Exemple de performances obtenues avec les différentes implémentations d’un ensemble de données indexées : Type TreeMap HashMap Hashtable Taille Déposer Prendre Itération 10 143.00 110.00 186.00 100 201.10 188.40 280.10 1000 222.80 205.20 40.70 10 66.00 83.00 197.00 100 80.70 135.70 278.50 1000 48.20 105.70 41.40 10 61.00 93.00 302.00 100 90.60 143.30 329.00 1000 54.10 110.95 47.30 Le tableau ci-dessus représente le temps nécessaire (en ms) à l’exécution de 50 000 opérations sur 10 éléments en fonction en de la taille des ensembles. Ces performances ne sont données qu'à titre indicatif et peuvent bien évidemment varier en fonction de la plate-forme et de la machine virtuelle utilisées. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA OPTIM-BitSet Page 91 Version 4 10 décembre 2005 L’utilisation de la classe BitSet est déconseillée. Applet : Recom. Standalone : Recom. Description La classe BitSet permet de stocker des valeurs binaires sous forme compacte mais, au regard de ses performances, son usage est à déconseiller. Justification Les performances de manipulation d’un tel ensemble sont bien inférieures à celles obtenues avec un tableau classique. Le seul intérêt de cette classe est l’éventuel gain mémoire mais il faut savoir qu’un objet de ce type aura une taille minimum de 64 bits. L’intérêt de l’usage de cette classe est donc fortement discutable. OPTIM-Iteration Il faut réaliser les itérations avec l’interface Iterator. Applet : Recom. Standalone : Recom. Description Pour parcourir de manière itérative les différents ensembles d'objets, le JDK contient deux interfaces spécifiques : Iterator et Enumeration. Outre le fait de fournir des fonctionnalités adaptées au parcours itératif, ces interfaces permettent de s'affranchir du type d'implémentation utilisée pour l’ensemble des données à traiter ; leur utilisation est donc fortement conseillée. On utilisera par contre systématiquement l’interface Iterator au détriment de l’interface Enumeration. Beaucoup de collections d’objets peuvent être parcourues à la fois par un Iterator et une Enumeration, il faut toujours préférer l’interface Iterator. Certains objets n’offrent qu’un parcours par l’interface Enumeration, par extension ces derniers sont donc à proscrire (une implémentation plus récente de leur(s) fonctionnalité(s) est généralement présente dans le JDK (utiliser par exemple, HashMap plutôt que Hashtable et ArrayList plutôt que Vector). Justification L’interface Iterator introduite par Java 2 est préférable à l’ancienne interface Enumeration car elle est plus rapide et offre des fonctionnalités accrues. Le respect de cette règle garantit la pérennité de l’application développée et optimise l’implémentation. Exemple // Methode de suppression des elements null. public void supprimeObjetsNull(Iterator iteration) { while (iteration.hasNext()) { if (iteration.next() == null) { iteration.remove(); } } } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 92 Version 4 10 décembre 2005 // Exemple d’appel de cette methode. ArrayList maliste; ... supprimeObjetsNull(maListe.iterator()); ... OPTIM-AppletJar Il est préférable de regrouper tous les composants d’une applet dans un fichier “ .jar ” unique. Applet : Exigé Standalone : Sans Objet Description Tous les éléments utilisés par une applet (aussi bien les classes que les images ou les sons), seront placés dans un même JAR (Java Archive). Justification Une applet peut prendre beaucoup de temps à se charger car elle doit télécharger tous ses composants à chaque fois en utilisant une connexion serveur distincte (le cache du browser peut être utilisé mais ce n’est pas garanti). Un fichier JAR unique contenant tous les éléments d’une applet pourra être téléchargé en une seule fois et la signature des composants pourra tout de même être utilisée individuellement pour chaque entrée du fichier JAR. OPTIM-Access Il faut limiter l’implémentation des accesseurs (get/set/is) au minimum. Applet : Exigé Standalone : Exigé Description Tous les attributs d’une classe n’ont pas besoin d’accesseurs. Il ne faut pas présumer de l’usage d’un accesseur et surcharger inutilement le code et la documentation d’une classe. Les méthodes d’accès aux attributs privés d’une classe devront donc être définies de manière à être suffisantes pour l’usage préconisé. On prendra toutefois garde à implémenter suffisamment d’accesseurs pour assurer la réutilisation de la classe. Attention, certains outils de conception (comme Rational Rose) peuvent être paramétrés pour générer automatiquement des méthodes d’accès pour tous les attributs d’un objet. Justification La surcharge de travail liée à la création et à la maintenance d’accesseurs non nécessaires nuit à la productivité. Les variables de classes sont souvent dépendantes les unes des autres et le fait d’autoriser leur lecture et écriture indépendamment complexifie (souvent inutilement) le code. De plus, l’implémentation de méthodes n’étant pas utilisées dans le cadre du projet augmente fortement les risques de bug lors d’une utilisation ultérieure de ces dernières. Exemple Public class Maliste { private int taille; ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 93 Version 4 10 décembre 2005 private double[] elements; // Cette classe implementera les methodes d’acces suivantes : // public int getTaille() // public void ajoutElement(double valeur) // public void supprimeElement(int numero) // public void definirElement(int numero, double valeur) // public double[] getElements() } // Les accesseurs suivants ne seront pas implante : // void setTaille(int taille) // void setElements(double[] elements) ... ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 Page 94 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA Version 4 10 décembre 2005 11. UTILISATION DES LIBRAIRIES JAVA FORMA-PackBase Une connaissance correcte des packages java.lang, java.util et java.io est indispensable dès la conception. Applet : Exigé Standalone : Exigé Description Les packages java.* font partie intégrante du langage Java. • Le package java.lang est une extension immédiate du langage ; il définit par exemple les classes Integer, Float, ... qui permettent de gérer les valeurs numériques comme des objets en fournissant les services de conversion etc. associés. • Le package java.util contient des classes utilitaires dont il est difficile de se passer : String, StringBuffer, StringTokenizer pour gérer les chaînes de caractères, HashMap et Dictionary pour gérer les collections,... • Le package java.util.zip compression/décompression de fichiers. contient des utilitaires gérant la • Le package java.io contient toute une série de classes permettant de gérer les entrées/sorties. Il faut connaître et utiliser le contenu de ces librairies dès la phase de conception. Justification Cela permet en effet en phase de conception de définir de façon efficace des classes utilitaires spécifiques au projet en utilisant au mieux les fonctionnalités préexistantes. En phase de développement cela permet d'écrire du code plus efficace et plus synthétique, ce qui facilite la maintenance et l'évolutivité du logiciel. FORMA-PackSpecif Il faut utiliser les packages standard adaptés au type d'application réalisée. Applet : Exigé Standalone : Exigé Description Suivant le type d'application réalisée, il faut utiliser dès la conception les packages fournis avec le langage. Il est nécessaire de bien connaître le contenu des packages du JDK dès la phase de conception afin de les utiliser au plus tôt s’ils sont adaptés aux besoins de l’application. On trouvera la liste exhaustive de ces packages dans la documentation HTML du JDK (page : api/overview-summary.html). Justification Même justifications que pour la règle FORMA-PackBase. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA Page 95 Version 4 10 décembre 2005 Exemple de quelques packages utiles Package Usage java.lang Doit toujours être utilisé, il contient les classes fondamentales de Java. java.math Doit être utilisé pour l’arithmétique de précision. java.text Doit être utilisé si l'application gère l’internationalisation des textes. java.swing et ses nombreux sous-packages Doivent être utilisés si l'application contient une Interface Homme Machine. javax.swing.event java.awt.event Doivent être utilisés pour gérer les événements graphiques. java.applet Doit être utilisé en complément de la classe javax.swing.JApplet si l'application est activée depuis une page HTML accessible depuis un navigateur. java.net Doit être utilisé si l'application manipule des sockets ou des URLs. java.awt.image Doit être utilisé si l'application gère des images. java.awt.datatransfer Doit être utilisé si l’on envisage de transférer des données entre applications (sur le mode copier-coller). java.beans Doit être utilisé pour définir des JavaBeans. java.lang.reflect Permet à un programme d’accéder aux fonctionnalités d’introspection disponibles dans le langage Java (découverte dynamique du contenu d’une classe et instanciation/invocation dynamique de méthode). java.rmi org.omg ainsi que leurs sous-packages Peuvent être utilisés pour créer des objets distribués et accéder à des objets distants. java.security et ses sous-packages Doivent être utilisés si on gère la sécurité de façon explicite (cryptage, signature électronique des classes, sécurité introduite dans une application standalone). java.sql Doit être utilisé de préférence pour s’interfacer avec une base de données (il faut connaître son contenu avant d’envisager l’utilisation du package propriétaire d’une base de donnée spécifique). ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA FORMA-PackMetier RNC-CNES-Q-80-527 Page 96 Version 4 10 décembre 2005 Il faut engager dès le début du projet une réflexion sur la réutilisation. Applet : Exigé Standalone : Exigé Description Il faut réfléchir aux objets métier, et ce à deux niveaux : • Les classes dont j’ai besoin existent-elles déjà ? • Si elles n’existent pas comment les rendre réutilisables ? (qualité, caractère générique, information,…) Justification La réutilisation implique un investissement qui peut s’avérer rentable si les objets métier sont bien identifiés et font l’objet d’une concertation entre les utilisateurs potentiels. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 97 Version 4 10 décembre 2005 12. INTERFACE AVEC L’EXTERIEUR Les chapitres traitant de la portabilité et de la sécurité expliquent pourquoi il faut limiter au maximum les interfaces entre un programme Java et l’extérieur, à savoir le système d’exploitation, l’environnement d’exécution, des programmes ou librairies externes. On est cependant parfois contraint d’utiliser ces interfaces. Les règles de ce chapitre donnent quelques conseils d’utilisation de ces interfaces. 12.1. INTERFACE ENTRE JAVA ET DES PROGRAMMES EXTERNES CONCEP-Exterieur Il faut adapter le type d’interface avec l’extérieur aux besoins du projet. Applet : Exigé Standalone : Exigé Description Il faut structurer l’application ou l’applet en tenant compte des besoins réels en termes de distribution ; on peut distinguer trois cas de figure allant de la solution la moins distribuée à la solution la plus distribuée : • Chargement de fonctions natives par l’intermédiaire d’une librairie dynamique. Il y a alors un seul exécutable (multi-threadé) : l’interpréteur Java. • Appel d’exécutables extérieurs à l’aide de la méthode System.exec(...). Il y a alors exécution d’un autre programme sur le même ordinateur. C’est la méthode la plus simple et la plus efficace dans le cas d’un contexte mono-machine ; elle présente l’avantage de découpler le code Java du code natif ce qui permet de conserver les qualités de robustesse du programme Java, surtout au niveau de la gestion de la mémoire. Cette solution est moins coûteuse en termes d’effort de développement que la précédente. • Appel à des services distants de façon plus ou moins élaborée : • connexion directe par sockets ou URL (package java.net), • utilisation de l’API Java RMI (Remote Method Invocation), • utilisation d’un middleware CORBA Ces solutions sont les plus souples en termes de distribution de l’application, mais nécessitent bien sûr un effort de développement supplémentaire. Justification Dans le cas où l’on est obligé de faire appel à des ressources extérieures, il faut bien évaluer le besoin et choisir une solution adaptée de façon à limiter les coûts de développement et de maintenance. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 Page 98 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA Version 4 10 décembre 2005 12.2. ACCES A L’ENVIRONNEMENT CONCEP-Ressources Il est recommandé setProperty. d’utiliser les méthodes Applet : Recom. Standalone : Recom getProperty et Description Lorsqu’on a besoin d’accéder à des caractéristiques extérieures, ou de paramétrer le comportement de l’application en fonction du contexte d’exécution, il faut utiliser la méthode System.getProperty(...) pour extraire des informations, le passage des informations au moment de l’invocation de l’interpréteur pour en positionner de façon statique, et la méthode System.setProperty(...) pour en positionner de façon dynamique. Il ne faut pas par exemple définir un fichier de paramétrage de l’application et lire dedans le chemin d’accès au répertoire des données. Justification Le mécanisme des propriétés existe déjà. Il faut donc l’utiliser. Exemple Passage d’une variable d’environnement comme propriété à l’interpréteur Java (sous Windows) : C:\> java -Dprinter=%PRINTER% Idem (sous UNIX) : % java -Dprinter=$PRINTER ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 99 Version 4 10 décembre 2005 13. ORGANISATION DU CODE ORGANI-Package Un package doit être constitué d'un ensemble de classes formant un tout sémantique. Applet : Exigé Standalone : Exigé Justification L’organisation en package a pour but de créer des groupes de classes sémantiquement liées. En Java, une importance prédominante est donnée à la collaboration entre classes d’un même package. Ainsi, il n’est pas possible de donner des droits aux classes filles (protected) sans que ces droits ne soient partagés par les classes du package et la seule façon d’interdire l’accès du package à un élément d’une classe est de le définir private. ORGANI-Import Il faut expliciter les classes importées. Applet : Recom. Standalone : Recom. Description Lors de l'importation de classes d'un autre package, il est recommandé de ne pas utiliser le caractère “ * ” mais plutôt d’indiquer explicitement quelles classes sont utilisées. Justification L'importation d'un package entier ne diminue pas l'efficacité du code : en effet seules les classes réellement utilisées sont prises en compte par le compilateur. Cependant une référence exacte aux classes externes utilisées améliore la lisibilité du code. Exemple la ligne : import javax.swing.*; ne donne aucune information sur les classes réellement utilisées dans le code. Au contraire les lignes : import javax.swing.JButton; import javax.swing.JContainer; donnent des informations sur la nature du code développé. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 100 Version 4 10 décembre 2005 14. DOCUMENTATION ET COMMENTAIRES DOC-JavaDoc Chaque programme doit définir la documentation minimale associée à chaque entité. Applet : Exigé Standalone : Exigé Description L'utilitaire javadoc permet de générer une aide en ligne sous forme de pages HTML à partir de commentaires insérés dans le code. Il faut commenter le code en suivant les spécifications de javadoc. Cette règle présente la syntaxe minimale associée à l’usage de javadoc. Cet usage doit être précisé en début de Projet. On s’appuiera notamment sur les règles DOC-Dev, DOC-Version et DOC-Détail pour compléter la syntaxe obligatoire. Outre la présentation générale des fonctionnalités de chaque classe, méthode et attribut, les tags suivants doivent impérativement être utilisés quand ils sont pertinents : @author, @see, @param, @return et @exception. Les commentaires doivent être explicites et on utilisera si besoin le fait que javadoc autorise les commentaires de plusieurs lignes pour les 5 tags cités. Justification L'aide en ligne est standardisée ce qui facilite son utilisation ; on peut référencer par des liens hypertexte l'aide en ligne des classes Java. Cette règle permet de fournir le minimum d’informations nécessaires à la compréhension d’un programme. Exemple 1 : documentation minimale des classes /** * Semantique de la classe. * @see Classe ou methode pouvant servir de reference. * @see Autre classe pouvant servir de reference. * @author Auteur de la classe. */ // NB: @see ne sera utilise que si necessaire. Exemple 2 : documentation minimale des méthodes /** * Semantique de la méthode. * @param 1er parametre de methode. * @param 2eme parametre de methode. * @return valeur de retour. * @exception exception renvoyée. */ Exemple 3 : documentation minimale des attributs /** * Description de l’attribut. * @see Classe, méthode ou variable pouvant servir de reference. */ ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA Page 101 Version 4 10 décembre 2005 // NB: @see ne sera utilise que si necessaire. Exemple 4 : documentation du code // On utilise generalement les commentaire style C++ : "//". // Ceci décrit le contenu du bloc de code qui suit // ou encore de l’instruction qui figure sur la ligne suivante. int maVariable; //Ceci commente la déclaration d’une variable locale. Exemple 5 : documentation du code mort Le code mort n’est acceptable dans un programme que de façon temporaire. On utilisera de préférence les commentaires de style C pour mettre de coté un bloc de code temporairement non utilisé (ces commentaires pourront être retrouvés lors des revues de codes de manière à ne pas les laisser dans le logiciel final). /* */ // Test de debuggage : maVariable ne doit jamais depasser 32 bbp. if (maVariable >= 32) { System.out.println("Attention, la variable est superieure a 32 !"); } Exemples complémentaires /** * Utilisations du tag @see : * @see NomDeClasse * @see com.cnes.image.ConversionImage * @see com.cnes.image.ConversionImage#bmp2gif(File, File) */ // Utilisation du tag @exception /** * Calcul de la surface d’un rectangle. * * @param cote1 longueur du premier cote * @param cote2 longueur du second cote * @return la surface rectangle * @exception IllegalArgumentException IF (cote1 < 0 || cote2 < 0) Cette exception est levee si les dimensions du rectangle ne sont pas conformes (longueur < 0). */ public float calculerSurfaceRectangle(float cote1, float cote2) throws IllegalArgumentException { ... } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA DOC-Dev RNC-CNES-Q-80-527 Page 102 Version 4 10 décembre 2005 Les commentaires javadoc doivent être utilisés pendant les phases de développement. Applet : Recom. Standalone : Recom. Description javadoc propose un ensemble de tags permettant de tracer les évolutions du code lors des phases de développement. Le projet devra préciser les conditions d’utilisation de ces tags. Justification En utilisant les tags @bug, @review, @todo et @idea tout au long des phases de développement, on facilite grandement le suivi et la maintenance. Exemple // Le tag @bug peut etre utilise dans les entetes de classes, // inferfaces ou methodes. /** * Exemple de methode contenant un bug identifie. * @param variable Description de la variable. * @bug Explication du probleme connu et des cas d’utilisation dans lesquels il se manifeste. */ public methodeBuggee(Variable variable) { ... } // // // // Les tags @review, @todo et @idea peuvent etre utilises tout au long du code pour indiquer un probleme ou une amelioration a effectuer. Tous ces tags contiennent un nom d’utilisateur responsable des modifications a effectuer. // Exemples d’utilisation : /** * @review martinG La boucle de traitement peut etre optimisee. */ ... /** * @idea nadineM Ce probleme pourrait etre resolu de maniere plus elegante en utilisant l’algorithme de Viterbi. */ ... /** * @todo martinG Il faut implementer la mise a jour des attributs. */ ... ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA DOC-Version RNC-CNES-Q-80-527 Page 103 Version 4 10 décembre 2005 Les tags javadoc doivent être utilisés pour inclure les notions de gestion de configuration dans la documentation liée au code. Applet : Recom. Standalone : Recom. Description javadoc propose un ensemble de tags permettant de tracer les évolutions liées à la gestion de configuration. Le projet devra préciser les conditions d’utilisation de ces tags. Justification En utilisant les tags @version, @deprecated et @since tout au long des phases de développement, on facilite grandement le suivi et la maintenance. Exemple // // // // // Les tags @since et @version sont utilises de preference pour des classes ou des interfaces; ils indiquent la version correspondant a la creation de la classe et sa version actuelle. On pourra utiliser des tags geres automatiquement par les outils de gestion de configuration du projet (ex: $Id:$ avec RCS ou CVS) /** * Egalisation d’histogramme sur des images au format BMP. * * @author MartinG * @see com.cnes.image.EgalisationTIFF * @since TI-CNES v1.3 (05/03/97) * @version $Id:$ */ public class EgalisationBMP extends FiltrageFichierImage { ... } DOC-Détail Une bonne connaissance des formalismes javadoc est nécessaire. Applet : Recom. Standalone : Recom. Description Il faut bien connaître les potentialités de javadoc de manière à accroître la réutilisabilité de certains modules. Ainsi, lorsque le code est jugé complexe ou réutilisable, il faut compléter la syntaxe de base de la règle DOC-JavaDoc. Chaque projet définira les conditions précises associées au respect de cette règle. On pourra notamment définir les pré-conditions, les post-conditions et les problèmes de concurrence. Il est également fortement conseillé d’utiliser certains tags HTML. Justification Les tags @precondition ou @pre, @postcondition ou @post et @concurrency permettent de compléter la documentation des classes et de leurs méthodes. Le formatage HTML des commentaires permet d’améliorer la lisibilité de la documentation générée par javadoc. En respectant cette règle, on facilite donc le suivi et la maintenance. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 104 Version 4 10 décembre 2005 Exemple /** * Application du filtrage gaussien. * * Exemple d’utilisation : * <CODE> * ImageCouleur image = new ImageCouleur("nomFichier.img"); * FiltrageGaussien filtre = new FiltrageGaussien(); * filtre.setImage(image); * filtre.appliquer(); * </CODE> * * @precondition L’image de reference doit avoir ete definie. * @postcondition Le fichier image est ferme. * @concurrency SEQUENTIAL La methode ne peut pas etre utilisee en parallele. * public void appliquer() { ... } // Il est possible de formater n’importe quelle description avec // une syntaxe HTML identique a celle utilisee pour les pages Web. /** * On peut <em>par exemple</em> inserer une liste : * <ol> * <li> premier point ; * <li> deuxieme point ; * <li> troisieme point. * </ol> */ ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 105 Version 4 10 décembre 2005 15. CONVENTIONS DE NOMMAGE 15.1. GENERALITES La standardisation de la documentation du code est facilitée par l’existence de l’utilitaire javadoc et de la documentation en ligne sur les librairies de base de Java. STYLE-Langue Il faut choisir une langue en début de projet pour le nommage des entités et la documentation, donc les commentaires du code. Applet : Exigé Standalone : Exigé Justification Homogénéiser la langue utilisée amène à améliorer la cohérence globale de style. Exception Les langages objet, Java en particulier, facilitent la réutilisation du code. Dans ce contexte, si la langue de développement est le français, il faut prévoir des dérogations en faveur de l'anglais : en effet, on peut avoir besoin de surcharger certaines méthodes ou attributs dans des classes dérivées. Or, les librairies de base de Java sont programmées en anglais. De plus l'utilitaire javadoc génère des pages HTML à partir des commentaires insérés dans le code ; la structure de ces pages comporte des mots clé eux-mêmes en anglais ; de plus on peut accéder via des liens hypertexte à la documentation d'autres packages, par exemple ceux du langage Java, qui sont documentés en anglais. 15.2. REGLES DE NOMMAGE NOM-Défaut Par défaut, un nom d’élément Java commence par une minuscule et les différents champs sémantiques de ce nom prennent une majuscule qui sert de délimiteur. Applet : Exigé Standalone : Exigé Description Cette règle préconise d’utiliser le même principe pour créer les noms de tous les éléments utilisés dans un programme Java. Seul les noms de classes et de constantes seront construits de manière différente (Cf. NOM-Classe et NOM-Constante). Cette règle s’applique donc notamment aux variables locales, aux attributs de classe, aux paramètres formels des méthodes et aux noms des méthodes. Cette règle doit toujours être utilisée en adéquation avec la règle NOM-Explicite. Justification Cette notation est commune en Java et notamment utilisée par Sun. Le fait de construire de manière similaire les noms de tous les éléments d’un programme Java améliore la lisibilité des algorithmes implémentés. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 Page 106 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA Version 4 10 décembre 2005 Exemple int valeurNumeriqueEntiere; float resultatDuCalcul; double soldeCompte; soldeCompte = monClient.donnerSolde(referenceCompte, typeCompte); NOM-Classe Les noms de classe commencent par une majuscule ; les différents champs sémantiques du nom sont délimités par des majuscules. Applet : Exigé Standalone : Exigé Description Contrairement aux autres éléments d’un programme Java, les noms de classes commencent par une majuscule. Justification Cette notation est commune en Java et notamment utilisée par Sun. Le fait d’utiliser une notation particulière pour les noms de classes permet de les identifier plus facilement. Exemple Client client = new Client(); // Appel d’une methode publique de l’objet client. double solde = client.donnerSolde(); // Appel d’une methode statique de la Classe Client. double clef = Client.calculerClef(); NOM-Constante Les noms de constantes sont en majuscule. Applet : Exigé Standalone : Exigé Description Contrairement aux autres éléments d’un programme Java, les noms des constantes s’écrivent entièrement en majuscule. Justification Cette notation est commune en Java et notamment utilisée par Sun. Le fait d’utiliser une notation particulière pour les noms des constantes (variables final) permet de les identifier plus facilement. Exemple Class Calculateur { public final static int MAXIMUM = public final static int MINIMUM = public final static double ALPHA = private final static int TAILLETABLEAU = ... } ... monCalculateur.integrale(Calculateur.MAXIMUM); 100; -10; 3.4566757345675; 111; ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA NOM-AccèsAttribut RNC-CNES-Q-80-527 Page 107 Version 4 10 décembre 2005 Les méthodes d'accès aux attributs doivent être préfixées par get (accès en lecture), set (accès en écriture), is (renvoi d'une valeur booléenne). Applet : Exigé Standalone : Exigé Justification Cette notation est commune en Java et notamment utilisée par Sun. Le fait d’utiliser systématiquement ces préfixes facilite notamment la création ultérieure de JavaBeans. Exemple isString() isPersistent() getCompteEpargne() setCompteEpargne() NOM-Explicite Les noms d’éléments Java (variables, attributs, méthodes, …) doivent être explicites. Applet : Exigé Standalone : Exigé Description D’une façon générale, le nom d’un élément Java doit être significatif et permettre de comprendre immédiatement quel est son contenu et son usage. On évitera ainsi par exemple, les abréviations et les variables d’une seule lettre. Des règles de nommage pourront être mises en œuvre au niveau des classes pour préciser la catégorie de ces dernières (abstract, factory, exception, etc.). Les catégories pourront ainsi être spécifiées sous forme de préfixes ou de suffixes explicites. Justification L’application de cette règle permet d’améliorer notablement la lisibilité des fichiers sources. Il faut toujours avoir à l’esprit qu’un code source est bien plus souvent lu qu’il n’est écrit. Exemple incorrect // Init. for (i=0; i<nbI; i++) { for (j=0; j<nbC; j++) { for (k=0; k<nbL; k++) { tabI[i].tab[k][j] = i; } } } Exemple correct // Initialisation du tableau d’images. for (noImage = 0; noImage < nombreImages; noImage++) { for (noColonne = 0; noColonne < nombreColonnes; noColonne++) { for (noLigne = 0; noLigne < nombreLignes; noLigne++) { // // Les pixels prennent la valeur du numero de l’image associee. // tableauImages[noImage].pixels[noColonne][noLigne] = noImage; ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA } } RNC-CNES-Q-80-527 Page 108 Version 4 10 décembre 2005 } Exemple de règle de nommage Un projet d’infographie utilisant un nommage entièrement en anglais pourra par exemple donner à ses classes “ types ” les noms suivants : SceneFactory SceneInterface SceneImplementation NoMoreObjectException PickableInterface DrawableInterface Abstract3Dobject // // // // // // // Fabrique des scenes 3D. Service offert par une scene 3D. Implementation d’une scene 3D (Classe persistante). Exception levee par manque d’objets a visualiser. Services de manipulation a la souris. Services d’affichage. Tronc commun des objets 3D (classe abstraite). Alors que d’autres classes ne respectant par de design de conception particulier seront nommées : Cube Sphere PanelRenderer NOM-Widget // Objet 3D de forme cubique. // Objet 3D de forme spherique. // Panel de rendu d’une scene 3D. Les noms des widgets sont des noms de variables ; il faut de plus les préfixer ou les suffixer par leur classe. Applet : Exigé Standalone : Exigé Exemple okButton, fileMenu, clientMenuItem // anglais. buttonOk, menuFichier, menuItemClient // français. NOM-Package Le nom des packages doit indiquer leur localisation ou leur appartenance. Applet : Exigé Standalone : Exigé Justification Ceci permet d’obtenir une classification prenant en compte la localisation et l’appartenance de ces package. Exemple javax.swing java.security.interfaces org.omg.stub.java.rmi fr.capgemini.www.gestion.fichiers fr.cnes.qtis.egalisation.spot5 ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 109 Version 4 10 décembre 2005 15.3. DOCUMENTATION DOC-MiseEnPage Il faut définir une politique globale de mise en page. Applet : Exigé Standalone : Exigé Description L’ensemble des consignes liées au respect de cette règle devra être défini au démarrage du projet. On essayera au maximum d’appliquer les mêmes consignes à l’ensemble des projets. Nous recommandons à cet effet, d’utiliser le plus possible les usages préconisés par Sun (Cf. http://java.sun.com/codeconv/). Ces règles couvriront entre autre les conventions liées à l’indentation, le positionnement des accolades, l’utilisation des espaces, le positionnement et l’usage des commentaires et la largeur maximale des lignes de codes. Pour assurer un bon respect des règles de mise en page, il est souhaitable de créer des fichiers types (Templates) pour toutes les catégories de classe. En effet, en créant chaque nouvelle classe à partir d’un fichier de référence, on améliore la conformité avec l’ensemble des standards de codage (tout en simplifiant la tâche des développeurs). Justification En raison du fort potentiel de réutilisation de tous les programmes développés en Java, il est particulièrement important de définir un ensemble de règles de présentation des fichiers sources de manière à faciliter leur relecture et donc leur compréhension ultérieure. Précisons que la majeure partie des outils de développement Java peuvent être paramétrés pour adopter une mise en page particulière. Exemple de mise en page // // // // // Les exemples de ce document respectent tous les memes regles de positionnement des accolades, des parentheses et des espaces. L’indentation est de 4 caracteres. Pour eviter de surcharger le document, ils ne respectent pas tous les regles de commentaires de l’exemple suivant. Exemple de commentaires /* * Fichier : Blah.java * * Contenu de l’entete de fichier normalisee... * * Cette entete est utilisee pour l’ensemble d’une societe et * contient generalement les coordonnees de cette derniere. * * On trouve egalement dans l’entete les informations sur les * copyrights et eventuels brevets lies a l’utilisation des sources. * * On peut egalement y trouver des informations liees au projet. */ package java.blah; import java.blah.blahdy.BlahBlah; /** ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 110 Version 4 10 décembre 2005 * La description de la classe est effectuée ici. * * @version 1.82 18 Mar 1999 * @author NOM Prenom */ public class Blah extends UneClass { // ... Commentaire eventuel sur l’implementation de cette classe ... /** classVar1 commentaire documentaire */ public static int classVar1; /** * classVar2 commentaire documentaire qui doit * utiliser plus d’une ligne */ private static Object classVar2; /** instanceVar1 commentaire documentaire */ public Object instanceVar1; /** instanceVar2 commentaire documentaire */ protected int instanceVar2; /** instanceVar3 commentaire documentaire */ private Object[] instanceVar3; /** * constructeur Blah : commentaire documentaire. */ public Blah() { // ...l’implementation est ici... } /** * method faireCeci : commentaire documentaire ... */ public void faireCeci() { // ...l’implementation est ici... } } /** * ...method faireCela : commentaire documentaire ... * @param someParam description */ public void faireCela(Object someParam) { // ...l’implementation est ici... } ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 111 Version 4 10 décembre 2005 16. INDEX DES REGLES 16.1. INDEX DES REGLES PAR ORDRE ALPHABETIQUE Les règles sont données ci-dessous par ordre alphabétique : clé libellé Page APPLET-Animation Il est recommandé d’utiliser des threads dédiés pour réaliser des animations dans des applets. 56 APPLET-AppletAppli Il est recommandé de fournir les applets également sous forme d’application. 55 APPLET-Debugging Il est recommandé de déboguer les fonctionnalités d’une applet dans un appletviewer plutôt que dans un navigateur. 57 APPLET-MultiSynchro Ne pas s’appuyer sur un ordre de chargement a priori des différentes applets contenues dans une page HTML. 59 APPLET-StartStop On doit démarrer et arrêter les tâches de fond d’une applet dans les méthodes start() stop() respectivement. 56 APPLET-TagName Il faut toujours renseigner le paramètre NAME de la balise APPLET des fichiers HTML contenant une applet Java. 58 APPLET-TagParam Il faut utiliser la balise PARAM pour paramétrer les applets. 58 BEANS-Choix Il convient de choisir les composants que l’on désire transformer en JavaBeans. 53 BEANS-Notification Un composant JavaBean doit générer un événement lié à tout changement significatif de son aspect. 54 BEANS-Transient Toutes les données dont la sauvegarde n’est pas nécessaire doivent être déclarées transient. 53 CLASSE-Inner Il est recommandé de ne pas abuser des classes incluses non statiques. 25 CLASSE-InstanceOf Il est conseillé d’utiliser l’opérateur instanceOf avec parcimonie. 44 CLASSE-MembreStatic Il est recommandé de ne pas abuser des classes ou interfaces membres statiques. 24 CLASSE-MembreVis Il est interdit de modifier la visibilité des classes membre. 27 CLASSE-MéthAbstr Il faut préférer les méthodes abstraites aux méthodes de corps vide. 20 CLASSE-ProtégerDon Il ne faut pas déclarer des données membres public, sauf pour définir des constantes (public final static). 22 CLASSE-This Il faut utiliser la référence this à l’objet courant avec parcimonie. 37 CONCEP-Exterieur Il faut adapter le type d’interface avec l’extérieur aux besoins du projet. 98 CONCEP-Interface La notion d’interface Java doit être utilisée à bon escient 18 CONCEP-InterfEstUn La notion d’interface doit implémenter une relation conceptuelle “ est un ” ou la relation conceptuelle “ est une implémentation de ”. 17 CONCEP-IntInstance Une classe de base dont on veut interdire l’instanciation doit être définie comme une classe abstraite. 16 CONCEP-Ressources Il est recommandé d’utiliser les méthodes getProperty et setProperty. 99 CONSTR-But Il faut réserver les constructeurs aux tâches d’initialisation. 28 CONSTR-Retour Il ne faut pas définir de “ constructeur ” avec une valeur de CONTR-Break Tout branchement d’un choix multiple doit se terminer par l’instruction break. 41 CONTR-ConditionFor Il ne faut pas modifier la valeur de la condition de boucle for dans la boucle. 42 CONTR-Default Il faut prévoir le cas default dans un choix multiple switch. 41 CONTR-ParamFor Il ne faut pas modifier le paramètre de boucle for DESTR-Finalize Il est recommandé de ne pas redéfinir la méthode finalize(). retour. dans la boucle. 28 42 29 ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA clé Page 112 Version 4 10 décembre 2005 libellé Page DESTR-SuperFinalize En cas de redéfinition de la méthode finalize() on doit appeler super.finalize(). 29 DOC-Détail Une bonne connaissance des formalismes javadoc est nécessaire. 104 DOC-Dev Les commentaires javadoc doivent être utilisés pendant les phases de développement. 103 DOC-JavaDoc Chaque programme doit définir la documentation minimale associée à chaque entité. 101 DOC-MiseEnPage Il faut définir une politique globale de mise en page. 110 DOC-Version Les tags javadoc doivent être utilisés pour inclure les notions de gestion de configuration dans la documentation liée au code. 104 EXCEP-CatchUtil Une exception ne doit pas être récupérée par une fonction qui n’a pas les moyens de la traiter. 48 EXCEP-Error Il ne faut pas capter les exceptions de la classe Error. 47 EXCEP-RuntimeExcep Il est recommandé de ne pas explicitement propager les exceptions de la classe RuntimeException. 47 EXCEP-SousClasse Les exceptions du projet doivent être des sous-classes de la classe Exception. 45 EXCEP-Specifique Il ne faut pas manipuler directement les classes Exception et RunTimeException. 46 FORMA-PackBase Une connaissance correcte des packages java.lang, java.util et java.io est indispensable dès la conception. 95 FORMA-PackMetier Il faut engager dès le début du projet une réflexion sur la réutilisation. 97 FORMA-PackSpecif Il faut utiliser les packages standard adaptés au type d'application réalisée. 95 MAINT-AffectMask Aucune affectation ne doit être masquée par une autre opération. 32 MAINT-Const Il est recommandé d’utiliser des constantes pour représenter les nombres et les chaînes de caractères. 39 MAINT-Debug Il est conseillé d’introduire dans les classes développées les méthodes main() et toString(). 32 MAINT-Outil Il est fortement conseillé d’utiliser un outil de test du code. 33 MEM-RazRéférence Il faut remettre à null les références aux objets volumineux comme les tableaux. 31 MEM-TempsRéel Il ne faut pas utiliser Java pour les applications à forte contrainte temps réel. 31 METH-Final Il faut préfixer du mot clé final les méthodes dont on veut interdire la redéfinition. 35 METH-Protected Une méthode ne doit être protected que si elle doit être utilisée depuis au moins une méthode définie dans une autre classe de la sous-hiérarchie. 34 METH-Public Une méthode ne doit être public que si elle doit être utilisée depuis au moins une classe définie dans un autre package. 34 METH-Redéfinie Les définitions d’une fonction membre redéfinie entre une classe de base et une classe dérivée doivent comporter les mêmes noms de paramètres. 34 METH-Retour Il ne faut pas utiliser le retour fonctionnel pour la gestion des erreurs. 36 METH-Surcharge Les différentes surcharges d’une fonction doivent offrir des services ayant la même sémantique. 35 NOM-AccèsAttribut Les méthodes d'accès aux attributs doivent être préfixées par get (accès en lecture), set (accès en écriture), is (renvoi d'une valeur booléenne). 108 NOM-Classe Les noms de classe commencent par une majuscule ; les différents champs sémantiques du nom sont délimités par des majuscules. 107 NOM-Constante Les noms de constantes sont en majuscule. 107 NOM-Défaut Par défaut, un nom d’élément Java commence par une minuscule et les différents champs sémantiques de ce nom prennent une majuscule qui sert de délimiteur. 106 NOM-Explicite Les noms d’éléments Java (variables, attributs, méthodes, …) doivent être explicites. 108 NOM-Package Le nom des packages doit indiquer leur localisation ou leur appartenance. 109 NOM-Widget Les noms des widgets sont des noms de variables ; il faut de plus les préfixer ou les suffixer par leur classe. 109 ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA clé Page 113 Version 4 10 décembre 2005 libellé Page OPTIM-9010 Il faut d’abord déterminer correctement les parties à optimiser. 80 OPTIM-Access Il faut limiter l’implémentation des accesseurs (get/set/is) au minimum. 93 OPTIM-AccesVars Il faut utiliser des variables locales quand on le peut. 84 OPTIM-AlgoStructs Il est recommandé de réfléchir à l’optimisation de façon globale en termes d’algorithmes et de structures de données. 81 OPTIM-AppletJar Il est préférable de regrouper tous les composants d’une applet dans un fichier “ .jar ” unique. 93 OPTIM-BitSet L’utilisation de la classe BitSet est déconseillée. 91 OPTIM-Compilation Il est recommandé d’utiliser l’option de compilation optimisée de Java. 83 OPTIM-InvBoucle Il faut sortir des boucles leurs invariants. 83 OPTIM-Iteration Il faut réaliser les itérations avec l’interface Iterator. 92 OPTIM-List Il faut éviter d’utiliser la classe Vector et choisir le type de classe “liste” le plus adapté en fonction de l’algorithme. 88 OPTIM-Map Il faut éviter d’utiliser la classe Hashtable et choisir le type de classe “ données indexées ” en fonction 90 de l’application visée. OPTIM-Null Il est inutile de tester l’allocation des objets. 88 OPTIM-Productivité1 Il est recommandé d’utiliser de bons outils de développement. 82 OPTIM-Productivité2 Il faut utiliser la documentation de base fournie avec le JDK ou les IDEs pour améliorer la productivité de développement. 82 OPTIM-Set Il faut adapter le type de classe “ ensemble ” implémenté en fonction de l’application visée. 89 OPTIM-SousExpr Il faut éliminer les sous-expressions communes coûteuses en temps. 84 OPTIM-Strings Si une optimisation des performances sur la gestion des strings est nécessaire, il est recommandé d’utiliser la méthode append plutôt que l’opérateur +. 86 OPTIM-Synchro Il est recommandé de n’utiliser le mot-clef synchronized que si nécessaire. 87 ORGANI-Import Il faut expliciter les classes importées. 100 ORGANI-Package Un package doit être constitué d'un ensemble de classes formant un tout sémantique. 100 PORTAB-AppProperty Il ne faut jamais redéfinir des propriétés de l’application dépendantes de la plate-forme. 65 PORTAB-ConstPlat Il ne faut pas définir en dur des constantes dépendantes de la plate-forme. 63 PORTAB-DependAPI Il est recommandé de n’utiliser que les APIs Java officielles. 60 PORTAB-Deprecated Il ne faut pas utiliser les méthodes marquées comme Deprecated dans le JDK. 70 PORTAB-GetProperty Il est recommandé d’utiliser les propriétés portables de la plate-forme si besoin. 64 PORTAB-GUICapa On ne doit pas présumer des capacités graphiques des machines cibles. 67 PORTAB-GUIEvent On ne doit jamais utiliser le modèle événementiel du JDK 1.0.*. 69 PORTAB-GUIFonts Il ne faut pas coder en dur les polices de caractères utilisées. 67 PORTAB-GUIPaintGC Il ne faut pas enregistrer de Graphics à l’intérieur d’une instance. 68 PORTAB-GUISize On ne doit jamais fixer en dur la taille et/ou la position des widgets. 66 PORTAB-IHMStable1 Une classe graphique doit être “ stable ”. 72 PORTAB-IHMStable2 Si le constructeur d’une classe graphique peut être amené à échouer, une exception doit être levée. 73 PORTAB-InOutErr On ne doit pas dépendre des fichiers standards in, out et err. 65 PORTAB-JavaOfficiel On ne doit utiliser que la partie officielle des APIs utilisées. 61 PORTAB-Limit Les fonctionnalités non portables doivent être localisées dans une classe spécifique. 74 ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA clé Page 114 Version 4 10 décembre 2005 libellé Page PORTAB-Native On ne doit utiliser des méthodes natives qu’en cas de force majeure. 60 PORTAB-Swing Les classes swing doivent toujours être utilisées en priorité par rapport aux classes awt. 71 PORTAB-SystemCall Il est recommandé de ne pas appeler de méthode ouverte au système. 62 SECUR-Applet On doit sécuriser les applets Java. 76 SECUR-AppletTest On doit toujours tester les applets dans un navigateur. 77 SECUR-Application On doit sécuriser les applications Java standalone. 76 SECUR-CLASSPATH Il faut protéger particulièrement les packages standard Java. 78 SECUR-JavaFlaws Il faut connaître les problèmes de sécurité des outils Java utilisés. 79 SECUR-Obfuscator Encrypter le bytecode des applications ou des applets contenant du code “ confidentiel ”. 78 SPECS-Version Il faut s’assurer que la version des navigateurs utilisés supporte le JDK utilisé. 15 STYLE-Blocs Tous les blocs d’une instruction de contrôle doivent être délimités par des accolades. 43 STYLE-Langue Il faut choisir une langue en début de projet pour le nommage des entités et la documentation, donc les commentaires du code. 106 STYLE-Tableau Il faut déclarer les tableaux de façon uniforme. 39 THREAD-Création Il est recommandé d’utiliser l’interface java.lang.Runnable pour créer un thread. 50 THREAD-Daemon Les threads effectuant des traitements de fond doivent être définis comme des “ démons ”. 51 THREAD-Encapsuler Il est recommandé d’encapsuler la création d’un thread. 49 THREAD-SystemExit Il faut fermer les threads non “ démons ” avant d’appeler System.exit(). 52 VARLOC-Initialisation Il est recommandé d’initialiser les variables locales lors de leur déclaration. 39 VARLOC-Ligne Il faut dédier une ligne de code à chaque déclaration de variable locale. 37 VARLOC-Proximité Il est recommandé d’utiliser des déclarations de proximité. 38 VARLOC-Utilisation Il faut réserver chaque variable locale à une utilisation unique. 38 ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA RNC-CNES-Q-80-527 Page 115 Version 4 10 décembre 2005 16.2. INDEX DES REGLES APPLICABLES AUX APPLETS Les règles sont données ci-dessous par niveau d’applicabilité aux applets (Exigence, Recom) et par ordre alphabétique : R Page APPLET-Animation clé Il est recommandé d’utiliser des threads dédiés pour réaliser des animations dans des applets. libellé R 56 APPLET-AppletAppli Il est recommandé de fournir les applets également sous forme d’application. R 55 APPLET-Debugging Il est recommandé de déboguer les fonctionnalités d’une applet dans un appletviewer plutôt que dans un navigateur. R 57 APPLET-MultiSynchro Ne pas s’appuyer sur un ordre de chargement a priori des différentes applets contenues dans une page HTML. R 59 APPLET-StartStop On doit démarrer et arrêter les tâches de fond d’une applet dans les méthodes start() stop() respectivement. E 56 APPLET-TagName Il faut toujours renseigner le paramètre NAME de la balise APPLET des fichiers HTML contenant une applet Java. E 58 APPLET-TagParam Il faut utiliser la balise PARAM pour paramétrer les applets. E 58 BEANS-Choix Il convient de choisir les composants que l’on désire transformer en JavaBeans. R 53 BEANS-Notification Un composant JavaBean doit générer un événement lié à tout changement significatif de son aspect. E 54 BEANS-Transient Toutes les données dont la sauvegarde n’est pas nécessaire doivent être déclarées transient. E 53 CLASSE-Inner Il est recommandé de ne pas abuser des classes incluses non statiques. R 25 CLASSE-InstanceOf Il est conseillé d’utiliser l’opérateur instanceOf avec parcimonie. R 44 CLASSE-MembreStatic Il est recommandé de ne pas abuser des classes ou interfaces membres statiques. R 24 CLASSE-MembreVis Il est interdit de modifier la visibilité des classes membre. E 27 CLASSE-MéthAbstr Il faut préférer les méthodes abstraites aux méthodes de corps vide. E 20 CLASSE-ProtégerDon Il ne faut pas déclarer des données membres public, sauf pour définir des constantes (public final static). E 22 CLASSE-This Il faut utiliser la référence this à l’objet courant avec parcimonie. E 37 CONCEP-Exterieur Il faut adapter le type d’interface avec l’extérieur aux besoins du projet. E 98 CONCEP-Interface La notion d’interface Java doit être utilisée à bon escient E 18 CONCEP-InterfEstUn La notion d’interface doit implémenter une relation conceptuelle “ est un ” ou la relation conceptuelle “ est une implémentation de ”. E 17 CONCEP-IntInstance Une classe de base dont on veut interdire l’instanciation doit être définie comme une classe abstraite. E 16 CONCEP-Ressources Il est recommandé d’utiliser les méthodes getProperty et setProperty. R 99 CONSTR-But Il faut réserver les constructeurs aux tâches d’initialisation. R 28 CONSTR-Retour Il ne faut pas définir de “ constructeur ” avec une valeur de E 28 CONTR-Break Tout branchement d’un choix multiple doit se terminer par l’instruction break. E 41 CONTR-ConditionFor Il ne faut pas modifier la valeur de la condition de boucle for dans la boucle. R 42 CONTR-Default Il faut prévoir le cas default dans un choix multiple switch. E 41 CONTR-ParamFor Il ne faut pas modifier le paramètre de boucle for E 42 retour. dans la boucle. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA clé Page 116 Version 4 10 décembre 2005 R Page DESTR-Finalize Il est recommandé de ne pas redéfinir la méthode finalize(). libellé R 29 DESTR-SuperFinalize En cas de redéfinition de la méthode finalize() on doit appeler super.finalize(). E 29 DOC-Détail Une bonne connaissance des formalismes javadoc est nécessaire. R 104 DOC-Dev Les commentaires javadoc doivent être utilisés pendant les phases de développement. R 103 DOC-JavaDoc Chaque programme doit définir la documentation minimale associée à chaque entité. E 101 DOC-MiseEnPage Il faut définir une politique globale de mise en page. E 110 DOC-Version Les tags javadoc doivent être utilisés pour inclure les notions de gestion de configuration dans la documentation liée au code. R 104 EXCEP-CatchUtil Une exception ne doit pas être récupérée par une fonction qui n’a pas les moyens de la traiter. E 48 EXCEP-Error Il ne faut pas capter les exceptions de la classe Error. R 47 EXCEP-RuntimeExcep Il est recommandé de ne pas explicitement propager les exceptions de la classe RuntimeException. R 47 EXCEP-SousClasse Les exceptions du projet doivent être des sous-classes de la classe Exception. E 45 EXCEP-Specifique Il ne faut pas manipuler directement les classes Exception et RunTimeException. E 46 FORMA-PackBase Une connaissance correcte des packages java.lang, java.util et java.io est indispensable dès la conception. E 95 FORMA-PackMetier Il faut engager dès le début du projet une réflexion sur la réutilisation. E 97 FORMA-PackSpecif Il faut utiliser les packages standard adaptés au type d'application réalisée. E 95 MAINT-AffectMask Aucune affectation ne doit être masquée par une autre opération. E 32 MAINT-Const Il est recommandé d’utiliser des constantes pour représenter les nombres et les chaînes de caractères. R 39 MAINT-Debug Il est conseillé d’introduire dans les classes développées les méthodes main() et toString(). R 32 MAINT-Outil Il est fortement conseillé d’utiliser un outil de test du code. R 33 MEM-RazRéférence Il faut remettre à null les références aux objets volumineux comme les tableaux. E 31 METH-Final Il faut préfixer du mot clé final les méthodes dont on veut interdire la redéfinition. E 35 METH-Protected Une méthode ne doit être protected que si elle doit être utilisée depuis au moins une méthode définie dans une autre classe de la sous-hiérarchie. E 34 METH-Public Une méthode ne doit être public que si elle doit être utilisée depuis au moins une classe définie dans un autre package. E 34 METH-Redéfinie Les définitions d’une fonction membre redéfinie entre une classe de base et une classe dérivée doivent comporter les mêmes noms de paramètres. E 34 METH-Retour Il ne faut pas utiliser le retour fonctionnel pour la gestion des erreurs. E 36 METH-Surcharge Les différentes surcharges d’une fonction doivent offrir des services ayant la même sémantique. E 35 NOM-AccèsAttribut Les méthodes d'accès aux attributs doivent être préfixées par get (accès en lecture), set (accès en écriture), is (renvoi d'une valeur booléenne). E 108 NOM-Classe Les noms de classe commencent par une majuscule ; les différents champs sémantiques du nom sont délimités par des majuscules. E 107 NOM-Constante Les noms de constantes sont en majuscule. E 107 NOM-Défaut Par défaut, un nom d’élément Java commence par une minuscule et les différents champs sémantiques de ce nom prennent une majuscule qui sert de délimiteur. E 106 NOM-Explicite Les noms d’éléments Java (variables, attributs, méthodes, …) doivent être explicites. E 108 NOM-Package Le nom des packages doit indiquer leur localisation ou leur appartenance. E 109 ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA clé Page 117 Version 4 10 décembre 2005 libellé R Page NOM-Widget Les noms des widgets sont des noms de variables ; il faut de plus les préfixer ou les suffixer par leur classe. E 109 OPTIM-9010 Il faut d’abord déterminer correctement les parties à optimiser. E 80 OPTIM-Access Il faut limiter l’implémentation des accesseurs (get/set/is) au minimum. E 93 OPTIM-AccesVars Il faut utiliser des variables locales quand on le peut. R 84 OPTIM-AlgoStructs Il est recommandé de réfléchir à l’optimisation de façon globale en termes d’algorithmes et de structures de données. R 81 OPTIM-AppletJar Il est préférable de regrouper tous les composants d’une applet dans un fichier “ .jar ” unique. E 93 OPTIM-BitSet L’utilisation de la classe BitSet est déconseillée. R 91 OPTIM-Compilation Il est recommandé d’utiliser l’option de compilation optimisée de Java. R 83 OPTIM-InvBoucle Il faut sortir des boucles leurs invariants. R 83 OPTIM-Iteration Il faut réaliser les itérations avec l’interface Iterator. R 92 OPTIM-List Il faut éviter d’utiliser la classe Vector et choisir le type de classe “liste” le plus adapté en fonction de l’algorithme. R 88 OPTIM-Map Il faut éviter d’utiliser la classe Hashtable et choisir le type de classe “ données indexées ” en R 90 fonction de l’application visée. OPTIM-Null Il est inutile de tester l’allocation des objets. E 88 OPTIM-Productivité1 Il est recommandé d’utiliser de bons outils de développement. R 82 OPTIM-Productivité2 Il faut utiliser la documentation de base fournie avec le JDK ou les IDEs pour améliorer la productivité de développement. E 82 OPTIM-Set Il faut adapter le type de classe “ ensemble ” implémenté en fonction de l’application visée. R 89 OPTIM-SousExpr Il faut éliminer les sous-expressions communes coûteuses en temps. R 84 OPTIM-Strings Si une optimisation des performances sur la gestion des strings est nécessaire, il est recommandé d’utiliser la méthode append plutôt que l’opérateur +. R 86 OPTIM-Synchro Il est recommandé de n’utiliser le mot-clef synchronized que si nécessaire. R 87 ORGANI-Import Il faut expliciter les classes importées. R 100 ORGANI-Package Un package doit être constitué d'un ensemble de classes formant un tout sémantique. E 100 PORTAB-AppProperty Il ne faut jamais redéfinir des propriétés de l’application dépendantes de la plate-forme. E 65 PORTAB-ConstPlat Il ne faut pas définir en dur des constantes dépendantes de la plate-forme. E 63 PORTAB-DependAPI Il est recommandé de n’utiliser que les APIs Java officielles. R 60 PORTAB-Deprecated Il ne faut pas utiliser les méthodes marquées comme Deprecated dans le JDK. E 70 PORTAB-GetProperty Il est recommandé d’utiliser les propriétés portables de la plate-forme si besoin. R 64 PORTAB-GUICapa On ne doit pas présumer des capacités graphiques des machines cibles. E 67 PORTAB-GUIEvent On ne doit jamais utiliser le modèle événementiel du JDK 1.0.*. E 69 PORTAB-GUIFonts Il ne faut pas coder en dur les polices de caractères utilisées. E 67 PORTAB-GUIPaintGC Il ne faut pas enregistrer de Graphics à l’intérieur d’une instance. E 68 PORTAB-GUISize On ne doit jamais fixer en dur la taille et/ou la position des widgets. E 66 PORTAB-IHMStable1 Une classe graphique doit être “ stable ”. R 72 PORTAB-IHMStable2 Si le constructeur d’une classe graphique peut être amené à échouer, une exception doit être levée. E 73 PORTAB-InOutErr On ne doit pas dépendre des fichiers standards in, out et err. E 65 ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA clé Page 118 Version 4 10 décembre 2005 R Page PORTAB-JavaOfficiel On ne doit utiliser que la partie officielle des APIs utilisées. libellé E 61 PORTAB-Limit Les fonctionnalités non portables doivent être localisées dans une classe spécifique. E 74 PORTAB-Native On ne doit utiliser des méthodes natives qu’en cas de force majeure. E 60 PORTAB-Swing Les classes swing doivent toujours être utilisées en priorité par rapport aux classes awt. E 71 PORTAB-SystemCall Il est recommandé de ne pas appeler de méthode ouverte au système. R 62 SECUR-Applet On doit sécuriser les applets Java. E 76 SECUR-AppletTest On doit toujours tester les applets dans un navigateur. E 77 SECUR-CLASSPATH Il faut protéger particulièrement les packages standard Java. R 78 SECUR-JavaFlaws Il faut connaître les problèmes de sécurité des outils Java utilisés. E 79 SECUR-Obfuscator Encrypter le bytecode des applications ou des applets contenant du code “ confidentiel ”. R 78 SPECS-Version Il faut s’assurer que la version des navigateurs utilisés supporte le JDK utilisé. E 15 STYLE-Blocs Tous les blocs d’une instruction de contrôle doivent être délimités par des accolades. E 43 STYLE-Langue Il faut choisir une langue en début de projet pour le nommage des entités et la documentation, donc les commentaires du code. E 106 STYLE-Tableau Il faut déclarer les tableaux de façon uniforme. E 39 THREAD-Création Il est recommandé d’utiliser l’interface java.lang.Runnable pour créer un thread. E 50 THREAD-Encapsuler Il est recommandé d’encapsuler la création d’un thread. R 49 THREAD-SystemExit Il faut fermer les threads non “ démons ” avant d’appeler System.exit(). E 52 VARLOC-Initialisation Il est recommandé d’initialiser les variables locales lors de leur déclaration. R 39 VARLOC-Ligne Il faut dédier une ligne de code à chaque déclaration de variable locale. E 37 VARLOC-Proximité Il est recommandé d’utiliser des déclarations de proximité. R 38 VARLOC-Utilisation Il faut réserver chaque variable locale à une utilisation unique. E 38 ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA Page 119 Version 4 10 décembre 2005 16.3. INDEX DES REGLES APPLICABLES AUX APPLICATIONS STANDALONE Les règles sont données ci-dessous par niveau d’applicabilité aux applications standalone (Exigence, Recom) et par ordre alphabétique : S Page BEANS-Choix clé Il convient de choisir les composants que l’on désire transformer en JavaBeans. libellé R 53 BEANS-Notification Un composant JavaBean doit générer un événement lié à tout changement significatif de son aspect. E 54 BEANS-Transient Toutes les données dont la sauvegarde n’est pas nécessaire doivent être déclarées transient. E 53 CLASSE-Inner Il est recommandé de ne pas abuser des classes incluses non statiques. R 25 CLASSE-InstanceOf Il est conseillé d’utiliser l’opérateur instanceOf avec parcimonie. R 44 CLASSE-MembreStatic Il est recommandé de ne pas abuser des classes ou interfaces membres statiques. R 24 CLASSE-MembreVis Il est interdit de modifier la visibilité des classes membre. E 27 CLASSE-MéthAbstr Il faut préférer les méthodes abstraites aux méthodes de corps vide. E 20 CLASSE-ProtégerDon Il ne faut pas déclarer des données membres public, sauf pour définir des constantes (public final static). E 22 CLASSE-This Il faut utiliser la référence this à l’objet courant avec parcimonie. E 37 CONCEP-Exterieur Il faut adapter le type d’interface avec l’extérieur aux besoins du projet. E 98 CONCEP-Interface La notion d’interface Java doit être utilisée à bon escient E 18 CONCEP-InterfEstUn La notion d’interface doit implémenter une relation conceptuelle “ est un ” ou la relation conceptuelle “ est une implémentation de ”. E 17 CONCEP-IntInstance Une classe de base dont on veut interdire l’instanciation doit être définie comme une classe abstraite. E 16 CONCEP-Ressources Il est recommandé d’utiliser les méthodes getProperty et setProperty. R 99 CONSTR-But Il faut réserver les constructeurs aux tâches d’initialisation. R 28 CONSTR-Retour Il ne faut pas définir de “ constructeur ” avec une valeur de E 28 CONTR-Break Tout branchement d’un choix multiple doit se terminer par l’instruction break. E 41 CONTR-ConditionFor Il ne faut pas modifier la valeur de la condition de boucle for dans la boucle. R 42 CONTR-Default Il faut prévoir le cas default dans un choix multiple switch. E 41 CONTR-ParamFor Il ne faut pas modifier le paramètre de boucle for E 42 DESTR-Finalize Il est recommandé de ne pas redéfinir la méthode finalize(). R 29 DESTR-SuperFinalize En cas de redéfinition de la méthode finalize() on doit appeler super.finalize(). E 29 DOC-Détail Une bonne connaissance des formalismes javadoc est nécessaire. R 104 DOC-Dev Les commentaires javadoc doivent être utilisés pendant les phases de développement. R 103 DOC-JavaDoc Chaque programme doit définir la documentation minimale associée à chaque entité. E 101 DOC-MiseEnPage Il faut définir une politique globale de mise en page. E 110 DOC-Version Les tags javadoc doivent être utilisés pour inclure les notions de gestion de configuration dans la documentation liée au code. R 104 EXCEP-CatchUtil Une exception ne doit pas être récupérée par une fonction qui n’a pas les moyens de la traiter. E 48 EXCEP-Error Il ne faut pas capter les exceptions de la classe Error. R 47 retour. dans la boucle. ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA clé Page 120 Version 4 10 décembre 2005 S Page EXCEP-RuntimeExcep Il est recommandé de ne pas explicitement propager les exceptions de la classe RuntimeException. libellé R 47 EXCEP-SousClasse Les exceptions du projet doivent être des sous-classes de la classe Exception. E 45 EXCEP-Specifique Il ne faut pas manipuler directement les classes Exception et RunTimeException. E 46 FORMA-PackBase Une connaissance correcte des packages java.lang, java.util et java.io est indispensable dès la conception. E 95 FORMA-PackMetier Il faut engager dès le début du projet une réflexion sur la réutilisation. E 97 FORMA-PackSpecif Il faut utiliser les packages standard adaptés au type d'application réalisée. E 95 MAINT-AffectMask Aucune affectation ne doit être masquée par une autre opération. E 32 MAINT-Const Il est recommandé d’utiliser des constantes pour représenter les nombres et les chaînes de caractères. R 39 MAINT-Debug Il est conseillé d’introduire dans les classes développées les méthodes main() et toString(). R 32 MAINT-Outil Il est fortement conseillé d’utiliser un outil de test du code. R 33 MEM-RazRéférence Il faut remettre à null les références aux objets volumineux comme les tableaux. E 31 MEM-TempsRéel Il ne faut pas utiliser Java pour les applications à forte contrainte temps réel. E 31 METH-Final Il faut préfixer du mot clé final les méthodes dont on veut interdire la redéfinition. E 35 METH-Protected Une méthode ne doit être protected que si elle doit être utilisée depuis au moins une méthode définie dans une autre classe de la sous-hiérarchie. E 34 METH-Public Une méthode ne doit être public que si elle doit être utilisée depuis au moins une classe définie dans un autre package. E 34 METH-Redéfinie Les définitions d’une fonction membre redéfinie entre une classe de base et une classe dérivée doivent comporter les mêmes noms de paramètres. E 34 METH-Retour Il ne faut pas utiliser le retour fonctionnel pour la gestion des erreurs. E 36 METH-Surcharge Les différentes surcharges d’une fonction doivent offrir des services ayant la même sémantique. E 35 NOM-AccèsAttribut Les méthodes d'accès aux attributs doivent être préfixées par get (accès en lecture), set (accès en écriture), is (renvoi d'une valeur booléenne). E 108 NOM-Classe Les noms de classe commencent par une majuscule ; les différents champs sémantiques du nom sont délimités par des majuscules. E 107 NOM-Constante Les noms de constantes sont en majuscule. E 107 NOM-Défaut Par défaut, un nom d’élément Java commence par une minuscule et les différents champs sémantiques de ce nom prennent une majuscule qui sert de délimiteur. E 106 NOM-Explicite Les noms d’éléments Java (variables, attributs, méthodes, …) doivent être explicites. E 108 NOM-Package Le nom des packages doit indiquer leur localisation ou leur appartenance. E 109 NOM-Widget Les noms des widgets sont des noms de variables ; il faut de plus les préfixer ou les suffixer par leur classe. E 109 OPTIM-9010 Il faut d’abord déterminer correctement les parties à optimiser. E 80 OPTIM-Access Il faut limiter l’implémentation des accesseurs (get/set/is) au minimum. E 93 OPTIM-AccesVars Il faut utiliser des variables locales quand on le peut. R 84 OPTIM-AlgoStructs Il est recommandé de réfléchir à l’optimisation de façon globale en termes d’algorithmes et de structures de données. R 81 OPTIM-BitSet L’utilisation de la classe BitSet est déconseillée. R 91 OPTIM-Compilation Il est recommandé d’utiliser l’option de compilation optimisée de Java. R 83 OPTIM-InvBoucle Il faut sortir des boucles leurs invariants. R 83 ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ RNC-CNES-Q-80-527 REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA clé Page 121 Version 4 10 décembre 2005 libellé S Page OPTIM-Iteration Il faut réaliser les itérations avec l’interface Iterator. R 92 OPTIM-List Il faut éviter d’utiliser la classe Vector et choisir le type de classe “liste” le plus adapté en fonction de l’algorithme. R 88 OPTIM-Map Il faut éviter d’utiliser la classe Hashtable et choisir le type de classe “ données indexées ” en R 90 fonction de l’application visée. OPTIM-Null Il est inutile de tester l’allocation des objets. E 88 OPTIM-Productivité1 Il est recommandé d’utiliser de bons outils de développement. R 82 OPTIM-Productivité2 Il faut utiliser la documentation de base fournie avec le JDK ou les IDEs pour améliorer la productivité de développement. E 82 OPTIM-Set Il faut adapter le type de classe “ ensemble ” implémenté en fonction de l’application visée. R 89 OPTIM-SousExpr Il faut éliminer les sous-expressions communes coûteuses en temps. R 84 OPTIM-Strings Si une optimisation des performances sur la gestion des strings est nécessaire, il est recommandé d’utiliser la méthode append plutôt que l’opérateur +. R 86 OPTIM-Synchro Il est recommandé de n’utiliser le mot-clef synchronized que si nécessaire. R 87 ORGANI-Import Il faut expliciter les classes importées. R 100 ORGANI-Package Un package doit être constitué d'un ensemble de classes formant un tout sémantique. E 100 PORTAB-AppProperty Il ne faut jamais redéfinir des propriétés de l’application dépendantes de la plate-forme. E 65 PORTAB-ConstPlat Il ne faut pas définir en dur des constantes dépendantes de la plate-forme. E 63 PORTAB-DependAPI Il est recommandé de n’utiliser que les APIs Java officielles. R 60 PORTAB-Deprecated Il ne faut pas utiliser les méthodes marquées comme Deprecated dans le JDK. E 70 PORTAB-GetProperty Il est recommandé d’utiliser les propriétés portables de la plate-forme si besoin. R 64 PORTAB-GUICapa On ne doit pas présumer des capacités graphiques des machines cibles. E 67 PORTAB-GUIEvent On ne doit jamais utiliser le modèle événementiel du JDK 1.0.*. E 69 PORTAB-GUIFonts Il ne faut pas coder en dur les polices de caractères utilisées. E 67 PORTAB-GUIPaintGC Il ne faut pas enregistrer de Graphics à l’intérieur d’une instance. E 68 PORTAB-GUISize On ne doit jamais fixer en dur la taille et/ou la position des widgets. E 66 PORTAB-IHMStable1 Une classe graphique doit être “ stable ”. R 72 PORTAB-IHMStable2 Si le constructeur d’une classe graphique peut être amené à échouer, une exception doit être levée. E 73 PORTAB-InOutErr On ne doit pas dépendre des fichiers standards in, out et err. E 65 PORTAB-JavaOfficiel On ne doit utiliser que la partie officielle des APIs utilisées. E 61 PORTAB-Limit Les fonctionnalités non portables doivent être localisées dans une classe spécifique. E 74 PORTAB-Native On ne doit utiliser des méthodes natives qu’en cas de force majeure. E 60 PORTAB-Swing Les classes swing doivent toujours être utilisées en priorité par rapport aux classes awt. E 71 PORTAB-SystemCall Il est recommandé de ne pas appeler de méthode ouverte au système. R 62 SECUR-Application On doit sécuriser les applications Java standalone. E 76 SECUR-CLASSPATH Il faut protéger particulièrement les packages standard Java. R 78 SECUR-JavaFlaws Il faut connaître les problèmes de sécurité des outils Java utilisés. E 79 SECUR-Obfuscator Encrypter le bytecode des applications ou des applets contenant du code “ confidentiel ”. R 78 STYLE-Blocs Tous les blocs d’une instruction de contrôle doivent être délimités par des accolades. E 43 ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. METHODE ET PROCEDURE _______ REGLES ET RECOMMANDATIONS POUR L'UTILISATION DU LANGAGE JAVA clé RNC-CNES-Q-80-527 Page 122 Version 4 10 décembre 2005 S Page STYLE-Langue Il faut choisir une langue en début de projet pour le nommage des entités et la documentation, donc les commentaires du code. libellé E 106 STYLE-Tableau Il faut déclarer les tableaux de façon uniforme. E 39 THREAD-Création Il est recommandé d’utiliser l’interface java.lang.Runnable pour créer un thread. E 50 THREAD-Daemon Les threads effectuant des traitements de fond doivent être définis comme des “ démons ”. E 51 THREAD-Encapsuler Il est recommandé d’encapsuler la création d’un thread. R 49 THREAD-SystemExit Il faut fermer les threads non “ démons ” avant d’appeler System.exit(). E 52 VARLOC-Initialisation Il est recommandé d’initialiser les variables locales lors de leur déclaration. R 39 VARLOC-Ligne Il faut dédier une ligne de code à chaque déclaration de variable locale. E 37 VARLOC-Proximité Il est recommandé d’utiliser des déclarations de proximité. R 38 VARLOC-Utilisation Il faut réserver chaque variable locale à une utilisation unique. E 38 ______________________________________________________________________________________________________ Avant utilisation vérifier sur le serveur du RNC (http://rnc.cnes.fr) que la version utilisée est la version applicable. REFERENTIEL NORMATIF REALISE PAR : Centre National d’Etudes Spatiales Inspection Générale Direction de la Fonction Qualité 18 Avenue Edouard Belin 31401 TOULOUSE CEDEX 9 Tél. : 61 27 31 31 - Fax : 61 28 28 49 CENTRE NATIONAL D'ETUDES SPATIALES Siège social : 2 pl. Maurice Quentin 75039 Paris cedex 01 / Tel. (33) 01 44 76 75 00 / Fax : 01 44 46 76 76 RCS Paris B 775 665 912 / Siret : 775 665 912 00082 / Code APE 731Z