Académique Documents
Professionnel Documents
Culture Documents
Christophe Couronne
Rsum
Ce document est un recueil des bonnes et mauvaises pratiques de dveloppement.
Il constitue une suite de recommandations dont lobjectif est de faciliter la lecture des codes ou leur
distribution. A ce titre il ne sagit, en aucun cas, de consignes contraignantes.
Cependant, lintgration et la valorisation de vos dveloppements seront facilits si vous suivez ces
recommandations.
La plupart des pratiques prsentes dans ce document ont fait lobjet dun recensement slectif
parmi des rfrentiels connus dont la liste figure en bibliographie. Les autres relvent dexpriences
concrtes et sont, par nature, empiriques.
Il sagit dun document de travail participatif dont le contenu est destin voluer suivant une d-
marche continue damlioration des mthodes de dveloppement.
Les pratiques prsentes dans ce document sont classes en fonction de leurs portes (style de
code, codage, conception...) ou par catgories (Java, Java Enterprise Edition (JEE), PHP...).
1
TABLE DES MATIRES TABLE DES MATIRES
2 Pratiques Gnrales 5
2.1 Style de code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.1.1 Indentation du code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.1.2 Accolades autour des structures de contrles . . . . . . . . . . . . . . . . . . . . . 6
2.1.3 viter les oprateurs ternaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.1.4 viter les affectations dans les conditions des structures de controles . . . . . . . 8
2.2 Mtriques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2.1 Longueur de classe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2.2 Longueur des mthodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.2.3 Nombre de paramtres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2.4 Nombre de champs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2.5 Nombre de mthodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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 return par fonction . . . . . . . . . . . 19
2.3.2 viter les instructions "en cascade" . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.3.3 viter les instructions break . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.3.4 viter les instructions continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.3.5 viter les conditionnelles ngatives . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.3.6 Remplacer les nombres et les chanes par des constantes . . . . . . . . . . . . . 25
2.4 Rgles de conception . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.4.1 Le patron de conception singleton . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.4.2 Substituer les instructions switch par du polymorphisme . . . . . . . . . . . . . . 27
2.4.3 viter les champs protgs dans les classes final . . . . . . . . . . . . . . . . . 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 Hritage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.1.4 Attributs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.2 Rgles de conception et de codage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.2.1 viter les retours null . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.2.2 viter les passages de paramtres null . . . . . . . . . . . . . . . . . . . . . . . . 38
3.2.3 La variable devrait tre dclare final . . . . . . . . . . . . . . . . . . . . . . . . . 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 numrations en lieu et place des listes de constantes . . . . . . . . . 44
3.2.7 viter de proposer un attribut dinstance 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 mthodes des classes . . . . . . . . . 47
2
TABLE DES MATIRES TABLE DES MATIRES
4 Java Enterprise 48
4.1 Traitement par lots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
4.1.1 Pr-allocation des squences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
4.1.2 Utiliser hibernate.jdbc.batch_size . . . . . . . . . . . . . . . . . . . . . . . . . 49
4.2 Logging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
4.2.1 viter le println() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
4.2.2 viter le printStackTrace() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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 linversion de contrle . . . . . . . . . . . . . . . . . . . . . . . . 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 Dvelopper en E_ALL|E_STRICT . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
5.2.2 Utiliser les structures de contrle 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 Concatnation dune variable valeur NULL . . . . . . . . . . . . . . . . . . . . . . . 65
5.2.9 viter lappel de fonctions dans le corps dne dclaration de boucle for . . . . . . 66
6 Python 67
6.1 Excuter linterprteur avec loption -tt . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Bibliographie 68
3
1 REMERCIEMENTS
1 Remerciements
Je tiens remercier les contributeurs ci-dessous qui mont donn des conseils clairs sur ce docu-
ment.
Davy Gigan ;
Jean-Marc Lecarpentier ;
Bruno Mermet ;
Bruno Zanuttini.
4
2 PRATIQUES GNRALES
2 Pratiques Gnrales
Cette partie du document sintresse aux rgles transverses qui sappliquent, peu ou proue, tous
les langages objets.
5
2.1 Style de code 2 PRATIQUES GNRALES
Ceci permet dviter les problmes avec les fichiers diff, les patches, lhistorique CVS et les annota-
tions.
/
Mauvaise p r a t i q u e
/
i f ( isEnabled ( ) )
System . o u t . p r i n t l n ( " Enabled ! " ) ;
/
Bonne p r a t i q u e
/
i f ( isEnabled ( ) ) {
System . o u t . p r i n t l n ( " Enabled ! " ) ;
}
6
2.1 Style de code 2 PRATIQUES GNRALES
/
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 ( isEnabled ( ) ) {
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 GNRALES
2.1.4 viter les affectations dans les conditions des structures de controles
Une rgle simple, qui vite de nombreuses erreurs de programmation : viter dutiliser laffectation
dans la condition dune 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 Mtriques 2 PRATIQUES GNRALES
2.2 Mtriques
Quelques mesures destines fournir des indicateurs de la qualit logicielle.
La limite communment 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 Mtriques 2 PRATIQUES GNRALES
Restructurer votre code en crant, par exemple, dautres mthodes ou dautres classes dune 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 Mtriques 2 PRATIQUES GNRALES
/
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 Mtriques 2 PRATIQUES GNRALES
/
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 Mtriques 2 PRATIQUES GNRALES
Il est possible dutiliser des objets imbriqus qui groupent une partie de linformation. 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 Mtriques 2 PRATIQUES GNRALES
/
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 Mtriques 2 PRATIQUES GNRALES
Cela permet de rduire sa complexit et davoir des objets dune 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 Mtriques 2 PRATIQUES GNRALES
/
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 Mtriques 2 PRATIQUES GNRALES
Le seuil standard de cette mtrique est de 10 points. Si vous avez une fonction avec une complexit
suprieure 10, vous devez essayer de la rusiner.
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 Mtriques 2 PRATIQUES GNRALES
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 incontrlable, dans du vieux code.
Ne soyez pas surpris si vous trouvez des fonctions avec une complexit suprieure 100 000. La valeur
par dfaut du seuil de cette mtrique est de 200. Vous devez rester sous cette valeur.
18
2.3 Codage 2 PRATIQUES GNRALES
2.3 Codage
Les rgles prsentes dans ce paragraphe ciblent lcriture mme du code dans sa logique intrin-
sque.
2.3.1 Limiter autant que possible les instructions return par fonction
Dans lidal, une mthode/fonction ne devrait avoir quun et un seul point de sortie. Ce devrait tre
sa dernire instruction.
Linstruction return fait partie des jump statements. Il y a 3 jump statements en java : continue,
break et return. Ces instructions ont une action similaire celle des instructions goto des langages
BASIC ou Fortran : elles transfrent le contrle un autre endroit du programme.
Cette rgle fait partie des pratiques de dveloppement dites de programmation structure [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 GNRALES
Les piles dappels et les erreurs de compilations sont bien souvent imprcises lorsquon ne respecte
pas cette rgle.
Attention toutefois, cette rgle est adapter votre contexte de programmation car il arrive que ce
style soit recommand dans certains cas prcis, p. ex. pour lusage des StringBuilder ou des Stream en
Java.
Dans ce cas spcifique, il convient de veiller respecter un strict retour la ligne entre chaque appel
de mthode afin que les messages soient prcis en cas derreurs.
/
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 dcompose .
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 GNRALES
/
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 GNRALES
Cette rgle fait partie des pratiques de dveloppement dites de programmation structure [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 GNRALES
Cette rgle fait partie des pratiques de dveloppement dites de programmation structure [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 GNRALES
/
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 GNRALES
En rgle gnrale, les seuls nombres en dur que lon 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 Rgles de conception 2 PRATIQUES GNRALES
Il faut alors ajouter un constructeur private (i.e. priv) pour viter toute instanciation exterieure
cette classe.
cf. http://pmd.sourceforge.net/rules/design.html#UseSingleton.
cf. https://pmd.github.io/pmd-5.4.1/pmd-java/rules/java/design.html#UseUtilityClass.
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 mthode d i n s t a n c e f o o ( ) .
p u b l i c void foo ( ) {
/ / skipped code .
}
/ / La mthode 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 Rgles de conception 2 PRATIQUES GNRALES
Il sagit de dplacer chaque composante de la condition dans une mthode surcharge au sein dune
sous classe. On rend la mthode 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 dutiliser une mme interface avec diffrentes implmentations. Il sagit
de remplacer les instructions des diffrents cas fonctionnels, par des implmentations distinctes qui
mettent en oeuvre la mme interface de programmation.
27
2.4 Rgles de conception 2 PRATIQUES GNRALES
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 Rgles de conception 2 PRATIQUES GNRALES
/
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 Rgles de conception 2 PRATIQUES GNRALES
/
Java , bonne p r a t i q u e ( o p t i o n 2 )
On enlve 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 GNRALES
2.5 Couplage
Ces rgles servent rduire le couplage entre les diffrents 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
/
/ / subo 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 GNRALES
2.6.1 Langue
Il est conseill dcrire la documentation en anglais (ainsi que les noms des classes, des mthodes,
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 dclaration dune classe doit tre prcde dun 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 vnements 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 vnement 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 dclaration dune mthode, mme prive, doit faire lobjet dun commentaire explicite qui expose :
Son fonctionnement, cest dire ce quelle fait ;
Le type et le sens de chaque paramtre attendu ;
Si la mthode est une fonction (et non une procdure), le commentaire doit exprimer le type
dobjet 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 vnement 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 mthode 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 chane 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 mthode
{ @link # getHandlerType ( ) getHandlerType ( ) }
/
v o i d handleEvent ( E event ) ;
}
34
3.1 Documentation du code 3 JAVA
3.1.3 Hritage
Pour la documentation des classes drives, on peut viter la redondance des commentaires laide
du tag javadoc {@inheritDoc}
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 vnement 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 Rgles de conception et de codage 3 JAVA
3.1.4 Attributs
La dclaration dun attribut ou dune constante doit, en gnral, faire lobjet dun commentaire java-
doc ou doxygen destin en expliciter la prsence.
Il faut cependant viter les commentaires qui paraphrasent le code. Auquel cas, il est prfrable de
ne pas commenter lattribut.
/
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 null, vous devriez lever une exception ou retourner un objet vide la
place.
Si vous appelez une mthode dune API tierce qui retourne null, il faut envelopper cette mthode
dans une autre mthode qui lve 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
/
getEmployees() peut retourner null, mais le doit-il vraiment ? si on change getEmployee() afin quil
retourne une liste vide, on peut nettoyer le code ainsi :
36
3.2 Rgles de conception et de codage 3 JAVA
/
Clean Code , A Handbook o f A g i l e Software Craftsmanship
/
LAPI java propose une mthode Collections.emptyList() qui retourne une liste immuable prd-
finie que lon peut utiliser dans ce cas prcis :
/
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 manire, vous minimisez le risque NullPointerException et le code est bien
meilleur.
37
3.2 Rgles de conception et de codage 3 JAVA
38
3.2 Rgles de conception et de codage 3 JAVA
De mme, on ne rassigne jamais les paramtres dune fonction. Ceux-ci devraient donc toujours
tre nots final.
/
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 Rgles 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 Rgles de conception et de codage 3 JAVA
ArrayList est une meilleure implmentation de linterface Collection si lon 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 Rgles de conception et de codage 3 JAVA
La classe StringBuffer de lAPI Java standard prend en charge les logiques dexclusion mutuelle
propres aux accs concurrents des contextes concurrentiels. On dit quelle 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 Rgles 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 Rgles 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 Rgles de conception et de codage 3 JAVA
Lusage du qualifier "protected" est controvers car les classes qui hritent peuvent avoir besoin
daccder au champ de la super classe.
Toutefois, il ne faut pas oublier quun qualifier "protected" autorise les classes du paquetage acc-
der au champ, ce qui est finalement trs ouvert.
La pratique courante est de protger les champs laide du qualifier "private" et de proposer, au cas
par cas, des mthodes dites getters et setters pour y accder si besoin est.
La classe est alors garante de lintgrit de ses donnes. Il sagit du concept dencapsulation.
45
3.2 Rgles de conception et de codage 3 JAVA
Il sagit dun type trs abstrait qui ne contient que le strict ncessaire la mise en oeuvre ultrieure
par des classes drives.
Java autorise, pour chaque mthode abstraite de dclarer (ou non) sa visibilit. Il sagit conceptuelle-
ment dun dtail dimplmentation qui est souvent considr 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 Rgles de conception et de codage 3 JAVA
Il est prfrable dexpliciter clairement la visibilit des mthodes 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 squences
Les gnrateurs didentifiants de JPA et dhibernate utilisent par dfaut une pr-allocation de s-
quence de taille 1[Sut11].
Dans cette configuration, chaque instruction insert ou update provoque lappel une autre instruc-
tion select qui sert rcuprer la nouvelle valeur de la squence.
En consquence, les accs sont doubls en base de donnes lors des traitements par lots.
Cette configuration est excessive. Si lon modifie ce critre pour 500 ou 1000, on rduit de moiti les
accs dans les procdures 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 insres dans le cache de second niveau[Doc14a] ce qui provoque
gnralement une OutOfMemoryException aux alentours du 50 000 me objet trait.
On configure donc le framework afin quil place les objets dans le cache de premier niveau et ce,
avec une fentre 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
rgulirement appeler flush() et puis clear() sur la session, pour contrler 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 println()
Dans les applications dentreprise, il convient dviter les instructions de type System.out.println().
Il est prfrable dutiliser 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 linversion de contrle
Spring est un conteneur lger dapplication javaee. Il prend en charge linstanciation des objets
laide dun patron de conception qui rduit le couplage entre les classes : linversion de contrle (IOC,
Inversion Of Control).
Linversion de contrle remplace linstanciation des dpendances par une injection de celles-ci
laide dun framework, en loccurence, spring.
Exemple : nous avons une dpendance directe dune classe A vers une classe B.
Il sagit dintroduire un typage par interfaces afin de rduire le couplage entre les classes A et B.
La classe A ne dpend donc plus de B directement, mais de I qui peut tre implment par nimporte
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 sintressent, 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 problmes de scurit.
Dans ce processus, lditeur ou les diteurs dune proposition sont essentiellements les contribu-
teurs principaux qui ont crit la PSR et ils sont appuys par 2 membres qui votent. Les membres qui
votent sont le coordinateur (qui est responsable du pilotage de ltape de relecture "Review") ainsi quun
second membre dit "Sponsor".
Lobjectif est de reduire la friction cognitive qui rsulte de lanalyse des codes de diffrents auteurs.
On y arrive en partageant un ensemble de rgles et dattentes sur la manire dont doit etre format le
code PHP.
Le style des rgles prsentes ici sont drives des points communs relatifs un certain nombre de
projets. Quand divers auteurs collaborent sur plusieurs projets, il est utile davoir un ensemble de lignes
directrices quil convient de respecter sur ces projets. Cest pourquoi les bnfices de cette norme nest
pas dans le contenu des rgles, en tant que telles, mais dans le partage de celles-ci.
57
5.2 En vrac 5 PHP
5.2 En vrac
Des rgles en vrac, releves de manire empiriques.
/
Bonne p r a t i q u e de dveloppement : 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 E_ALL | E_STRICT dans un fichier .htaccess de la manire
suivante :
php_value e r r o r _ r e p o r t i n g 4095
On peut galement ajouter les paramtres de configuration suivants pour forcer laffichage dun
maximum dinformations.
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 contrle du langage C sont reprises par les langages C, Java, C# et C++. De ce
fait, elles sont familires pour la plupart des dveloppeurs. Les structures de contrle 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 supportes pour des raisons de compatibilit
ascendante.
Elles sont cependant dconseilles (dprcies) 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 sen trouve plus simple et plus propre. Cest une aide pour son dbugage, sa relecture et sa
prnit.
Dune manire gnrale, lorsque le mot cl global est utilis, on considre suspect le code et on
procde une opration de rusinage pour le corriger.
62
5.2 En vrac 5 PHP
Cest notamment le cas si lon additionne une chane de caractres (qui reprsente un entier) avec
un entier. La valeur de la chane de caractres est alors extraite puis convertie en entier.
Le dveloppeur distrait na plus conscience du type de donnes quil manipule ! On prfre videm-
ment une conversion explicite de type.
/
Mauvaise p r a t i q u e (PHP)
/
/
$groupe [ count_etapes ] e s t une chane 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 zro .
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 numrique .
/
$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 dveloppeur paresseux peut tre heureux car PHP va automatiquement dclarer ces variables
pour lui. Charge au relecteur de trouver sil sagit ou non dun oubli. Le code est brouillon et difficile
comprendre.
/
Mauvaise p r a t i q u e (PHP)
/
function retrieveValues ( ) {
/
La mthode 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 manire 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 manire 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 concatner une v a r i a b l e NULL
avec une chane de c a r a c t r e s !
/
$where . = " ( ETP . cod_cge = " ;
...
}
/
Bonne p r a t i q u e de dveloppement : 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
concatner l e s yeux ferms .
/
$where . = " ( ETP . cod_cge = " ;
...
}
65
5.2 En vrac 5 PHP
5.2.9 viter lappel de fonctions dans le corps dne dclaration de boucle for
Appeler une fonction dans le corps dune dclaration de boucle for est inutilement couteux en calcul
et peut tre source derreurs. 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 Excuter linterprteur avec loption -tt
Il est prfrable de lancer linterprteur avec loption -tt et ce, afin de lever des erreurs si lindentation
nest pas concistante.
67
RFRENCES RFRENCES
Bibliographie
Rfrences
[Cor14] Oracle Corp. Code conventions for the java programming language : Contents, 2014. http:
//www.oracle.com/technetwork/java/codeconvtoc-136057.html.
[Doc14a] Hibernate Community Documentation. Chapitre 14. traitement par lot, 2014. http://docs.
jboss.org/hibernate/core/3.5/reference/fr-FR/html/batch.html.
[doc14b] The PEAR documentation. Indentation et longueur de lignes, 2014. http://pear.php.net/
manual/fr/standards.indenting.php.
[GHJV94] Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. Design Patterns : Ele-
ments of Reusable Object-Oriented Software. Addison-Wesley professional computing se-
ries, 1994.
[Gri14] Miguel Griffa. Pmd rulesets index, 2014. http://pmd.sourceforge.net/pmd-5.1.1/rules/
index.html.
[Gro16] PHP Framework Interop Group. Moving php forward through collaboration and standards,
2016. http://www.php-fig.org/.
[ll14] Wikipedia lencyclopdie libre. Programmation structure wikipdia, 2014. http://fr.
wikipedia.org/wiki/Programmation_structur%C3%A9e.
[Mar09] Robert C. Martin. Clean Code, A Handbook of Agile Software Craftmanship. Prentice Hall,
2009.
[Mer10] Bruno Mermet. Code smells, 2010. https://mermet.users.greyc.fr/Enseignement/
CoursPDF/codeSmells.pdf.
[Mer11] Bruno Mermet. Vrification automatique de la qualit de code, 2011. https://mermet.
users.greyc.fr/Enseignement/CoursPDF/verificationAutomatiqueQualiteCode.pdf.
[Mod13] Niklas Modess. Cyclomatic and npath complexity explained, 2013. http://codingswag.
ghost.io/cyclomatic-and-npath-complexity-explained/.
[PHP14a] Manuel PHP. Php : Constructors and destructors - manual, 2014. http://php.net/manual/
en/language.oop5.decon.php.
[PHP14b] Manuel PHP. Php : Syntaxe alternative - manual, 2014. http://php.net/manual/fr/
control-structures.alternative-syntax.php.
[Sou14] SourceMaking. Replace conditional with polymorphism, 2014. http://sourcemaking.com/
refactoring/replace-conditional-with-polymorphism.
[Sut11] James Sutherland. Java persistence performance : How to improve jpa performance
by 1 825 %, 2011. http://java-persistence-performance.blogspot.fr/2011/06/
how-to-improve-jpa-performance-by-1825.html.
[Tea14] Checkstyle Development Team. checkstyle - available checks, 2014. http://checkstyle.
sourceforge.net/availablechecks.html.
[Wik16] Wikipedia. Rgles de codage, 2016. https://fr.wikipedia.org/wiki/R%C3%A8gles_de_
codage.
68