Académique Documents
Professionnel Documents
Culture Documents
2 Pratiques Générales 5
2.1 Style de code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.1.1 Indentation du code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.1.2 Accolades autour des structures de contrôles . . . . . . . . . . . . . . . . . . . . . 6
2.1.3 Éviter les opérateurs ternaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.1.4 Éviter les affectations dans les conditions des structures de controles . . . . . . . 8
2.2 Métriques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2.1 Longueur de classe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2.2 Longueur des méthodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.2.3 Nombre de paramètres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2.4 Nombre de champs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2.5 Nombre de méthodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.2.6 Complexité cyclomatique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.2.7 Complexité NPATH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.3 Codage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.3.1 Limiter autant que possible les instructions ❡"✉ ♥ par fonction . . . . . . . . . . . 19
2.3.2 Éviter les instructions "en cascade" . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.3.3 Éviter les instructions ❜ ❡❛❦ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.3.4 Éviter les instructions ❝♦♥"✐♥✉❡ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.3.5 Éviter les conditionnelles négatives . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.3.6 Remplacer les nombres et les chaînes par des constantes . . . . . . . . . . . . . 25
2.4 Règles de conception . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.4.1 Le patron de conception singleton . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.4.2 Substituer les instructions +✇✐"❝❤ par du polymorphisme . . . . . . . . . . . . . . 27
2.4.3 Éviter les champs protégés dans les classes ❢✐♥❛❧ . . . . . . . . . . . . . . . . . 29
2.5 Couplage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.5.1 Typer par des interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.6 Documentation du code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
2.6.1 Langue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
3 Java 33
3.1 Documentation du code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.1.1 Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.1.2 Methodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.1.3 Héritage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.1.4 Attributs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.2 Règles de conception et de codage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.2.1 Éviter les retours ♥✉❧❧ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.2.2 Éviter les passages de paramètres ♥✉❧❧ . . . . . . . . . . . . . . . . . . . . . . . . 38
3.2.3 La variable devrait être déclarée ❢✐♥❛❧ . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.2.4 Utiliser ArrayList au lieu de Vector . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.2.5 Utiliser StringBuilder au lieu de StringBuffer . . . . . . . . . . . . . . . . . . . . . . 42
3.2.6 Utiliser des énumérations en lieu et place des listes de constantes . . . . . . . . . 44
3.2.7 Éviter de proposer un attribut d’instance de visibilité publique . . . . . . . . . . . . 45
3.2.8 Éviter de qualifier la visibilité dans les interfaces . . . . . . . . . . . . . . . . . . . 46
3.2.9 Qualifier "public", "protected" et "private" les méthodes des classes . . . . . . . . . 47
2
TABLE DES MATIÈRES TABLE DES MATIÈRES
4 Java Enterprise 48
4.1 Traitement par lots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
4.1.1 Pré-allocation des séquences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
4.1.2 Utiliser ❤✐❜❡$♥❛'❡✳❥❞❜❝✳❜❛'❝❤❴-✐③❡ . . . . . . . . . . . . . . . . . . . . . . . . . 49
4.2 Logging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
4.2.1 Éviter le ♣$✐♥'❧♥✭✮ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
4.2.2 Éviter le ♣$✐♥'❙'❛❝❦❚$❛❝❡✭✮ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
4.2.3 Un logger par classe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
4.2.4 Bien logger un message en mode debug . . . . . . . . . . . . . . . . . . . . . . . 53
4.3 Couplage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
4.3.1 Utiliser Spring et l’inversion de contrôle . . . . . . . . . . . . . . . . . . . . . . . . 54
5 PHP 57
5.1 PHP Standards Recommendations (PSR) . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
5.1.1 PSR-1 : Basic Coding Standard . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
5.1.2 PSR-2 : Coding Style Guide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
5.1.3 PSR-4 : Autoloading Standard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
5.2 En vrac . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
5.2.1 Développer en ❊❴❆▲▲⑤❊❴❙❚❘■❈❚ . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
5.2.2 Utiliser les structures de contrôle du langage C . . . . . . . . . . . . . . . . . . . . 59
5.2.3 Ne pas utiliser les short open tags . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
5.2.4 Constructeurs PHP5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
5.2.5 Ne jamais utiliser de variables globales . . . . . . . . . . . . . . . . . . . . . . . . 62
5.2.6 Éviter les conversions implicites . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
5.2.7 Toujours initialiser ses variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
5.2.8 Concaténation d’une variable valeur ◆❯▲▲ . . . . . . . . . . . . . . . . . . . . . . . 65
5.2.9 Éviter l’appel de fonctions dans le corps dúne déclaration de boucle ❢♦$ . . . . . . 66
6 Python 67
6.1 Exécuter l’interpréteur avec l’option ✲'' . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Bibliographie 68
3
2 PRATIQUES GÉNÉRALES
2 Pratiques Générales
Cette partie du document s’intéresse aux règles transverses qui s’appliquent, peu ou proue, à tous
les langages objets.
5
2.1 Style de code 2 PRATIQUES GÉNÉRALES
Ceci permet d’éviter les problèmes avec les fichiers diff, les patches, l’historique CVS et les annota-
tions.
/∗
∗ Mauvaise p r a t i q u e
∗/
i f ( is E n a b l e d ( ) )
System . o u t . p r i n t l n ( " Enabled ! " ) ;
/∗
∗ Bonne p r a t i q u e
∗/
i f ( is E n a b l e d ( ) ) {
System . o u t . p r i n t l n ( " Enabled ! " ) ;
}
6
2.1 Style de code 2 PRATIQUES GÉNÉRALES
/∗
∗ Mauvaise p r a t i q u e
∗/
f i n a l I n t e g e r r e s u l t = ( isEnabled ( ) )
? getValidCode ( )
: ( isBusy ( ) )
? getBusyCode ( )
: getErrorCode ( ) ;
/∗
∗ Bonne p r a t i q u e
∗/
i f ( is E n a b l e d ( ) ) {
r e s u l t = getValidCode ( ) ;
} e l s e i f ( isBusy ( ) ) {
r e s u l t = getBusyCode ( ) ;
}
7
2.1 Style de code 2 PRATIQUES GÉNÉRALES
2.1.4 Éviter les affectations dans les conditions des structures de controles
Une règle simple, qui évite de nombreuses erreurs de programmation : éviter d’utiliser l’affectation
dans la condition d’une structure de controle [Wik16].
/∗
∗ Mauvaise p r a t i q u e ( j a v a )
∗/
p u b l i c void foo ( ) {
i n t a = 42;
i n t b = 0;
if ( ( a = b ) == 0 ) {
/ / skipped code !
}
}
/∗
∗ Bonne p r a t i q u e ( j a v a )
∗/
p u b l i c void foo ( ) {
i n t a = 42;
i n t b = 0;
a = b;
i f ( a == 0 ) {
/ / skipped code !
}
}
8
2.2 Métriques 2 PRATIQUES GÉNÉRALES
2.2 Métriques
Quelques mesures destinées à fournir des indicateurs de la qualité logicielle.
La limite communément admise est de 1000 lignes par classe grand maximum.
/∗
∗ Mauvaise p r a t i q u e ( j a v a )
∗/
p u b l i c c l a s s Foo {
/ / 2000 l i n e s o f code
}
/∗
∗ Bonne p r a t i q u e ( j a v a )
∗/
p u b l i c c l a s s Foo {
/ / 1000 l i n e s o f code
}
p u b l i c c l a s s Bar {
/ / 1000 l i n e s o f code
}
9
2.2 Métriques 2 PRATIQUES GÉNÉRALES
Restructurer votre code en créant, par exemple, d’autres méthodes ou d’autres classes d’une lon-
gueur raisonnable.
/∗
∗ Mauvaise p r a t i q u e ( j a v a )
∗/
/∗
∗ h t t p : / / pmd . s o u r c e f o r g e . n e t / [ . . . ] # ExcessiveMethodLength
∗/
p u b l i c v o i d doSomething ( ) {
/ / 200 c o p i e s o m i t t e d f o r b r e v i t y .
}
/∗
∗ Bonne p r a t i q u e ( j a v a )
∗/
p u b l i c v o i d doSomething ( ) {
/ / 100 c o p i e s o m i t t e d f o r b r e v i t y .
doSubRoutine ( ) ;
}
p u b l i c v o i d doSubRoutine ( ) {
/ / 100 c o p i e s o m i t t e d f o r b r e v i t y .
10
2.2 Métriques 2 PRATIQUES GÉNÉRALES
/∗
∗ Mauvaise p r a t i q u e ( j a v a )
∗
∗ h t t p : / / pmd . s o u r c e f o r g e . n e t / [ . . . ] # E x c e s s i v e P a r a m e t e r L i s t
∗/
p u b l i c c l a s s Foo {
p u b l i c v o i d addData (
i n t p0 , i n t p1 , i n t p2 , i n t p3 , i n t p4 , i n t p5 ,
i n t p5 , i n t p6 , i n t p7 , i n t p8 , i n t p9 , i n t p10 ) {
/∗
∗ method body
∗/
}
}
/∗
∗ Bonne p r a t i q u e ( j a v a )
∗/
p u b l i c c l a s s DataDto {
p r i v a t e i n t p0 ;
p r i v a t e i n t p1 ;
p r i v a t e i n t p2 ;
p r i v a t e i n t p3 ;
p r i v a t e i n t p4 ;
p r i v a t e i n t p5 ;
p r i v a t e i n t p6 ;
p r i v a t e i n t p7 ;
p r i v a t e i n t p8 ;
p r i v a t e i n t p9 ;
p r i v a t e i n t p10 ;
11
2.2 Métriques 2 PRATIQUES GÉNÉRALES
/∗
∗ 10 g e t t e r s and s e t t e r s o m i t t e d .
∗/
}
...
p u b l i c c l a s s Foo {
p u b l i c v o i d addData ( f i n a l DataDto d t o ) {
/∗
∗ method body
∗/
}
12
2.2 Métriques 2 PRATIQUES GÉNÉRALES
Il est possible d’utiliser des objets imbriqués qui groupent une partie de l’information. Par exemple,
une classe avec des champs ville / état / code postal pourrait, à la place, avoir un seul champ "Adresse".
/∗
∗ Mauvaise p r a t i q u e ( j a v a )
∗
∗ h t t p : / / pmd . s o u r c e f o r g e . n e t / [ . . . ] / codesize . h t m l #TooManyFields
∗/
p u b l i c c l a s s Person {
p r i v a t e S t r i n g one ;
p r i v a t e i n t two ;
private i n t three ;
/∗
∗ [ . . . many more p u b l i c f i e l d s ...]
∗/
/∗
∗ code o m i t t e d
∗/
}
/∗
∗ Bonne p r a t i q u e ( j a v a )
∗/
p u b l i c c l a s s Adresse {
/∗
∗ 3 g e t t e r s and 3 s e t t e r s o m i t t e d .
∗/
}
/∗
∗ h t t p : / / pmd . s o u r c e f o r g e . n e t / [ . . . ] / codesize . h t m l #TooManyFields
13
2.2 Métriques 2 PRATIQUES GÉNÉRALES
∗/
p u b l i c c l a s s Person {
p r i v a t e S t r i n g one ;
p r i v a t e i n t two ;
private i n t three ;
/∗
∗ [ . . . many more p u b l i c f i e l d s ...]
∗/
p r i v a t e Adresse adresse ;
/∗
∗ code o m i t t e d
∗/
}
14
2.2 Métriques 2 PRATIQUES GÉNÉRALES
Cela permet de réduire sa complexité et d’avoir des objets d’une granularité plus fine.
/∗
∗ Mauvaise p r a t i q u e ( j a v a )
∗/
p u b l i c c l a s s Foo
{
p u b l i c v o i d foo1 ( ) {
/ / code o m i t t e d
}
p u b l i c v o i d foo2 ( ) {
/ / code o m i t t e d
}
p u b l i c v o i d foo3 ( ) {
/ / code o m i t t e d
}
/∗
∗ 16 methods o m i t t e d
∗/
p u b l i c v o i d foo20 ( ) {
/ / code o m i t t e d
}
}
/∗
∗ Bonne p r a t i q u e ( j a v a )
∗/
p u b l i c c l a s s Foo
{
p u b l i c v o i d foo1 ( ) {
/ / code o m i t t e d
}
p u b l i c v o i d foo2 ( ) {
/ / code o m i t t e d
}
p u b l i c v o i d foo3 ( ) {
/ / code o m i t t e d
}
15
2.2 Métriques 2 PRATIQUES GÉNÉRALES
/∗
∗ 6 methods o m i t t e d
∗/
p u b l i c v o i d foo10 ( ) {
/ / code o m i t t e d
}
}
p u b l i c c l a s s Bar
{
p u b l i c v o i d bar1 ( ) {
/ / code o m i t t e d
}
p u b l i c v o i d bar2 ( ) {
/ / code o m i t t e d
}
p u b l i c v o i d bar3 ( ) {
/ / code o m i t t e d
}
/∗
∗ 6 methods o m i t t e d
∗/
p u b l i c v o i d bar10 ( ) {
/ / code o m i t t e d
}
}
16
2.2 Métriques 2 PRATIQUES GÉNÉRALES
Le seuil standard de cette métrique est de 10 points. Si vous avez une fonction avec une complexité
supérieure à 10, vous devez essayer de la réusiner.
1 p u b l i c f u n c t i o n example ( ) {
2 i f ( $a == $b ) {
3 i f ( $a1 == $b1 ) {
fiddle ();
4 } e l s e i f ( $a2 == $b2 ) {
fiddle ();
} else {
fiddle ();
}
5 } e l s e i f ( $c == $d ) {
6 w h i l e ( $c == $d ) {
fiddle ();
}
7 } e l s e i f ( $e == $ f ) {
8 f o r ( $n = 0 ; $n > $h ; $n ++) {
fiddle ();
}
} else {
s w i t c h ( $z ) {
9 case 1 :
fiddle ();
break ;
10 case 2 :
fiddle ();
break ;
11 case 3 :
fiddle ();
break ;
12 default :
fiddle ();
break ;
}
}
}
17
2.2 Métriques 2 PRATIQUES GÉNÉRALES
f u n c t i o n f o o ( $a , $b ) {
i f ( $a > 10) {
echo 1 ;
} else {
echo 2 ;
}
i f ( $a > $b ) {
echo 3 ;
} else {
echo 4 ;
}
}
La complexité NPath est exponentielle et peut facilement devenir incontrôlable, dans du vieux code.
Ne soyez pas surpris si vous trouvez des fonctions avec une complexité supérieure à 100 000. La valeur
par défaut du seuil de cette métrique est de 200. Vous devez rester sous cette valeur.
18
2.3 Codage 2 PRATIQUES GÉNÉRALES
2.3 Codage
Les règles présentées dans ce paragraphe ciblent l’écriture même du code dans sa logique intrin-
sèque.
2.3.1 Limiter autant que possible les instructions ❡"✉ ♥ par fonction
Dans l’idéal, une méthode/fonction ne devrait avoir qu’un et un seul point de sortie. Ce devrait être
sa dernière instruction.
L’instruction ❡"✉ ♥ fait partie des jump statements. Il y a 3 jump statements en java : ❝♦♥"✐♥✉❡,
❜ ❡❛❦ et ❡"✉ ♥. Ces instructions ont une action similaire à celle des instructions ❣♦"♦ des langages
BASIC ou Fortran : elles transfèrent le contrôle à un autre endroit du programme.
Cette règle fait partie des pratiques de développement dites de « programmation structurée » [ll14].
/∗
∗ Mauvaise p r a t i q u e ( Java ) .
∗/
p u b l i c c l a s s OneReturnOnly1 {
p u b l i c S t r i n g foo ( i n t x ) {
i f ( x > 0) {
r e t u r n " hey " ; / / oops , m u l t i p l e e x i t p o i n t s !
}
return " hi " ;
}
}
/∗
∗ Bonne p r a t i q u e ( Java ) .
∗/
p u b l i c c l a s s OneReturnOnly1 {
String result = " hi " ;
p u b l i c S t r i n g foo ( i n t x ) {
i f ( x > 0) {
r e s u l t = " hey " ;
}
return result ;
}
}
19
2.3 Codage 2 PRATIQUES GÉNÉRALES
Les piles d’appels et les erreurs de compilations sont bien souvent imprécises lorsqu’on ne respecte
pas cette règle.
Attention toutefois, cette règle est à adapter à votre contexte de programmation car il arrive que ce
style soit recommandé dans certains cas précis, p. ex. pour l’usage des StringBuilder ou des Stream en
Java.
Dans ce cas spécifique, il convient de veiller à respecter un strict retour à la ligne entre chaque appel
de méthode afin que les messages soient précis en cas d’erreurs.
/∗
∗ Mauvaise p r a t i q u e (PHP ) .
∗/
/∗
∗ Bonne p r a t i q u e (PHP ) .
∗
∗ Dans c e t exemple , chaque i n s t r u c t i o n e s t décomposée .
∗
∗ En cas d ’ e r r e u r s , l a p i l e d ’ appel e s t p r é c i s e .
∗/
$message = Swift_Message : : newInstance ( ) ;
$charset = s e l f : : $configs [ ’ charset ’ ] ;
$ p a r t = s t r i p _ t a g s ( $messageHtml ) ;
$message−>s e t C h a r s e t ( $ c h a r s e t ) ;
$message−>s e t S u b j e c t ( $ t h i s −>s u b j e c t ) ;
$message−>setFrom ( $assocAdressesFrom ) ;
$message−>setTo ( $assocAdressesTo ) ;
$message−>setBody ( $messageHtml , ’ t e x t / html ’ ) ;
$message−>addPart ( $ p a r t , ’ t e x t / p l a i n ’ ) ;
20
2.3 Codage 2 PRATIQUES GÉNÉRALES
/∗
∗ Mauvaise p r a t i q u e ( Java ) .
∗/
L i s t <EtablissementUna > r e s u l t s = ( L i s t <EtablissementUna >) s e s s i o n F a c t o r y
. getCurrentSession ( )
. createCriteria (
" f r . univbordeaux . [ . . . ] . EtablissementUna " )
. add ( c r e a t e ( i n s t a n c e ) ) . l i s t ( ) ;
/∗
∗ Bonne p r a t i q u e ( Java ) .
∗/
f i n a l Session = s e s s i o n F a c t o r y . g e t C u r r e n t S e s s i o n ( ) ;
f i n a l C r i t e r i a c r i t e r i a = session . c r e a t e C r i t e r i a (
" f r . univbordeaux . [ . . . ] . EtablissementUna " ) ;
f i n a l C r i t e r i o n c r i t e r i o n = create ( instance ) ;
c r i t e r i a . add ( c r i t e r i o n ) ;
f i n a l L i s t <EtablissementUna > r e s u l t s = c r i t e r i a . l i s t ( ) ;
21
2.3 Codage 2 PRATIQUES GÉNÉRALES
Cette règle fait partie des pratiques de développement dites de « programmation structurée » [ll14].
/∗
∗ Mauvaise p r a t i q u e ( Java ) .
∗/
f o r ( i n t i = 0 ; i <4; i ++)
{
i f ( i == 2 ) {
break ;
}
System . o u t . p r i n t l n ( " i = " + i ) ;
}
/∗
∗ Bonne p r a t i q u e ( Java ) .
∗/
f o r ( i n t i = 0 ; i < 2 ; i ++)
{
System . o u t . p r i n t l n ( " i = " + i ) ;
}
22
2.3 Codage 2 PRATIQUES GÉNÉRALES
Cette règle fait partie des pratiques de développement dites de « programmation structurée » [ll14].
f o r ( i n t i = 0 ; i <4; i ++)
{
i f ( i == 2 ) {
continue ;
}
System . o u t . p r i n t l n ( " i = " + i ) ;
}
f o r ( i n t i = 0 ; i <4; i ++)
{
i f ( i != 2) {
System . o u t . p r i n t l n ( " i = " + i ) ;
}
}
23
2.3 Codage 2 PRATIQUES GÉNÉRALES
/∗
∗ Mauvaise p r a t i q u e
∗/
if ( ! b u f f e r . shouldNotCompact ( ) )
/∗
∗ Bonne p r a t i q u e
∗/
i f ( b u f f e r . shouldCompact ( ) )
24
2.3 Codage 2 PRATIQUES GÉNÉRALES
En règle générale, les seuls nombres « en dur » que l’on peut trouver dans le code sont -1, 0, 1 et 2.
/∗
∗ Mauvaise p r a t i q u e ( Java ) .
∗/
/∗
∗ Bonne p r a t i q u e ( Java ) .
∗/
25
2.4 Règles de conception 2 PRATIQUES GÉNÉRALES
Il faut alors ajouter un constructeur ♣!✐✈❛%❡ (i.e. privé) pour éviter toute instanciation exterieure à
cette classe.
— cf. ❤%%♣✿✴✴♣♠❞✳-♦✉!❝❡❢♦!❣❡✳♥❡%✴!✉❧❡-✴❞❡-✐❣♥✳❤%♠❧★❯-❡❙✐♥❣❧❡%♦♥ .
— cf. ❤%%♣-✿✴✴♣♠❞✳❣✐%❤✉❜✳✐♦✴♣♠❞✲✺✳✹✳✶✴♣♠❞✲❥❛✈❛✴!✉❧❡-✴❥❛✈❛✴❞❡-✐❣♥✳❤%♠❧★❯-❡❯%✐❧✐%②❈❧❛-- .
p u b l i c c l a s s ShouldBeASingleton {
p u b l i c s t a t i c v o i d f o o ( ) { / / skipped code }
/ / Singleton classique .
p u b l i c c l a s s MySingleton
{
/ / Constructeur privé .
p r i v a t e MySingleton ( ) { }
/ / I n s t a n c e unique non p r é i n i t i a l i s é e .
p r i v a t e s t a t i c MySingleton INSTANCE = n u l l ;
i f ( INSTANCE == n u l l ) {
INSTANCE = new MySingleton ( ) ;
}
r e t u r n INSTANCE ;
}
/ / La méthode d ’ i n s t a n c e f o o ( ) .
p u b l i c void foo ( ) {
/ / skipped code .
}
/ / La méthode d ’ i n s t a n c e bar ( ) .
p u b l i c v o i d bar ( ) {
/ / skipped code .
}
}
26
2.4 Règles de conception 2 PRATIQUES GÉNÉRALES
Il s’agit de déplacer chaque composante de la condition dans une méthode surchargée au sein d’une
sous classe. On rend la méthode originelle abstraite.
/∗
∗ Java , mauvaise p r a t i q u e .
∗
∗ h t t p : / / sourcemaking . com / r e f a c t o r i n g / r e p l a c e −c o n d i t i o n a l −w i t h −polymorphism
∗/
double getSpeed ( ) {
s w i t c h ( _type ) {
case EUROPEAN:
r e t u r n getBaseSpeed ( ) ;
case AFRICAN :
r e t u r n getBaseSpeed ( ) − getLoadFactor ( ) ∗ _numberOfCoconuts ;
case NORWEGIAN_BLUE:
r e t u r n ( _ i s N a i l e d ) ? 0 : getBaseSpeed ( _ v o l t a g e ) ;
}
Le polymorphisme permet d’utiliser une même interface avec différentes implémentations. Il s’agit
de remplacer les instructions des différents cas fonctionnels, par des implémentations distinctes qui
mettent en oeuvre la même interface de programmation.
27
2.4 Règles de conception 2 PRATIQUES GÉNÉRALES
p u b l i c c l a s s European implements B i r d
{
p u b l i c double getSpeed ( ) {
r e t u r n getBaseSpeed ( ) ;
}
p u b l i c c l a s s A f r i c a n implements B i r d
{
p u b l i c double getSpeed ( ) {
r e t u r n getBaseSpeed ( ) − getLoadFactor ( ) ∗ numberOfCoconuts ;
}
}
p u b l i c c l a s s NorwegianBlue implements B i r d
{
p u b l i c double getSpeed ( ) {
i n t value = 0;
if ( ! isNailed ) {
v a l u e = getBaseSpeed ( v o l t a g e ) ;
}
r e t u r n value ;
}
}
p u b l i c double getSpeed ( t y p e ) {
f i n a l B i r d b i r d = map . g e t ( t y p e ) ;
r e t u r n b i r d . getSpeed ( ) ;
}
28
2.4 Règles de conception 2 PRATIQUES GÉNÉRALES
/∗
∗ Java , mauvaise p r a t i q u e .
∗/
p u b l i c f i n a l c l a s s Bar {
private int x ;
/∗
∗ Bar ne peut pas ê t r e sous classé , i l s ’ a g i t donc d ’ un
∗ champ p r i v a t e ou f r i e n d l y .
∗/
protected i n t y ;
Bar ( ) { }
}
/∗
∗ Java , bonne p r a t i q u e ( o p t i o n 1 )
∗/
p u b l i c f i n a l c l a s s Bar {
private int x ;
/∗
∗ Bar ne peut pas ê t r e sous classé ,
∗ on rend l e champ p r i v a t e .
∗/
private int y ;
Bar ( ) { }
}
29
2.4 Règles de conception 2 PRATIQUES GÉNÉRALES
/∗
∗ Java , bonne p r a t i q u e ( o p t i o n 2 )
∗
∗ On enlève l e m o d i f i e r f i n a l .
∗/
p u b l i c c l a s s Bar {
private int x ;
/∗
∗ Bar peut ê t r e sous classé ,
∗ on l a i s s e l e champ p r o t e c t e d .
∗/
protected i n t y ;
Bar ( ) { }
}
30
2.5 Couplage 2 PRATIQUES GÉNÉRALES
2.5 Couplage
Ces règles servent à réduire le couplage entre les différents composants des applications.
/∗
∗ Java , mauvaise p r a t i q u e .
∗
∗ h t t p : / / pmd . s o u r c e f o r g e . n e t / [ . . . ] # LooseCoupling
∗/
/ / sub−o p t i m a l approach
p r i v a t e A r r a y L i s t <Foo> l i s t = new A r r a y L i s t <Foo > ( ) ;
/∗
∗ Java , bonne p r a t i q u e .
∗
∗ h t t p : / / pmd . s o u r c e f o r g e . n e t / [ . . . ] # LooseCoupling
∗/
/ / p r e f e r r e d approach
p r i v a t e L i s t <Foo> l i s t = new A r r a y L i s t <Foo > ( ) ;
31
2.6 Documentation du code 2 PRATIQUES GÉNÉRALES
2.6.1 Langue
Il est conseillé d’écrire la documentation en anglais (ainsi que les noms des classes, des méthodes,
etc.) et ce, pour que le code puisse être repris par quiconque.
32
3 JAVA
3 Java
3.1 Documentation du code
3.1.1 Classes
La déclaration d’une classe doit être précédée d’un commentaire javadoc ou doxygen destiné à
expliquer son fonctionnement.
package f r . unicaen . r e a c t o r ;
/∗∗
∗ Une c l a s s e q u i met en oeuvre l e p a t r o n de c o n c e p t i o n « Reactor » a f i n de
∗ g é r e r l e s t r a i t e m e n t s a s s o c i é s aux évènements m é t i e r .
∗
∗ @author C h r i s t o p h e
∗ @see Handler
∗
∗ @param E l e t y p e d ’ évènement que l ’ on t r a i t e .
∗ @param T l e t y p e q u i i d e n t i f i e l e c a l l b a c k dans l e r e a c t e u r .
∗/
p u b l i c c l a s s Reactor <T , E>
{
/ / skipped code
}
33
3.1 Documentation du code 3 JAVA
3.1.2 Methodes
La déclaration d’une méthode, même privée, doit faire l’objet d’un commentaire explicite qui expose :
— Son fonctionnement, c’est à dire ce qu’elle fait ;
— Le type et le sens de chaque paramètre attendu ;
— Si la méthode est une fonction (et non une procédure), le commentaire doit exprimer le type
d’objet retourné et sa signification.
package f r . unicaen . r e a c t o r ;
/∗∗
∗ Une i n t e r f a c e pour l e s « c a l l b a c k s » du r e a c t e u r .
∗
∗ @author C h r i s t o p h e
∗
∗ @see Reactor
∗
∗ @param E l e t y p e d ’ évènement que l ’ on t r a i t e .
∗ @param T l e t y p e q u i i d e n t i f i e e l e c a l l b a c k .
∗/
p u b l i c i n t e r f a c e Handler <T , E>
{
/∗∗
∗ C e t t e méthode donne l e t y p e " i d e n t i f i a n t " q u i
∗ c a r a c t é r i s e c e t o b j e t au s e i n du r é a c t e u r .
∗
∗ @return l e t y p e sous forme de chaîne de c a r a c t è r e
∗/
T getHandlerType ( ) ;
/∗∗
∗ T r a i t e m e n t a s s o c i é au t y p e r e t o u r n é par l a méthode
∗ { @link # getHandlerType ( ) getHandlerType ( ) }
∗/
v o i d handleEvent (E event ) ;
}
34
3.1 Documentation du code 3 JAVA
3.1.3 Héritage
Pour la documentation des classes dérivées, on peut éviter la redondance des commentaires à l’aide
du tag javadoc ④❅✐♥❤❡&✐'❉♦❝⑥
package f r . unicaen . r e a c t o r ;
/∗∗
∗ Une i m p l e m e n t a t i o n de l ’ i n t e r f a c e Handler pour l e r e a c t o r .
∗
∗ @author C h r i s t o p h e
∗
∗ @see Reactor
∗ @see Handler
∗
∗ @see Caddie
∗
∗ @param E l e t y p e d ’ évènement que l ’ on t r a i t e .
∗ @param T l e t y p e q u i i d e n t i f i e l e c a l l b a c k dans l e r e a c t e u r .
∗/
p u b l i c c l a s s HandleTeddyBear implements Handler < S t r i n g , Caddie >
{
/∗∗
∗ Une c o n s t a n t e pour l a c l é ( T ) du r e a c t e u r .
∗/
p r i v a t e s t a t i c f i n a l S t r i n g TEDDY_BEAR_TYPE = " TeddyBear " ;
/∗∗
∗ { @inheritDoc }
∗/
@Override
p u b l i c S t r i n g getHandlerType ( ) {
r e t u r n TEDDY_BEAR_TYPE ;
}
/∗∗
∗ { @inheritDoc }
∗/
@Override
p u b l i c v o i d handleEvent ( Caddie caddie ) {
caddie . add ( new TeddyBear ( ) ) ;
}
}
35
3.2 Règles de conception et de codage 3 JAVA
3.1.4 Attributs
La déclaration d’un attribut ou d’une constante doit, en général, faire l’objet d’un commentaire java-
doc ou doxygen destiné à en expliciter la présence.
Il faut cependant éviter les commentaires qui paraphrasent le code. Auquel cas, il est préférable de
ne pas commenter l’attribut.
/∗∗
∗ Le l o g g e r l o g 4 j .
∗/
p r i v a t e s t a t i c f i n a l LOGGER = Logger . getLogger ( Reactor . c l a s s ) ;
/∗∗
∗ Map d e s t i n é e à r e c e v o i r l e s h a n d l e u r s .
∗/
p r i v a t e Map< S t r i n g , Caddie > h a n d l e r s = new HashedMap< S t r i n g , Caddie > ( ) ;
Si vous souhaitez retourner ♥✉❧❧, vous devriez lever une exception ou retourner un objet vide à la
place.
Si vous appelez une méthode d’une API tierce qui retourne ♥✉❧❧, il faut envelopper cette méthode
dans une autre méthode qui lève une exception ou retourne un objet vide.
Dans de nombreux cas, les objets vide sont des solutions pratiques.
/∗
∗ Clean Code , A Handbook o f A g i l e Software Craftsmanship
∗/
❣❡%❊♠♣❧♦②❡❡+✭✮ peut retourner ♥✉❧❧, mais le doit-il vraiment ? si on change ❣❡%❊♠♣❧♦②❡❡✭✮ afin qu’il
retourne une liste vide, on peut nettoyer le code ainsi :
36
3.2 Règles de conception et de codage 3 JAVA
/∗
∗ Clean Code , A Handbook o f A g i l e Software Craftsmanship
∗/
L’API java propose une méthode ❈♦❧❧❡❝%✐♦♥(✳❡♠♣%②▲✐(%✭✮ qui retourne une liste immuable prédé-
finie que l’on peut utiliser dans ce cas précis :
/∗
∗ Clean Code , A Handbook o f A g i l e Software Craftsmanship
∗/
p u b l i c L i s t <Employee> getEmployees ( ) {
i f ( . . t h e r e are no employees . . ) {
return Collections . emptyList ( ) ;
}
}
Si vous codez de cette manière, vous minimisez le risque ◆✉❧❧2♦✐♥%❡3❊①❝❡♣%✐♦♥ et le code est bien
meilleur.
37
3.2 Règles de conception et de codage 3 JAVA
38
3.2 Règles de conception et de codage 3 JAVA
De même, on ne réassigne jamais les paramètres d’une fonction. Ceux-ci devraient donc toujours
être notés ❢✐♥❛❧.
/∗
∗ Mauvaise p r a t i q u e Java
∗
∗ PMD example .
∗
h t t p : / / pmd . s o u r c e f o r g e . n e t / [ . . . ] # MethodArgumentCouldBeFinal
h t t p : / / pmd . s o u r c e f o r g e . n e t / [ . . . ] # L o c a l V a r i a b l e C o u l d B e F i n a l
∗/
p u b l i c c l a s s Bar {
p u b l i c v o i d foo1 ( S t r i n g param ) {
/∗
∗ do s t u f f w i t h param never a s s i g n i n g i t
∗/
/ / skipped code
}
p u b l i c void foo ( ) {
/∗
∗ i f t x t A and t x t B w i l l n o t be assigned again .
∗/
String txtA = "a " ;
String txtB = "b " ;
/ / skipped code
}
}
/∗
∗ Bonne p r a t i q u e Java
∗
∗ PMD example .
∗
h t t p : / / pmd . s o u r c e f o r g e . n e t / [ . . . ] # MethodArgumentCouldBeFinal
h t t p : / / pmd . s o u r c e f o r g e . n e t / [ . . . ] # L o c a l V a r i a b l e C o u l d B e F i n a l
39
3.2 Règles de conception et de codage 3 JAVA
∗/
p u b l i c c l a s s Bar {
p u b l i c v o i d foo2 ( f i n a l S t r i n g param ) {
/∗
∗ b e t t e r , do s t u f f w i t h param never a s s i g n i n g i t
∗/
/ / skipped code
}
p u b l i c void foo ( ) {
/∗
∗ I t i s b e t t e r t o do t h i s .
∗/
/ / skipped code
}
}
40
3.2 Règles de conception et de codage 3 JAVA
❆%%❛②▲✐+# est une meilleure implémentation de l’interface Collection si l’on ne travaille pas dans un
contexte concurrentiel.
On gagne en performances.
/∗
∗ Mauvaise p r a t i q u e ( Java )
∗
∗ On u t i l i s e V e c t o r dans un c o n t e x t non c o n c u r r e n t i e l .
∗/
f i n a l C o l l e c t i o n c1 = new V e c t o r ( ) ;
/ / skipped code
}
/∗
∗ Bonne p r a t i q u e ( Java )
∗
∗ On u t i l i s e A r r a y L i s t dans un c o n t e x t non c o n c u r r e n t i e l .
∗/
f i n a l C o l l e c t i o n c1 = new A r r a y L i s t ( ) ;
/ / skipped code
}
}
41
3.2 Règles de conception et de codage 3 JAVA
La classe ❙#$✐♥❣❇✉❢❢❡$ de l’API Java standard prend en charge les logiques d’exclusion mutuelle
propres aux accès concurrents des contextes concurrentiels. On dit qu’elle est thread-safe.
/∗
∗ Mauvaise p r a t i q u e ( Java )
∗
∗ On u t i l i s e += s u r une chaine de c a r a c t è r e .
∗/
p u b l i c c l a s s Foo {
p u b l i c v o i d bar ( ) {
String a;
/ / skipped code
42
3.2 Règles de conception et de codage 3 JAVA
/∗
∗ Mauvaise p r a t i q u e ( Java )
∗
∗ On u t i l i s e S t r i n g B u f f e r dans un c o n t e x t e non c o n c u r r e n t i e l .
∗/
p u b l i c c l a s s Foo {
p u b l i c v o i d bar ( ) {
f i n a l S t r i n g B u f f e r b u f f e r = new S t r i n g B u f f e r ( ) ;
/ / skipped code
/∗
∗ Bonne p r a t i q u e ( Java )
∗
∗ On u t i l i s e S t r i n g B u i l d e r dans un c o n t e x t e non c o n c u r r e n t i e l .
∗/
p u b l i c c l a s s Foo {
p u b l i c v o i d bar ( ) {
f i n a l S t r i n g B u i l d e r b u i l d e r = new S t r i n g B u i l d e r ( ) ;
/ / skipped code
}
43
3.2 Règles de conception et de codage 3 JAVA
/∗
∗ Mauvaise p r a t i q u e j a v a .
∗/
p u b l i c s t a t i c f i n a l c l a s s CaddyItemTypes {
p u b l i c s t a t i c f i n a l S t r i n g BEAR = " Bear " ;
p u b l i c s t a t i c f i n a l S t r i n g RABBIT = " R a b b i t " ;
}
/∗
∗ Bonne p r a t i q u e j a v a .
∗/
p u b l i c enum CaddyItemType {
p r i v a t e S t r i n g value ;
p r i v a t e CaddyItemType ( S t r i n g v a l u e ) {
t h i s . value = value ;
}
p u b l i c S t r i n g getValue ( ) {
r e t u r n value ;
}
}
44
3.2 Règles de conception et de codage 3 JAVA
L’usage du qualifier "protected" est controversé car les classes qui héritent peuvent avoir besoin
d’accéder au champ de la super classe.
Toutefois, il ne faut pas oublier qu’un qualifier "protected" autorise les classes du paquetage à accé-
der au champ, ce qui est finalement très ouvert.
La pratique courante est de protéger les champs à l’aide du qualifier "private" et de proposer, au cas
par cas, des méthodes dites getters et setters pour y accéder si besoin est.
La classe est alors garante de l’intégrité de ses données. Il s’agit du concept d’encapsulation.
45
3.2 Règles de conception et de codage 3 JAVA
Il s’agit d’un type très abstrait qui ne contient que le strict nécessaire à la mise en oeuvre ultérieure
par des classes dérivées.
Java autorise, pour chaque méthode abstraite de déclarer (ou non) sa visibilité. Il s’agit conceptuelle-
ment d’un détail d’implémentation qui est souvent considéré comme inutile pour la lecture des interfaces
de programmation.
/∗
∗ Java , mauvaise p r a t i q u e
∗/
p u b l i c i n t e r f a c e Bear
{
p u b l i c v o i d e a t ( Salmon salmon ) ;
p u b l i c v o i d walkAlong ( R i v e r r i v e r ) ;
}
/∗
∗ Java , bonne p r a t i q u e
∗/
p u b l i c i n t e r f a c e Bear
{
/ / le q u a l i f i e r public disparait , i l
/ / sera d é c l a r é dans l a c l a s s e d é r i v é .
v o i d e a t ( Salmon salmon ) ;
v o i d walkAlong ( R i v e r r i v e r ) ;
}
46
3.2 Règles de conception et de codage 3 JAVA
Il est préférable d’expliciter clairement la visibilité des méthodes de chaque classe parmi les 3 quali-
fiers suivants :
— public ;
— private ;
— protected.
47
4 JAVA ENTERPRISE
4 Java Enterprise
4.1 Traitement par lots
4.1.1 Pré-allocation des séquences
Les générateurs d’identifiants de JPA et d’hibernate utilisent par défaut une pré-allocation de sé-
quence de taille 1[Sut11].
Dans cette configuration, chaque instruction ✐♥"❡$% ou ✉♣❞❛%❡ provoque l’appel à une autre instruc-
tion "❡❧❡❝% qui sert à récupérer la nouvelle valeur de la séquence.
En conséquence, les accès sont doublés en base de données lors des traitements par lots.
Cette configuration est excessive. Si l’on modifie ce critère pour 500 ou 1000, on réduit de moitié les
accès dans les procédures de traitement par lots.
Les identifiants ne sont cependant plus contigus en base, mais les performances sont au rendez-
vous.
< h i b e r n a t e −mapping>
< c l a s s name=" f r . univbordeaux . [ . . . ] . I n d i v i d u U n a "
t a b l e =" i n d i v i d u _ u n a " >
<!−−
− A l l o c a t i o n S i z e v a u t maintenant 1000.
−−>
<param name=" a l l o c a t i o n S i z e " >1000 </param>
</ g e n e r a t o r >
</ i d >
...
</ c l a s s >
</ h i b e r n a t e −mapping>
48
4.2 Logging 4 JAVA ENTERPRISE
Les nouvelles instances sont insérées dans le cache de second niveau[Doc14a] ce qui provoque
généralement une ❖✉'❖❢▼❡♠♦$②❊①❝❡♣'✐♦♥ aux alentours du 50 000 ème objet traité.
On configure donc le framework afin qu’il place les objets dans le cache de premier niveau et ce,
avec une fenêtre raisonnable (10-50)
h i b e r n a t e . j d b c . b a t c h _ s i z e 20
Lorsque vous rendez de nouveaux objets persistants ou lorsque vous les mettez à jour, vous devez
régulièrement appeler ❢❧✉-❤✭✮ et puis ❝❧❡❛$✭✮ sur la session, pour contrôler la taille du cache de
premier niveau[Doc14a].
Session s e s s i o n = s e s s i o n F a c t o r y . openSession ( ) ;
Transaction t x = session . beginTransaction ( ) ;
i f ( i % 20 == 0 ) {
/∗
∗ 20 , same as t h e JDBC batch s i z e
∗
∗ f l u s h a batch o f i n s e r t s and r e l e a s e memory :
∗/
session . f l u s h ( ) ;
session . c l e a r ( ) ;
}
t x . commit ( ) ;
session . close ( ) ;
4.2 Logging
4.2.1 Éviter le ♣$✐♥'❧♥✭✮
Dans les applications d’entreprise, il convient d’éviter les instructions de type ❙②-'❡♠✳♦✉'✳♣$✐♥'❧♥✭✮ .
Il est préférable d’utiliser un logger [Gri14].
49
4.2 Logging 4 JAVA ENTERPRISE
/∗
∗ Java , mauvaise p r a t i q u e
∗/
c l a s s Foo {
/∗∗
∗ Corps de l a f o n c t i o n .
∗/
public void testA ( ) {
System . o u t . p r i n t l n ( " E n t e r i n g t e s t " ) ;
}
}
/∗
∗ Java , bonne p r a t i q u e
∗/
c l a s s Foo {
/∗∗
∗ Le l o g g e r l o g 4 j .
∗/
p u b l i c s t a t i c f i n a l Logger LOGGER = Logger . getLogger ( Foo . c l a s s . getName ( ) ) ;
/∗∗
∗ Corps de l a f o n c t i o n .
∗/
public void testA ( ) {
/ / B e t t e r use t h i s
LOGGER. f i n e ( " E n t e r i n g t e s t " ) ;
}
}
50
4.2 Logging 4 JAVA ENTERPRISE
p u b l i c c l a s s Foo {
/∗
∗ Java e n t e r p r i s e , mauvaise p r a t i q u e .
∗/
/∗∗
∗ Corps de l a f o n c t i o n .
∗/
p u b l i c v o i d bar ( ) {
try {
/ / do something
}
catch ( f i n a l Exception e ) {
e . printStackTrace ( ) ;
}
}
/∗
∗ Java , bonne p r a t i q u e .
∗/
p u b l i c c l a s s Foo {
/∗∗
∗ Le l o g g e r l o g 4 j .
∗/
p r i v a t e s t a t i c f i n a l Logger LOGGER = Logger . getLogger ( Foo . c l a s s . getName ( ) ) ;
/∗∗
∗ Corps de l a f o n c t i o n .
∗/
p u b l i c v o i d bar ( ) {
try {
/ / do something
}
catch ( f i n a l Exception e ) {
LOGGER. e r r o r ( " Uncaught e x c e p t i o n " , e ) ;
}
}
}
51
4.2 Logging 4 JAVA ENTERPRISE
/∗
∗ Java , bonne p r a t i q u e .
∗/
p u b l i c c l a s s Foo {
/∗∗
∗ Le l o g g e r l o g 4 j .
∗/
p r i v a t e s t a t i c f i n a l Logger LOGGER = Logger . getLogger (
Foo . c l a s s . getName ( )
);
/ / skipped code
}
52
4.2 Logging 4 JAVA ENTERPRISE
/∗
∗ Java , bonne p r a t i q u e .
∗/
p u b l i c c l a s s Foo {
/∗∗
∗ Le l o g g e r l o g 4 j .
∗/
p r i v a t e s t a t i c f i n a l Logger LOGGER = Logger . getLogger (
Foo . c l a s s . getName ( )
);
/∗∗
∗ f u n c t i o n body .
∗/
p u b l i c v o i d bar ( f i n a l S t r i n g name ) {
i f (LOGGER. isDebugEnabled ( ) ) {
f i n a l S t r i n g B u i l d e r b u i l d e r = new S t r i n g B u i l d e r ( ) ;
f i n a l S t r i n g message = b u i l d e r . t o S t r i n g ( ) ;
53
4.3 Couplage 4 JAVA ENTERPRISE
4.3 Couplage
4.3.1 Utiliser Spring et l’inversion de contrôle
Spring est un conteneur léger d’application javaee. Il prend en charge l’instanciation des objets à
l’aide d’un patron de conception qui réduit le couplage entre les classes : l’inversion de contrôle (IOC,
Inversion Of Control).
L’inversion de contrôle remplace l’instanciation des dépendances par une injection de celles-ci à
l’aide d’un framework, en l’occurence, spring.
Exemple : nous avons une dépendance directe d’une classe A vers une classe B.
Il s’agit d’introduire un typage par interfaces afin de réduire le couplage entre les classes A et B.
La classe A ne dépend donc plus de B directement, mais de I qui peut être implémenté par n’importe
quelle autre classe.
public interface I
{
v o i d executeMethod ( ) ;
54
4.3 Couplage 4 JAVA ENTERPRISE
public class A
{
p r i v a t e I dependanceI ;
public A() {
}
p u b l i c A ( f i n a l I dependanceI ) {
t h i s . dependanceI = dependanceI ;
}
p u b l i c v o i d setDependanceI ( f i n a l I dependanceI ) {
t h i s . dependanceI = dependanceI ;
}
p u b l i c v o i d process ( ) {
dependanceI . executeMethod ( ) ;
}
p u b l i c c l a s s B implements I
{
public B() {
}
p u b l i c v o i d executeMethod ( ) {
/ / skipped code
}
55
4.3 Couplage 4 JAVA ENTERPRISE
</ beans>
56
5 PHP
5 PHP
Pratiques qui s’intéressent, quasi exclusivement, à la programmation en PHP.
Par nature, PHP est complaisant et permissif avec de nombreuses pratiques. Il convient de prendre
quelques habitudes pour rendre le code moins complexe à analyser et éviter des problèmes de sécurité.
Dans ce processus, l’éditeur ou les éditeurs d’une proposition sont essentiellements les contribu-
teurs principaux qui ont écrit la PSR et ils sont appuyés par 2 membres qui votent. Les membres qui
votent sont le coordinateur (qui est responsable du pilotage de l’étape de relecture "Review") ainsi qu’un
second membre dit "Sponsor".
L’objectif est de reduire la friction cognitive qui résulte de l’analyse des codes de différents auteurs.
On y arrive en partageant un ensemble de règles et d’attentes sur la manière dont doit etre formaté le
code PHP.
Le style des règles présentées ici sont dérivées des points communs relatifs à un certain nombre de
projets. Quand divers auteurs collaborent sur plusieurs projets, il est utile d’avoir un ensemble de lignes
directrices qu’il convient de respecter sur ces projets. C’est pourquoi les bénéfices de cette norme n’est
pas dans le contenu des règles, en tant que telles, mais dans le partage de celles-ci.
57
5.2 En vrac 5 PHP
5.2 En vrac
Des règles en vrac, relevées de manière empiriques.
/∗
∗ Bonne p r a t i q u e de développement : u t i l i s e r E_STRICT
∗/
e r r o r _ r e p o r t i n g ( E_ALL | E_STRICT ) ;
On peut, dans ce cas, forcer le mode ❊❴❆▲▲ ⑤ ❊❴❙❚❘■❈❚ dans un fichier ✳❤!❛❝❝❡-- de la manière
suivante :
php_value e r r o r _ r e p o r t i n g 4095
On peut également ajouter les paramètres de configuration suivants pour forcer l’affichage d’un
maximum d’informations.
php_flag d i s p l a y _ e r r o r s On
php_flag t r a c k _ e r r o r s On
php_flag h t m l _ e r r o r s On
php_flag report_memleaks On
php_flag d i s p l a y _ s t a r t u p _ e r r o r s On
php_flag l o g _ e r r o r s On
58
5.2 En vrac 5 PHP
Les structures de contrôle du langage C sont reprises par les langages C, Java, C# et C++. De ce
fait, elles sont familières pour la plupart des développeurs. Les structures de contrôle en style BASIC
sont à éviter.
/∗
∗ Mauvaise p r a t i q u e : é c r i r e l e s s t r u c t u r e s de c o n t r ô l e dans
∗ l e s t y l e du langage BASIC .
∗/
i f ( $a == 5 ) :
echo " a e s t é g a l à 5 " ;
echo " . . . " ;
else :
echo " a n ’ e s t pas é g a l à 5 " ;
endif ;
/∗
∗ Bonne p r a t i q u e : é c r i r e l e s s t r u c t u r e s de c o n t r ô l e dans l e s t y l e
∗ du langage C .
∗/
i f ( $a == 5 ) {
echo " a e s t é g a l à 5 " ;
echo " . . . " ;
}
else {
echo " a n ’ e s t pas é g a l à 5 " ;
}
59
5.2 En vrac 5 PHP
<?
/∗
∗ Mauvaise p r a t i q u e (PHP)
∗/
<?php
/∗
∗ Bonne p r a t i q u e (PHP)
∗/
?>
60
5.2 En vrac 5 PHP
Les conventions de nommage de PHP4 sont toujours supportées pour des raisons de compatibilité
ascendante.
Elles sont cependant déconseillées (dépréciées) dans la documentation de PHP.
/∗
∗ Mauvaise p r a t i q u e (PHP)
∗/
c l a s s DBConnect
{
/∗∗
∗ C o n s t r u c t e u r par d é f a u t .
∗
∗ C o n s t r u i t une i n s t a n c e de DBConnect .
∗/
p u b l i c DBConnect ( ) {
/∗
∗ Bonne p r a t i q u e (PHP)
∗/
c l a s s DBConnect
{
/∗∗
∗ C o n s t r u c t e u r par d é f a u t .
∗
∗ C o n s t r u i t une i n s t a n c e de DBConnect .
∗/
public __construct ( ) {
61
5.2 En vrac 5 PHP
Le code s’en trouve plus simple et plus propre. C’est une aide pour son débugage, sa relecture et sa
pérénité.
D’une manière générale, lorsque le mot clé ❣❧♦❜❛❧ est utilisé, on considère suspect le code et on
procède à une opération de réusinage pour le corriger.
62
5.2 En vrac 5 PHP
C’est notamment le cas si l’on additionne une chaîne de caractères (qui représente un entier) avec
un entier. La valeur de la chaîne de caractères est alors extraite puis convertie en entier.
Le développeur distrait n’a plus conscience du type de données qu’il manipule ! On prèfère évidem-
ment une conversion explicite de type.
/∗
∗ Mauvaise p r a t i q u e (PHP)
∗/
/∗
∗ $groupe [ ’ count_etapes ’ ] e s t une chaîne de c a r a c t è r e
∗ q u i r e p r é s e n t e un e n t i e r .
∗
∗ On cherche i c i à s a v o i r s i c e t t e v a l e u r e s t s u p é r i e u r e à zéro .
∗
∗ I l f a u t l a c o n v e r t i r en e n t i e r pour p o u v o i r t e s t e r sa
∗ v a l e u r numérique .
∗/
$count_etapes = $groupe [ ’ count_etapes ’ ]
i f ( ( $count_etapes + 0 ) > 0 ) {
...
}
/∗
∗ Bonne p r a t i q u e (PHP)
∗/
/∗
∗ Pour c o n v e r t i r $count_etapes en e n t i e r , i l e s t p r é f é r a b l e
∗ d ’ utiliser l ’ instruction intval ().
∗/
$count_etapes = i n t v a l ( $groupe [ ’ count_etapes ’ ] ) ;
i f ( $count_etapes > 0 ) {
...
}
63
5.2 En vrac 5 PHP
Le développeur paresseux peut être heureux car PHP va automatiquement déclarer ces variables
pour lui. Charge au relecteur de trouver s’il s’agit ou non d’un oubli. Le code est brouillon et difficile à
comprendre.
/∗
∗ Mauvaise p r a t i q u e (PHP)
∗/
function retrieveValues ( ) {
/∗
∗ La méthode r e t r i e v e V a l u e s I m p l ( ) r e n s e i g n e l e t a b l e a u
∗ $data passé par r é f é r e n c e .
∗
∗ Dans c e t exemple $data e s t d é c l a r é de manière i m p l i c i t e .
∗ C ’ e s t une mauvaise p r a t i q u e , b i e n que PHP l ’ a u t o r i s e .
∗/
r e t r i e v e V a l u e s I m p l ( $data ) ;
r e t u r n $data ;
}
/∗
∗ Bonne p r a t i q u e (PHP)
∗/
function retrieveValues ( ) {
/∗
∗ On d é c l a r e de manière e x p l i c i t e $data avant de
∗ l e passer à l a f o n c t i o n r e t r i e v e V a l u e s I m p l ( )
∗
∗ C ’ e s t l a bonne p r a t i q u e .
∗/
$data = array ( ) ;
r e t r i e v e V a l u e s I m p l ( $data ) ;
r e t u r n $data ;
}
64
5.2 En vrac 5 PHP
$where = NULL ;
i f ( empty ( $cod_cge ) === FALSE ) {
/∗
∗ A t t e n t i o n , on va i c i concaténer une v a r i a b l e NULL
∗ avec une chaîne de c a r a c t è r e s !
∗/
$where . = " ( ETP . cod_cge = ’ " ;
...
}
/∗
∗ Bonne p r a t i q u e de développement : i n i t i a l i s e r
∗ $where à une a u t r e v a l e u r que NULL : )
∗/
$where = ’ ’ ;
i f ( empty ( $cod_cge ) === FALSE ) {
/∗
∗ $where n ’ e s t pas NULL , on peut
∗ concaténer l e s yeux fermés .
∗/
$where . = " ( ETP . cod_cge = ’ " ;
...
}
65
5.2 En vrac 5 PHP
5.2.9 Éviter l’appel de fonctions dans le corps dúne déclaration de boucle ❢♦"
Appeler une fonction dans le corps d’une déclaration de boucle ❢♦" est inutilement couteux en calcul
et peut être source d’erreurs. Il vaut mieux écrire une ligne de plus.
/∗
∗ Mauvaise p r a t i q u e (PHP)
∗/
/∗
∗ Bonne p r a t i q u e (PHP)
∗/
$count = count ( $ a r r a y ) ;
66
6 PYTHON
6 Python
6.1 Exécuter l’interpréteur avec l’option ✲!!
Il est préférable de lancer l’interpréteur avec l’option ✲!! et ce, afin de lever des erreurs si l’indentation
n’est pas concistante.
67