OVH Cloud OVH Cloud

De l'usage des exceptions

106 réponses
Avatar
Guillaume Gourdin
Bonjour à tous,

selon ma (modeste) expérience, les exceptions en C++sont très largement sous
utilisées, et on en reste (me semble t-il) toujours à la bonne vieille
méthode du retour d'un code d'erreur. Je suis un peu surpris de cet état de
fait, les exceptions étant supposées apporter une gestion plus performantes
des erreurs. J'ai dons quelques questions: est-il vrai que les exceptions
sont sous utilisées? Quels sont vos retours d'expérience? Ou bien y a t'il
une raison plus profonde à la sous-utilisation des exceptions?

Merci!

- Guillaume -

10 réponses

7 8 9 10 11
Avatar
Wykaaa
Marc Espie a écrit :
In article ,
Mathias Gaunard wrote:
On 4 juil, 12:34, "Guillaume Gourdin" wrote:

selon ma (modeste) expérience, les exceptions en C++sont très largement sous
utilisées, et on en reste (me semble t-il) toujours à la bonne vieille
méthode du retour d'un code d'erreur.


La raison principale à cela est que certains considèrent qu'écrire du
code exception-safe est compliqué (ou du moins beaucoup plus compliqué
que de gérer des codes de retour) ce qui est bien entendu absolument
faux, puisqu'au contraire écrire du code exception-safe basique est
trivial puisqu'il suffit de suivre le RAII. (si on doit gérer plein de
vieux code pourri ne suivant pas ce principe, par contre, c'est bel et
bien compliqué)



Ouais, ben dans la vraie vie, tu n'as generalement pas le temps de tout
ecrire de fond en comble, ni meme d'auditer serieusement le code que tu
reutilises... ca fait tout un ensemble de cas ou les exceptions sont
difficilement utilisables.

Ca n'empeche pas de suivre evidemment de bons preceptes pour que le code
nouveau fonctionne avec des exceptions... le jour futur ou tout le code
fonctionnera correctement !



On parle beaucoup, dans ce fil, des exceptions du point du code mais, en
fait, la politique (philosophie ?) concernant les exceptions doit être
déterminée au niveau de la conception globale et même bien plus en amont
, en même temps que les choix principaux de l'application (je parle pour
une nouvelle application).
Choisir des codes retour ou utiliser les exceptions ne doit aucunement
relever du choix du programmeur (il est bien trop tard !).
Quand à la réutilisation, on réutilise des modules existants, des
librairies, etc. via des interfaces qui, normalement, documentent les
exceptions pouvant être levées. Si ce n'est pas le cas, cela signifie
que les modules en question ne sont pas réutilisables.

Quant à l'argument que, dans la "vraie vie", on n'a pas le temps, c'est
un faux argument que l'on entend depuis la nuit des temps de
l'informatique. La preuve, c'est qu'on trouve toujours le temps de
refaire ou de corriger (ce qui coûte plus cher que d'essayer de faire
bien dès le début).
je suis maintenant à la retraite, mais en suivant cette discussion, j'ai
l'impression que l'informatique n'a pas mûrie d'un pouce en 40 ans !
C'est vraiment dramatique de rester si longtemps en enfance...
Note : Marc, je place mon message en réponse à l'un des tiens, mais tu
n'es pas en cause plus que les autres. Nous sommes tous, hélas, fautifs
(et je me mets dans le tas car, en tant que chef ou directeur de projet,
j'ai quelques fois laisser faire des choses et je n'aurais pas dû...).
Avatar
Michael DOUBEZ
Wykaaa a écrit :
On parle beaucoup, dans ce fil, des exceptions du point du code mais, en
fait, la politique (philosophie ?) concernant les exceptions doit être
déterminée au niveau de la conception globale et même bien plus en amont
, en même temps que les choix principaux de l'application (je parle pour
une nouvelle application).
Choisir des codes retour ou utiliser les exceptions ne doit aucunement
relever du choix du programmeur (il est bien trop tard !).



Je pense que tout le monde est d'accord pour dire que si exception il y
a, cela a un impact sur l'ensemble du code, ne serait qu'au niveau de
l'exception-awareness.
Concernant une politique qui n'utiliserait qu'une seule des méthodes:
- que des codes de retour: on retombe dans les vieux démons. Ce qui
peut être souhaitable sous certaines contraintes (JSF par ex).
- que des exceptions: parait difficile à concevoir, il y a des cas où
une erreur est plausible (EBUSY d'un try_lock par exemple) mais il
parait peu naturel de considérer cela comme exceptionnel donc l'objet
d'une exception.

Donc, point trop n'en faut, utilisons un peu des deux. Mais dans ce cas,
la décision se fait localement en fonction de l'application. Une
ouverture de fichier ratée peut être plausible (ex: abscence de fichier
pour scanner des emplacements connus de fichier de config) ou être
exceptionnelle (ex: pas les droits, fichier locké) auquel cas
l'application doit prendre la décision.

Pour ces différents cas, qui peut prendre la décision sinon le programmeur ?
Dans quelle mesure cela est il spécifiable ?

Dans ce genre de cas, seule une code review permet AMA d'unifier la
vision. Ce qui veux dire prendre le risque de confier un savoir à la
culture/mémoire collective.

Quand à la réutilisation, on réutilise des modules existants, des
librairies, etc. via des interfaces qui, normalement, documentent les
exceptions pouvant être levées. Si ce n'est pas le cas, cela signifie
que les modules en question ne sont pas réutilisables.



Si il ne sont pas ré-utilisable, alors comment ont ils été utilisés en
premier lieu ? :)

Quant à l'argument que, dans la "vraie vie", on n'a pas le temps, c'est
un faux argument que l'on entend depuis la nuit des temps de
l'informatique. La preuve, c'est qu'on trouve toujours le temps de
refaire ou de corriger (ce qui coûte plus cher que d'essayer de faire
bien dès le début).



Je suis d'accord mais je mitigerais en faisant dépendre du degré de
pression. Certains ce font l'avocat de la notion de "dette technique":
une dette que l'on contracte quand on fait vite parce qu'on a pas le
temps (et donc doit apparaitre sur le gantt).
J'aurais aimé avoir cette idée quand je travaillais en start-up, ça
aurait facilité les négociations des temps :)

je suis maintenant à la retraite, mais en suivant cette discussion, j'ai
l'impression que l'informatique n'a pas mûrie d'un pouce en 40 ans !
C'est vraiment dramatique de rester si longtemps en enfance...



Ce qu'il y a, c'est qu'il n'y a pas de métrique permettant de déterminer
les facteurs de succès et les publier. Chaque projet est différent et
fonctionne sous des contraintes différentes avec des personnes différentes.

Peut être l'info devrait elle s'inspirer des techniques des sciences
sociales pour établir des postulats et ses méthodes.

--
Michael
Avatar
Michael DOUBEZ
Fabien LE LEZ a écrit :
On Mon, 20 Jul 2009 07:05:30 -0700 (PDT), Michael Doubez
:

Quand on a pas les outils, RAII impose une foultitude de petites
classes, ce qui peut être énervant.



Les classes qui servent souvent ne doivent pas être si nombreuses que
ça.



Hmmm. Je me suis un peu laissé emporté en parlant de foultitude.

Mais même quelques une peuvent être énervantes - enfin, ça m'enerve :) -
d'autant plus lorsqu'elles adressent des fonctions membres protected, ça
fait un code très laid.

Les classes qui servent une seule fois sont très locales, donc pas
très lourdes à gérer -- on ne les traîne pas dans un .h.



Sauf si tu es obligé de les mettre dans ta définition de classe
(firewall de compilation excepté).

Enfin, je suis d'accord avec toi.

Des classes génériques de smart pointer et de guard bien faites sont
quand même un plus dans un langage.

--
Michael
Avatar
espie
In article <4a64c1c4$0$22856$,
Michael DOUBEZ wrote:
Je suis d'accord mais je mitigerais en faisant dépendre du degré de
pression. Certains ce font l'avocat de la notion de "dette technique":
une dette que l'on contracte quand on fait vite parce qu'on a pas le
temps (et donc doit apparaitre sur le gantt).
J'aurais aimé avoir cette idée quand je travaillais en start-up, ça
aurait facilité les négociations des temps :)



Ouaip, il y a eu plein de publis sympa qui explicitent ces trucs-la
depuis quelques annees (refactoring, dette technique...)

ca permet, peu a peu, de resoudre (j'espere) le gros souci que tu as
en enseignement: impossible de montrer des vrais projets, sur la duree.
Et les sensations que tu as sur du vrai gros code que tu revisites sur
des annees, c'est un acquis qui n'est pas du tout simple a faire passer...
Avatar
James Kanze
On Jul 20, 12:42 pm, Mathias Gaunard wrote:
On 4 juil, 12:34, "Guillaume Gourdin" wrote:



> selon ma (modeste) expérience, les exceptions en C++sont
> très largement sous utilisées, et on en reste (me semble
> t-il) toujours à la bonne vieille méthode du retour d'un
> code d'erreur.



La raison principale à cela est que certains considèrent
qu'écrire du code exception-safe est compliqué



Pas compliqué, mais nouveau. Tout le monde sait (ou doit savoir)
comment écrire du code correct dans le cas sans exceptions. Les
exceptions introduisent des contraints supplémentaires, qui
n'ont pas encore été analysés autant que la situation classique.
(Dans les systèmes ultra-critiques, par exemple, les exceptions
sont souvent interdites parce qu'on ne sait pas prouver
formellement la correction du code avec exceptions. Sans doute
parce que les grosses têtes ne s'y sont encore penchées.)

(ou du moins beaucoup plus compliqué que de gérer des codes de
retour) ce qui est bien entendu absolument faux, puisqu'au
contraire écrire du code exception-safe basique est trivial
puisqu'il suffit de suivre le RAII.



Il ne faut pas prendre tes désirs pour la réalité. La RAII
facilite une formation transactionnelle du problème, mais ce
n'est pas pour autant une panacée.

(si on doit gérer plein de vieux code pourri ne suivant pas ce
principe, par contre, c'est bel et bien compliqué) Le RAII va
en effet garantir que le code sera robuste (de manière basique
uniquement, mais assez souvent de manière forte) aux erreurs
(erreurs levées par des exceptions) quoi qu'il arrive, ce qui
n'est certainement pas le cas de code écrit à la main gérant
les erreurs qui sont exprimées par des codes de retour.



L'utilisation de RAII est indépendante des exceptions. On peut
s'en servir très bien sans exceptions ; on s'en servait,
d'ailleurs, bien avant que les exceptions soient implémentées.

De plus, la levée d'exceptions dans les constructeurs permet
d'établir certains invariants pour des objets, plus celui-ci
est fort meilleur cela est pour la robustesse du programme.



Là, je suis d'accord.

Il est parfaitement acceptable par contre d'intégrer au sein
de l'invariant de l'objet la situation d'erreur, comme le font
les iostreams, si l'on considère que la situation d'erreur n'a
rien d'exceptionnelle. (et c'est très différent d'un système
de codes de retours)



Dans ce cas-là, je crois ce qui importe, c'est que les
conditions concernées ne sont pas vraiment des invariants,
puisqu'on ne peut pas empêcher qu'elles apparaissent par la
suite. Il faut donc de toute façon pouvoir les traiter après la
construction ; il n'y a donc pas de raison pour traiter la
construction à part.

Quoi qu'il en soit, du code ne suivant pas le RAII ou pire du
code non exception-safe est du code qui est bon à jeter selon
moi, puisqu'il va empêcher l'utilisation d'exceptions et n'est
donc réutilisable qu'au sein d'un dialecte ne les contenant
pas.



On peut faire le choix de ne pas utiliser les exceptions du
tout (comme le fait Google), mais on ne peut pas mélanger du
code non exception-safe (donc du code présupossant qu'il n'y a
pas d'exceptions) avec du code levant des exceptions, ce qui
en fait un choix exclusif.



C'est effectivement le mélange qui pose le problème. Quand le
comité a changé l'opérateur new, pourqu'il lève une exception,
plutôt que renvoyer null, il a cassé tout le code correct
existant. (C'était, évidemment, une casse nécessaire à la
longue -- l'épuisement de la mémoire est l'exemple type d'une
erreur où on ne veut pas utiliser un code de retour. Et il y
avait aussi de fortes chances qu'il y avait en fait très peu de
code correct, parce que vérifier le resultat de chaque new, et
le propager, c'était vraiment penible.)

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Avatar
Mathias Gaunard
On 21 juil, 09:39, James Kanze wrote:
On Jul 20, 12:42 pm, Mathias Gaunard wrote:

> écrire du code exception-safe basique est trivial
> puisqu'il suffit de suivre le RAII.

Il ne faut pas prendre tes désirs pour la réalité. La RAII
facilite une formation transactionnelle du problème, mais ce
n'est pas pour autant une panacée.



Gérer le problème de manière transactionnelle, c'est à dire avec un e
sémantique /rollback/, c'est de l'exception-safety forte, pas basique.
L'exception-safety basique ne fait que garantir que l'on libère toutes
les ressources associées et que le programme est dans un état valide,
mais il peut y avoir perte d'information. Le RAII (avec destructeurs
nothrow) suffit à garantir cela.

L'exception-safety forte, c'est un vrai problème où il n'y a pas de
solution universelle. Cela nécessite de disposer d'un certain nombre
de primitives atomiques et même nothrow, puisque les primitives
atomiques ne combinent pas.
L'usage recommande la définition d'une primitive swap nothrow, et plus
récemment de move constructors nothrow, afin de pouvoir faire du code
qui manipule des objets en mémoire avec exception-safety forte.

Mais pour des choses comme mettre à jour un fichier sur le disque (ce
qui est quand même un truc assez critique, personne n'a envie de
perdre un fichier de sauvegarde si le programme plante au milieu de
son écrasement, pour un jeu par exemple), il faut avoir une primitive
atomique rename-and-replace, qui n'est pas disponible sur tous les
systèmes.
Avatar
Wykaaa
Michael DOUBEZ a écrit :
Wykaaa a écrit :
On parle beaucoup, dans ce fil, des exceptions du point du code mais,
en fait, la politique (philosophie ?) concernant les exceptions doit
être déterminée au niveau de la conception globale et même bien plus
en amont , en même temps que les choix principaux de l'application (je
parle pour une nouvelle application).
Choisir des codes retour ou utiliser les exceptions ne doit aucunement
relever du choix du programmeur (il est bien trop tard !).



Je pense que tout le monde est d'accord pour dire que si exception il y
a, cela a un impact sur l'ensemble du code, ne serait qu'au niveau de
l'exception-awareness.
Concernant une politique qui n'utiliserait qu'une seule des méthodes:
- que des codes de retour: on retombe dans les vieux démons. Ce qui
peut être souhaitable sous certaines contraintes (JSF par ex).
- que des exceptions: parait difficile à concevoir, il y a des cas où
une erreur est plausible (EBUSY d'un try_lock par exemple) mais il
parait peu naturel de considérer cela comme exceptionnel donc l'objet
d'une exception.



Mon ou n'était pas exclusif, les deux méthodes peuvent cohabiter, bien
que ceci complique l'évolutivité et la maintenance des applications. Je
disais simplement que le choix ne doit pas se décider au moment de la
programmation. Je complète ma réponse ci-dessous après la deuxième
partie de ton intervention.

Donc, point trop n'en faut, utilisons un peu des deux. Mais dans ce cas,
la décision se fait localement en fonction de l'application. Une
ouverture de fichier ratée peut être plausible (ex: abscence de fichier
pour scanner des emplacements connus de fichier de config) ou être
exceptionnelle (ex: pas les droits, fichier locké) auquel cas
l'application doit prendre la décision.

Pour ces différents cas, qui peut prendre la décision sinon le
programmeur ?
Dans quelle mesure cela est il spécifiable ?



Toutes les exceptions survenant lors de la manipulation de fichiers
doivent être traitées, la plupart du temps, les cas que tu mentionnes
peuvent l'être par des exceptions (vois ce qui est fait en Java dans les
bibliothèques d'E/S standards).

Dans ce genre de cas, seule une code review permet AMA d'unifier la
vision. Ce qui veux dire prendre le risque de confier un savoir à la
culture/mémoire collective.



Ce n'est pas un risque de se fier à la culture/mémoire collective car
cela s'appelle le savoir-faire qui a largement fait ses preuves jusqu'à
présent. Je me rappelle d'une revue de conception dans laquelle nous
avions fait des choix concernant certaines exceptions dans un cadre
transactionnel. Un spécialiste du transactionnel (qui d'ailleurs
n'appartenait pas au projet reviewé), ayant un grand savoir-faire dans
le domaine, nous avait indiqué que nos choix n'étaient pas valides car
ils ne permettaient pas de satisfaire les objectifs de performance
requis. Ca sert à cela les revues !

Quand à la réutilisation, on réutilise des modules existants, des
librairies, etc. via des interfaces qui, normalement, documentent les
exceptions pouvant être levées. Si ce n'est pas le cas, cela signifie
que les modules en question ne sont pas réutilisables.



Si il ne sont pas ré-utilisable, alors comment ont ils été utilisés en
premier lieu ? :)



Heureusement que tu as mis un smiley car tu sais très bien, du moins je
l'espère, qu'il y a une grande différence entre des modules qui sont
utilisés spécifiquement dans une application et des modules
réutilisables dans différents contextes. C'est la même différence qu'il
y a entre une application prototype et l'application finale (le
prototype correspond, en général, à 20% du code final...).

Quant à l'argument que, dans la "vraie vie", on n'a pas le temps,
c'est un faux argument que l'on entend depuis la nuit des temps de
l'informatique. La preuve, c'est qu'on trouve toujours le temps de
refaire ou de corriger (ce qui coûte plus cher que d'essayer de faire
bien dès le début).



Je suis d'accord mais je mitigerais en faisant dépendre du degré de
pression. Certains ce font l'avocat de la notion de "dette technique":
une dette que l'on contracte quand on fait vite parce qu'on a pas le
temps (et donc doit apparaitre sur le gantt).



Toute gestion de projet qui ne prend pas en compte ces aspects est une
mauvaise gestion de projet (cf. le modèle COCOMO).

J'aurais aimé avoir cette idée quand je travaillais en start-up, ça
aurait facilité les négociations des temps :)



C'est clair.

je suis maintenant à la retraite, mais en suivant cette discussion,
j'ai l'impression que l'informatique n'a pas mûrie d'un pouce en 40 ans !
C'est vraiment dramatique de rester si longtemps en enfance...



Ce qu'il y a, c'est qu'il n'y a pas de métrique permettant de déterminer
les facteurs de succès et les publier. Chaque projet est différent et
fonctionne sous des contraintes différentes avec des personnes différentes.



Il y a des métriques qui existent, y compris pour mesurer le degré de
réutilisabilité d'un module. J'ai écrit 100 pages sur le sujet dans une
étude faite pour la DGA et j'ai élaboré des formules, hélas non
publiables car le contrat spécifiait que mon étude devenait propriété de
la DGA à l'issue du contrat.
J'ai même appliqué l'ensemble de ces formules (avec Logiscope) à 2 gros
projets de la DGA (l'un de 400 000 lignes de Java et l'autre de 200 000
lignes de C++).

Peut être l'info devrait elle s'inspirer des techniques des sciences
sociales pour établir des postulats et ses méthodes.



Je ne connais pas les techniques des sciences sociales, je ne connais
que les techniques du "software engineering", désolé :-(
Avatar
Wykaaa
Jean-Marc Bourguet a écrit :
Wykaaa writes:

Ma (longue) expérience sur la qualité du code est que, à terme
(c'est-à-dire dans la durée), il est presque toujours préférable
d'utiliser le mécanisme d'exception que les codes retour. C'est beaucoup
plus facile à maintenir et à faire évoluer.



Exemple a reecrire avec quelque chose qui utilise les exceptions pour
signifier que l'ouverture d'un fichier a echoue (que ce soit le mecanisme
des IOStreams ou tu peux concevoir ta bibliotheque si tu trouves que les
IOStreams ne sont pas bien concues sur ce point).

std::ifstream is(fileName.c_str());
if (! is) {
assert(!defaultExt.empty() && defaultExt[0] == '.');
is.open((fileName + defaultExt" ).c_str());
}
if (! is) {
assert(!defaultDir.empty() && defaultDir.last() == '/');
is.open((defaultDir + fileName).c_str());
}
if (! is) {
is.open((defaultDir + fileName + defaultExt).c_ctr());
}
if (! is) {
throw std::runtime_error("Unable to open '" + fileName +"'" );
// mais une exception plus adaptée au projet est vraisemblablement à utiliser
}



Dans cet exemple, je fais une table de décision implémentée par un
automate à états finis qui utilise, éventuellement, le polymorphisme en
fonction de la nature du fichier à ouvrir.
Il faut se rappeler ce que dit Bertand Meyer (auteur du langage Eiffel)
: "si vous avez trop de code, mettez-le dans les donnés."
Une table d'automate ce sont des données. CQFD :-)

Un critere du choix pour savoir si une fonction d'interface doit utiliser
une exception pour signifier une erreur ou un autre mecanisme, c'est
"est-ce que c'est l'appelant immediat qui va devoir faire quelque chose ou
se contentera-t'il generalement de transmettre?" Quelque chose de
potentiellement utile, c'est un code d'erreur degenerant en une exception
s'il n'est pas traite. Mais je ne l'ai jamais mis en oeuvre et c'est
peut-etre une fausse bonne idee.

A+



Avatar
Michael Doubez
On 21 juil, 20:35, Wykaaa wrote:
Michael DOUBEZ a écrit :



> Wykaaa a écrit :
>> On parle beaucoup, dans ce fil, des exceptions du point du code mais,
>> en fait, la politique (philosophie ?) concernant les exceptions doit
>> être déterminée au niveau de la conception globale et même bie n plus
>> en amont , en même temps que les choix principaux de l'application ( je
>> parle pour une nouvelle application).
>> Choisir des codes retour ou utiliser les exceptions ne doit aucunement
>> relever du choix du programmeur (il est bien trop tard !).

> Je pense que tout le monde est d'accord pour dire que si exception il y
> a, cela a un impact sur l'ensemble du code, ne serait qu'au niveau de
> l'exception-awareness.
> Concernant une politique qui n'utiliserait qu'une seule des méthodes:
>   - que des codes de retour: on retombe dans les vieux démons. Ce q ui
> peut être souhaitable sous certaines contraintes (JSF par ex).
>   - que des exceptions: parait difficile à concevoir, il y a des ca s où
> une erreur est plausible (EBUSY d'un try_lock par exemple) mais il
> parait peu naturel de considérer cela comme exceptionnel donc l'objet
> d'une exception.

Mon ou n'était pas exclusif, les deux méthodes peuvent cohabiter, bie n
que ceci complique l'évolutivité et la maintenance des applications. Je
disais simplement que le choix ne doit pas se décider au moment de la
programmation. Je complète ma réponse ci-dessous après la deuxièm e
partie de ton intervention.



Nous sommes d'accord.

> Donc, point trop n'en faut, utilisons un peu des deux. Mais dans ce cas ,
> la décision se fait localement en fonction de l'application. Une
> ouverture de fichier ratée peut être plausible (ex: abscence de fic hier
> pour scanner des emplacements connus de fichier de config) ou être
> exceptionnelle (ex: pas les droits, fichier locké) auquel cas
> l'application doit prendre la décision.

> Pour ces différents cas, qui peut prendre la décision sinon le
> programmeur ?
> Dans quelle mesure cela est il spécifiable ?

Toutes les exceptions survenant lors de la manipulation de fichiers
doivent être traitées, la plupart du temps, les cas que tu mentionnes
peuvent l'être par des exceptions (vois ce qui est fait en Java dans le s
bibliothèques d'E/S standards).



Prenons un exemple en Java:
FileReader in;
try{
in = new FileReader(file);
try{
// ... read file
}
catch(IOException e){
e.printStack();
}
finally{
in.close();
}
}
catch(FileNotFoundException e)
{
// could not open file
}

Ce qui est AMA inutilement verbeux (il y a peut être mieux, je n'ai
pas fait de Java en 10 ans)
et moins lisible que si je pouvais écrire:
FileReader in = new FileReader(file);
if( in.isOpen() ) {
// error opening file
}
// if()...
input.close();
}


> Dans ce genre de cas, seule une code review permet AMA d'unifier la
> vision. Ce qui veux dire prendre le risque de confier un savoir à la
> culture/mémoire collective.

Ce n'est pas un risque de se fier à la culture/mémoire collective car
cela s'appelle le savoir-faire qui a largement fait ses preuves jusqu'à
présent.



Ce n'est pas un risque tant qu'il y a transmission et continuité de ce
savoir.

Je me rappelle d'une revue de conception dans laquelle nous
avions fait des choix concernant certaines exceptions dans un cadre
transactionnel. Un spécialiste du transactionnel (qui d'ailleurs
n'appartenait pas au projet reviewé), ayant un grand savoir-faire dans
le domaine, nous avait indiqué que nos choix n'étaient pas valides ca r
ils ne permettaient pas de satisfaire les objectifs de performance
requis. Ca sert à cela les revues !



Un spécialiste est bien sûr utile mais je peux aussi aller de mon
propre chef voir un expert pour lui demander conseil ou alors, il
aurait pu faire l'audit seul et localiser le problème.

AMA, une revue de code sers moins à localiser les bugs qu'à confronter
les points de vue sur le design dans le cadre d'un projet donc assurer
une communication de la culture et des savoir faire.

>> Quand à la réutilisation, on réutilise des modules existants, de s
>> librairies, etc. via des interfaces qui, normalement, documentent les
>> exceptions pouvant être levées. Si ce n'est pas le cas, cela signi fie
>> que les modules en question ne sont pas réutilisables.

> Si il ne sont pas ré-utilisable, alors comment ont ils été utilis és en
> premier lieu ? :)

Heureusement que tu as mis un smiley car tu sais très bien, du moins je
l'espère, qu'il y a une grande différence entre des modules qui sont
utilisés spécifiquement dans une application et des modules
réutilisables dans différents contextes.



Oui, c'était une boutade.

Il y a, AMA, deux raisons majeurs de non ré-utilisation de code:
1. Le code n'a pas été utilisé: i.e. il a été conçu dès le début
pour être réutilisable sans utilisation pratique pour guider le
design. C'est le cas des librairies trop générales ou mal conçues.
2. La modularisation est moisie: c-à-d que des fonctionnalités
étrangères au module ont été inséré (souvent suite à un ajout de
fonctionnalité qui aurait nécessité un refactoring) ou est trop
spécifique à un environnement (modules spécifiques comme tu le dis).

Mais ne pas réutiliser du code pour non documentation pose la question
de son utilisation tout court, il n'est plus utilsable et ça veut dire
que le code l'utilisant n'est plus maintenable.

C'est la même différence qu'il
y a entre une application prototype et l'application finale (le
prototype correspond, en général, à 20% du code final...).



Je ne comprends pas la similarité que tu exposes ici.

>> Quant à l'argument que, dans la "vraie vie", on n'a pas le temps,
>> c'est un faux argument que l'on entend depuis la nuit des temps de
>> l'informatique. La preuve, c'est qu'on trouve toujours le temps de
>> refaire ou de corriger (ce qui coûte plus cher que d'essayer de fair e
>> bien dès le début).

> Je suis d'accord mais je mitigerais en faisant dépendre du degré de
> pression. Certains ce font l'avocat de la notion de "dette technique":
> une dette que l'on contracte quand on fait vite parce qu'on a pas le
> temps (et donc doit apparaitre sur le gantt).

Toute gestion de projet qui ne prend pas en compte ces aspects est une
mauvaise gestion de projet (cf. le modèle COCOMO).



Ce que je trouve parlant, ce n'est pas que la non-qualité à un coût
(et donc doit être intégré à la gestion de projet) mais qu'elle est
une dette: c-à-d que laisser la dette courrir entraine des intérèts
qui augmentent le coût dans le temps et qu'on aura peut être pas les
moyen de payer plus tard (ou justifient une opération couteuse).


>> je suis maintenant à la retraite, mais en suivant cette discussion,
>> j'ai l'impression que l'informatique n'a pas mûrie d'un pouce en 40 ans !
>> C'est vraiment dramatique de rester si longtemps en enfance...

> Ce qu'il y a, c'est qu'il n'y a pas de métrique permettant de déter miner
> les facteurs de succès et les publier. Chaque projet est différent et
> fonctionne sous des contraintes différentes avec des personnes diff érentes.

Il y a des métriques qui existent, y compris pour mesurer le degré de
réutilisabilité d'un module. J'ai écrit 100 pages sur le sujet dans une
étude faite pour la DGA et j'ai élaboré des formules, hélas non
publiables car le contrat spécifiait que mon étude devenait proprié té de
la DGA à l'issue du contrat.
J'ai même appliqué l'ensemble de ces formules (avec Logiscope) à 2 gros
projets de la DGA (l'un de 400 000 lignes de Java et l'autre de 200 000
lignes de C++).



Ces métrique étaient des mesures absolues ou permettainet elle de
mesurer l'évolution dans un projet ?

Je ne connais pas de mesure absolue applicable d'une équipe à une
autre.

> Peut être l'info devrait elle s'inspirer des techniques des sciences
> sociales pour établir des postulats et ses méthodes.

Je ne connais pas les techniques des sciences sociales, je ne connais
que les techniques du "software engineering", désolé :-(



Je pensais aux techniques d'enquète pour déterminer des lois
empiriques. En fait, c'est ce qui se fait souvent (l'agilité est une
reconnaissance de certaines valeurs) dans les méthodes modernes
d'organisation du travail en info par opposition aux méthodes
classiques scientifique.

--
Michael
Avatar
Wykaaa
Michael Doubez a écrit :
On 21 juil, 20:35, Wykaaa wrote:
Michael DOUBEZ a écrit :



Wykaaa a écrit :







[couic]


Donc, point trop n'en faut, utilisons un peu des deux. Mais dans ce cas,
la décision se fait localement en fonction de l'application. Une
ouverture de fichier ratée peut être plausible (ex: abscence de fichier
pour scanner des emplacements connus de fichier de config) ou être
exceptionnelle (ex: pas les droits, fichier locké) auquel cas
l'application doit prendre la décision.
Pour ces différents cas, qui peut prendre la décision sinon le
programmeur ?
Dans quelle mesure cela est il spécifiable ?


Toutes les exceptions survenant lors de la manipulation de fichiers
doivent être traitées, la plupart du temps, les cas que tu mentionnes
peuvent l'être par des exceptions (vois ce qui est fait en Java dans les
bibliothèques d'E/S standards).



Prenons un exemple en Java:
FileReader in;
try{
in = new FileReader(file);
try{
// ... read file
}
catch(IOException e){
e.printStack();
}
finally{
in.close();
}
}
catch(FileNotFoundException e)
{
// could not open file
}

Ce qui est AMA inutilement verbeux (il y a peut être mieux, je n'ai
pas fait de Java en 10 ans)
et moins lisible que si je pouvais écrire:
FileReader in = new FileReader(file);
if( in.isOpen() ) {
// error opening file
}
// if()...
input.close();
}



Non car le catch(IOException e) peut être affiné sans bouger le code. En
l'état (tel que tu l'as écrit) il factorise toutes les exceptions sur
les I/O (ce qui peut être un plus) alors que l'écriture avec les if
complexifie le graphe du code et augmente le nombre cyclomatique sans
apporter aucune plus-value.
En bref, l'écriture à l'aide des exceptions simplifie le graphe de
programme (je rappelle que si n "if" se succèdent, ceci produit 2^n
chemins dans le graphe. Le déroutement sur des exceptions augmente de
façon linéaire le nombre de chemins (les chemins de déroutement sur les
exceptions ne se combinent pas). Les successions de "if" augmentent la
complexité de façon exponentielle.

Dans ce genre de cas, seule une code review permet AMA d'unifier la
vision. Ce qui veux dire prendre le risque de confier un savoir à la
culture/mémoire collective.


Ce n'est pas un risque de se fier à la culture/mémoire collective car
cela s'appelle le savoir-faire qui a largement fait ses preuves jusqu'à
présent.



Ce n'est pas un risque tant qu'il y a transmission et continuité de ce
savoir.



Le fait que les entreprises, en virant prématurément leurs séniors,
perdent leur savoir-faire est un tout autre débat, malgré tout, très
important...

Je me rappelle d'une revue de conception dans laquelle nous
avions fait des choix concernant certaines exceptions dans un cadre
transactionnel. Un spécialiste du transactionnel (qui d'ailleurs
n'appartenait pas au projet reviewé), ayant un grand savoir-faire dans
le domaine, nous avait indiqué que nos choix n'étaient pas valides car
ils ne permettaient pas de satisfaire les objectifs de performance
requis. Ca sert à cela les revues !



Un spécialiste est bien sûr utile mais je peux aussi aller de mon
propre chef voir un expert pour lui demander conseil ou alors, il
aurait pu faire l'audit seul et localiser le problème.

AMA, une revue de code sers moins à localiser les bugs qu'à confronter
les points de vue sur le design dans le cadre d'un projet donc assurer
une communication de la culture et des savoir faire.



Je ne parle pas de revue de code mais de revue de conception. Dans une
revue de code, on parle de code, pas de conception et on suppose qu'une
revue de conception a eu lieu (et on dispose de ses conclusions et de
ses "findings").
Remarque : j'ai été formé par Miller lui-même aux revues de code.

Quand à la réutilisation, on réutilise des modules existants, des
librairies, etc. via des interfaces qui, normalement, documentent les
exceptions pouvant être levées. Si ce n'est pas le cas, cela signifie
que les modules en question ne sont pas réutilisables.


Si il ne sont pas ré-utilisable, alors comment ont ils été utilisés en
premier lieu ? :)


Heureusement que tu as mis un smiley car tu sais très bien, du moins je
l'espère, qu'il y a une grande différence entre des modules qui sont
utilisés spécifiquement dans une application et des modules
réutilisables dans différents contextes.



Oui, c'était une boutade.

Il y a, AMA, deux raisons majeurs de non ré-utilisation de code:
1. Le code n'a pas été utilisé: i.e. il a été conçu dès le début
pour être réutilisable sans utilisation pratique pour guider le
design. C'est le cas des librairies trop générales ou mal conçues.
2. La modularisation est moisie: c-à-d que des fonctionnalités
étrangères au module ont été inséré (souvent suite à un ajout de
fonctionnalité qui aurait nécessité un refactoring) ou est trop
spécifique à un environnement (modules spécifiques comme tu le dis).



Le cas 2 ne devrait pas se produire car si des fonctionnalités
étrangères au module ont été insérées, c'est un non respect de l'un des
principes qui sous-tendent la modularité, à savoir le principe de forte
cohérence.

Mais ne pas réutiliser du code pour non documentation pose la question
de son utilisation tout court, il n'est plus utilsable et ça veut dire
que le code l'utilisant n'est plus maintenable.



Tout à fait d'accord.

C'est la même différence qu'il
y a entre une application prototype et l'application finale (le
prototype correspond, en général, à 20% du code final...).



Je ne comprends pas la similarité que tu exposes ici.



Je voulais dire que pour faire d'un module spécifique à une application
un module réutilisable, il y a souvent 80% de travail supplémentaire à
faire sur le module (je me réfère à des études effectuées à la NASA sur
du code ADA à la fin des années 80. Je n'ai, hélas, plus les références
exactes).

Quant à l'argument que, dans la "vraie vie", on n'a pas le temps,
c'est un faux argument que l'on entend depuis la nuit des temps de
l'informatique. La preuve, c'est qu'on trouve toujours le temps de
refaire ou de corriger (ce qui coûte plus cher que d'essayer de faire
bien dès le début).


Je suis d'accord mais je mitigerais en faisant dépendre du degré de
pression. Certains ce font l'avocat de la notion de "dette technique":
une dette que l'on contracte quand on fait vite parce qu'on a pas le
temps (et donc doit apparaitre sur le gantt).


Toute gestion de projet qui ne prend pas en compte ces aspects est une
mauvaise gestion de projet (cf. le modèle COCOMO).



Ce que je trouve parlant, ce n'est pas que la non-qualité à un coût
(et donc doit être intégré à la gestion de projet) mais qu'elle est
une dette: c-à-d que laisser la dette courrir entraine des intérèts
qui augmentent le coût dans le temps et qu'on aura peut être pas les
moyen de payer plus tard (ou justifient une opération couteuse).



Oui, c'est un aspect très intéressant pour la gestion de projet logiciel.


je suis maintenant à la retraite, mais en suivant cette discussion,
j'ai l'impression que l'informatique n'a pas mûrie d'un pouce en 40 ans !
C'est vraiment dramatique de rester si longtemps en enfance...


Ce qu'il y a, c'est qu'il n'y a pas de métrique permettant de déterminer
les facteurs de succès et les publier. Chaque projet est différent et
fonctionne sous des contraintes différentes avec des personnes différentes.


Il y a des métriques qui existent, y compris pour mesurer le degré de
réutilisabilité d'un module. J'ai écrit 100 pages sur le sujet dans une
étude faite pour la DGA et j'ai élaboré des formules, hélas non
publiables car le contrat spécifiait que mon étude devenait propriété de
la DGA à l'issue du contrat.
J'ai même appliqué l'ensemble de ces formules (avec Logiscope) à 2 gros
projets de la DGA (l'un de 400 000 lignes de Java et l'autre de 200 000
lignes de C++).



Ces métrique étaient des mesures absolues ou permettainet elle de
mesurer l'évolution dans un projet ?



Ce sont des mesures absolues mais en comparant ces mesures sur des
versions successives on voit leur évolution.

Je ne connais pas de mesure absolue applicable d'une équipe à une
autre.



Ce ne sont pas des mesures qui s'appliquent à des équipes mais des
mesures qui s'appliquent à la CONCEPTION et au CODE !

Peut être l'info devrait elle s'inspirer des techniques des sciences
sociales pour établir des postulats et ses méthodes.


Je ne connais pas les techniques des sciences sociales, je ne connais
que les techniques du "software engineering", désolé :-(



Je pensais aux techniques d'enquète pour déterminer des lois
empiriques. En fait, c'est ce qui se fait souvent (l'agilité est une
reconnaissance de certaines valeurs) dans les méthodes modernes
d'organisation du travail en info par opposition aux méthodes
classiques scientifique.



Je crains fort que les méthodes "modernes" d'organisation du travail en
info soient en fait un gigantesque retour en arrière sur le mode
"essai/erreur" (si tu parles des méthodes "agiles") alors que les
méthodes classiques "scientifiques" ont largement fait leurs preuves, du
moins dans mes domaines d'intervention qui sont les systèmes complexes à
logiciel prépondérant.
7 8 9 10 11