code complete

62
Code Complete Sébastien Combéfis Lundi 29 février 2016

Upload: sebastien-combefis

Post on 17-Jul-2015

67 views

Category:

Engineering


4 download

TRANSCRIPT

Page 1: Code Complete

Code CompleteSébastien Combéfis

Lundi 29 février 2016

Page 2: Code Complete

Ce(tte) œuvre est mise à disposition selon les termes de la Licence Creative CommonsAttribution – Pas d’Utilisation Commerciale – Pas de Modification 4.0 International.

Page 3: Code Complete

Contexte

W. Strunk et E. B. White

1918B. W. Kernighan et P. J. Plauger

1974

3

Page 4: Code Complete

Qualité de code

4

Page 5: Code Complete

“Always code as if the guy who ends up maintainingyour code will be a violent psychopath who knowswhere you live.” — Martin Golding

“Always code as if the guy who ends up maintainingyour code will be a violent psychopath who knowswhere you live.” — Martin Golding

Page 6: Code Complete

Cacher l’information

Deux catégories de secrets

Cacher la complexité pour le développeur

Cacher les sources de changement pour faciliter les modifs

Barrière au masquage d’information

Distribution excessive de l’information

Dépendance circulaire

Confondre variable de classe avec variables globales

6

Page 7: Code Complete

Identifier le changement

Importance d’identifier le changement pour l’isoler

1 Identifier les éléments qui pourraient changer

2 Séparer les éléments identifiés dans une classe

3 Isoler les éléments identifiés du reste

Exemples communs qui peuvent changer

Règles business (facturation, taxe...)

Dépendances hardware

Entrée/sortie (format de fichiers produits)

Fonctionnalités non standards des langages

Zones avec des constructions difficiles

Variable statuts7

Page 8: Code Complete

Couplage

Il faut maintenir un couplage le plus faible possible

Critères de couplage

Minimiser le nombre de connexions vers d’autres modules

Rendre les connexions visibles

Pouvoir changer les connexions par flexibilité

Types de couplage

Simple-data-parameter (passage de paramètre primitif)

Simple-object (un objet instancie un autre objet)

Object-parameter

Semantic8

Page 9: Code Complete

Code de qualité

Focus sur la programmation orientée objet

Analyse top-down

Depuis la classe jusqu’aux instructions

Classe Méthode Instruction

9

Page 10: Code Complete

Trouver les objets du monde réel

Identifier l’objet et ses attributs

Déterminer ce qui peut être fait avec l’objet

Identifier ce que l’objet peut faire à d’autre objets

Déterminer ce qui sera visible de l’objet

Définir l’interface publique de l’objet

10

Page 11: Code Complete

Programmer avec des classes

Abstract Data Type

ADT

Cacher les détailsd’implémentation

Rendre les changementsindépendants du restedu programme

Le programme estauto-documenté

Le programme manipuledes entités qui modélisentle monde réel

11

Page 12: Code Complete

Manipuler les objets du monde

getFuelLevel

isOnGroundstartEngine

startAutopilot

Page 13: Code Complete

Abstraction

Créer une bonne abstraction de l’objet représenté

S’assurer que les détails d’implémentation soient bien cachés

L’abstraction doit former un tout cohérent et consistent

Le niveau d’abstraction doit être consistent

Abstraction — “Le fait de voir une opération complexesous une forme simplifiée”

13

Page 14: Code Complete

Encapsulation

Minimiser l’accès aux classes et à leurs membres

Ne pas exposer les données de la classe

Ne pas exposer des détails d’implémentation

Diminuer au maximum le couplage entre classes

public class GradeReport{

private Grade[] grades;

public double getGrade (String courseName) { /∗ ... ∗/ }

private static class Grade { /∗ ... ∗/ }}

14

Page 15: Code Complete

Composition ou héritage ? I

HAS-A

Une classe se compose àpartir d’autres

7± 2 (composants)

Surveillez le couplage

IS-A

Une classe est unespécialisation d’une autre

6 (niveaux d’héritage)

Surveillez l’encapsulation

Liskov Substitution Principle (LSP)

Si q(x) est une propriété démontrable pour tout objet x de type T ,Alors q(y) est vraie pour tout objet y de type Stel que S est un sous-type de T .

15

Page 16: Code Complete

Composition ou héritage ? II

Vehicle

Car Wheel

is-a

has-a

16

Page 17: Code Complete

Membres d’une classe

Limiter le nombre de méthodes

Limiter les appels de méthodes directs et indirects

En général : limiter la collaboration avec d’autres classes

Law of Demeter (LoD)

Une méthode M d’un objet O ne peut invoquer que :1 ses propres méthodes ;2 les méthodes de ses paramètres ;3 les méthodes des objets qu’elle instance ;4 et les méthodes de ses objets composants.

17

Page 18: Code Complete

Constructeurs

Initialiser toutes les variables d’instance

Interdire la création d’instances avec un constructeur privé

Éviter les shallow copies des paramètres

public class BookStore{

private Books[] books;

public BookStore (Books[] books){

this.books = books;}

}

18

Page 19: Code Complete

Deep or shallow copies ?public class Exam{

private Course course;private Student[] students;

public Exam (Course course, Student[] students){

this.course = course;this.students = students;

}}

public class Test{

public static void main (String[] args){

Student[] students = /∗ ... ∗/ ;Exam exam = new Exam (/∗ ... ∗/, students);Arrays.fill (students, null);

}}

19

Page 20: Code Complete

Pourquoi une classe ?

Modéliser un objet du monde réel

Modéliser des objets abstraits

Réduire ou isoler la complexité

Limiter les impacts lors de modifications

Cacher les données et détails d’implémentation

Faciliter la réutilisation de code

20

Page 21: Code Complete

Avoid God classesalso known as The Blob

Toute puissante et qui sait tout

Passe son temps à appeler des get et set

Page 22: Code Complete

Classes à éviter

Éviter les classes God

Éliminer les classes hors sujet

Classes avec seulement des données

Éviter les classes dont les noms sont des verbes

Classes avec seulement des comportements

22

Page 23: Code Complete

Programmer avec des routines

Réduire la complexité

Introduit des abstractions intermédiaire et compréhensibles

Éviter la duplication de code

Faciliter la réutilisation de code

23

Page 24: Code Complete

Pourquoi rassembler des instructions ?

Cohésion fonctionnelleUne routine = une opération

Cohésion séquentielleSéquence d’instructions qui partagent des données

Cohésion communicationnelleOpérations qui utilisent la même donnée

Cohésion temporelleOpérations qui doivent avoir lieu en même temps

24

Page 25: Code Complete

Choisir le bon nom

Décrire ce que fait la routine

Éviter les verbes vagues : process, handleOutput...

Ne pas différencier rien que par un numéro : test1, test2...

Ne pas hésiter sur la longueur du nom

Utiliser les opposés à bon escient : get/put, start/stop...

Fonction : décrire la valeur de retour

Procédure : verbe fort + sujet pour décrire l’action

25

Page 26: Code Complete

Longueur d’une routine

Pas de convention globalement acceptée

Doit tenir sur un écran ou une/deux page/s (50–150 lignes)

Convention NASA pour développer un code critique

60 lignes de code maximum par routine

26

Page 27: Code Complete

Paramètres d’une routine

39% des erreurs viennent de l’interface entre routines

Cette interface se fait lors des appels de routines

Bonnes pratiques par rapport aux paramètres

Ordre des paramètres : input/modify/output

Même ordre lorsque routines avec les mêmes paramètres

Utiliser tous les paramètres

Ne pas utiliser les paramètres comme variable de travail

Documenter les hypothèses sur les paramètres

Limiter le nombre de paramètres (environ 7)

27

Page 28: Code Complete

Protégez-vous !

Données provenant de sources externesValeurs des paramètres des routines

Page 29: Code Complete

Gestion des erreurs ou assertion ?

Gestion des erreursÀ utiliser pour des situations particulières qui pourraient seproduire

AssertionÀ utiliser pour des situations qui ne surviendront jamais

public Book getBook (int bookid){

for (int i = 0; i < books.length; i++){

if (books[i].getId() == bookid) { return books[i]; }}

assert false;return null;

}

29

Page 30: Code Complete

Assertion

Le code doit rester fonctionnel sans les assertions

Vérification des préconditions et postconditions

Peut être vu comme des commentaires exécutables

30

Page 31: Code Complete

Gestion des erreurs

Renvoyer une valeur neutre

Passer la donnée erronée

Renvoyer la même valeur que lors du dernier appel

Afficher un message d’erreur

Mécanisme d’exception pour communiquer des erreurs

Correctness <> Robustness31

Page 32: Code Complete

One variable = One purposeOne variable = One purpose

Page 33: Code Complete

Déclaration

Initialisation lors de la déclaration

... dans le constructeur pour les variables d’instance

Déclaration le plus proche de l’utilisation

Utilisez les constantes

33

Page 34: Code Complete

Span et durée de vie

Le « span » mesure l’espacement de l’utilisation de la variable

La durée de vie mesure le nombre d’instructions pourlesquelles la variable existe

public void test(){

int a = 0;int b = 0;int c = 0;b = a + 1;b = b / c;

}

Variable b

Average span : (1 + 0)/2 = 0.5

Live time : 4

(les deux valeurs sont à minimiser)

34

Page 35: Code Complete

Minimiser la portée

Initialiser les variables utilisée dans une boucle juste avant

Ne pas retarder l’initialisation d’une variable

Grouper les instructions liées (avec les mêmes variables)

Séparer les groupes d’instructions liées en routines

Toujours commencer avec la visibilité la plus faible

35

Page 36: Code Complete

Variable

Le nom décrit contenu de la variable et la documente

Longueur optimale entre 9 et 15 caractères

Une variable utilisée pour une seule raison

Éviter les variables avec plusieurs significations selon la valeur

S’assurer que toutes les variables sont utilisées

36

Page 37: Code Complete

Choisir les noms

Noms avec signification proche : input et inputVal

Noms similaires : clientRec et clientRep

Éviter les nombres : total1 et total2

Attention à l’orthographe !

Éviter de mélanger les langues

Éviter des caractères difficiles à lire : char1 et chartl, cOnf etc0nf, GREAT et 6REAT, tex2html et texZhtml...

37

Page 38: Code Complete

Nom pour types de données spécifiques

Compteur des boucles i, j, k (sauf si utilisée hors boucle)

Sauf pour les longues boucles, où un nom parlant est mieux

Ne pas mettre flag dans le nom des variables de statut

Les variables temporaires sont à éviter (temp...)

Nommer les variables booléennes (done, error, found, ok,success...) avec nom qui implique true ou false

38

Page 39: Code Complete

Data types

Page 40: Code Complete

Nombre (1)

Éviter les nombres magiques

Hardcoder les valeurs 0 et 1 ne pose pas problème

Anticiper les divisions par zéro

Rendre les conversions de type explicite

Éviter les comparaisons de types différents

40

Page 41: Code Complete

Nombre (2)

Nombre entier

Vérifier les divisions par zéro

Vérifier les dépassements de capacité

Diviser avant de multiplier (1e6 * 1e6 / 1e6)

Nombre flottant

Éviter addition et soustraction de nombres de magnitudes 6=

Éviter les comparaisons pour l’égalité

Anticiper les erreurs d’arrondi

41

Page 42: Code Complete

Chaine de caractères

Éviter les caractères et chaines magiques

Attention à l’accès par indice avec les méthodes utilisées

Attention au support ou non d’Unicode

Penser à la politique d’internationalisation de l’application

42

Page 43: Code Complete

Autres types

Booléen

Utiliser les booléens pour documenter son programme

En nommant des expressions booléennes pour les conditions

Simplifier les tests complexes avec des booléens

Tableau/Liste

S’assurer que les indices restent dans les bornes

Attention aux indices lorsque plusieurs dimensions

43

Page 44: Code Complete

Writing programs is like writing books

Page 45: Code Complete

Code séquentiel

Respecter l’ordre lorsqu’il a de l’importance

Rendre visible les dépendances (noms des routines, arguments)

Grouper les instructions de manière logique

45

Page 46: Code Complete

Instructions conditionnelles

Traiter les cas normaux d’abord (avec le if) ensuite les casd’erreur (avec le else)

Faire attention à bien utiliser < ou <=

Simplifier les conditions complexes par un appel de fonction

Ordonner les cas en commençant par le plus fréquent

46

Page 47: Code Complete

Instructions répétitives (1)

Boucles while, for et foreach

Un seul point d’entrée par boucle

Code d’initialisation juste avant la boucle

Boucle infinie avec while(true){}

Éviter les boucles vides

Mise à jour des variables de contrôle en début ou fin du corps

Une boucle = une fonction

47

Page 48: Code Complete

Instructions répétitives (2)

S’assurer que la boucle se termine et rendre la condition determinaison claire et limpide

Ne pas faire le singe en changeant les variables de contrôlepour quitter la boucle

Ne pas dépendre de la valeur des variables de contrôle après laboucle

Utiliser les break, mais avec modération

48

Page 49: Code Complete

Imbriquer des boucles

Attention aux noms des variables de contrôle

Limiter la portée des variables de contrôle à la boucle

Au grand maximum trois niveaux d’imbrication de boucles

On doit pouvoir lire la boucle de manière globale

49

Page 50: Code Complete

Expressions booléennes

Comparer implicitement des booléens avec true et false

Casser des conditions trop complexes en utilisant des variablesbooléennes intermédiaires ou dans une routine

Inverser la logique pour avoir la condition du if positive

Simplifier les expression booléennes avec la loi de De Morgan

! (A || B) ≡ ( !A) && ( !B)! (A && B) ≡ ( !A) || ( !B)

50

Page 51: Code Complete

Fundamental Theorem of Formatting

“A good visual layoutshows the logical

structure of a program”

“Any fool can write code that a computer canunderstand. Good programmers write code thathumans can understand.” — Martin Fowler

“Any fool can write code that a computer canunderstand. Good programmers write code thathumans can understand.” — Martin Fowler

Page 52: Code Complete

Bon layout

Représenter la structure logique du code de manière précise etconsistante

Augmenter la lisibilité

Supporter et faciliter les modifications

En utilisant les blancs pour regrouper, et pour indenter et lesparenthèses pour clarifier les expressions

52

Page 53: Code Complete

Quelques règles de layout

Une ligne de code ne devrait pas dépasser 80 caractères

Une déclaration de variable par ligne

Dans une classe : commentaire d’entête, données, méthodespublic, protected puis private

53

Page 54: Code Complete

Les commentaires

Répétition du code

Explication du code

Marqueurs dans le code

Résumé du code (focus sur le pourquoi, et pas sur le comment)

Explication de l’intention du code (niveau problème et pas solution)

Information additionnelle non présente dans le code

“Good code is its own best documentation.” — Steve McConnell

54

Page 55: Code Complete

Do not comment tricky code, rewrite it!Do not comment tricky code, rewrite it!

Page 56: Code Complete

56

Page 57: Code Complete

57

Page 58: Code Complete

En résumé

Réduire la complexité

Écrire ses programmes pour des humains, pas pour la machine

Consistance et cohérence

Garder les éléments proches de leurs utilisations

Penser et coder au niveau du problème, pas de la solution

58

Page 59: Code Complete

À suivre

http://geek-and-poke.com/

http://www.codinghorror.com/blog/

59

Page 60: Code Complete

Livres de référence I

ISBN 978-0-735-61967-8 ISBN 978-0-132-35088-4 ISBN 978-0-596-51004-6

60

Page 61: Code Complete

Livres de référence II

ISBN 978-0-201-61622-4 ISBN 978-0-321-35668-0 ISBN 978-0-201-48567-7

61

Page 62: Code Complete

Créditshttps://www.flickr.com/photos/toolmantim/2887927385https://www.flickr.com/photos/smitty/2245445147http://www.flickr.com/photos/tetezinharomana/7152072635/http://www.flickr.com/photos/jetstarairways/6769120131/http://www.flickr.com/photos/47104521@N08/4332849715/http://www.flickr.com/photos/dunechaser/2936384313/http://www.flickr.com/photos/sillydog/287354869/https://www.flickr.com/photos/small_realm/15375289074http://www.flickr.com/photos/j1x4r/4313734090/http://www.flickr.com/photos/focx/5485671820/http://www.flickr.com/photos/cyberslayer/952153409/http://geek-and-poke.com/geekandpoke/2014/7/17/simply-explainedPhotos des livres depuis Amazon

62