Coding Standard §36, DIP, et classes contrat

Le
Luc Hermitte
Bonsoir,

Je suis en train de consulter plus en détails le /Coding Standards/
d'Herb Sutter et Andrei Alexandrescu, en particulier le point 36
"Prefer providing abstract interfaces".
J'y lis que les classes racines doivent être des interfaces sans état
où toutes les fonctions membre sont virtuelles, de préférence pures.
Tout ça parce que le DIP, c'est bien (ce avec quoi je n'ai pas de
problème, bien au contraire).

Et d'un autre côté, je me souviens des classes contrats que James
avait pu me vendre, ainsi qu'à bien d'autres personnes [1]. Ces
classes contrats suivent le pattern NVI (item 39 du /Coding Standards/
qui conseille seulement de "considérer" l'utilisation du pattern NVI).

Du coup, je me pose des questions.

Le DIP est-il incompatible avec les classes contrats ? J'ai envie de
dire que non. Ai-je manqué le détail qui change tout ?
(au détail peut-être des invariants de classes exprimés sur l'_état=
_
interne de la classe)

Du coup, est-ce que le point 36 ne serait pas un peu excessif dans sa
formulation ? (qui stipule qu'une fonction membre n'a généralement pas
d'implémentation, et qui ne fait pas allusion au point 39)


[1] il y a-t-il un nom officiel, une personne que l'on peut créditer
pour cet idiome?

--
Luc Hermitte
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Fabien LE LEZ
Le #11166941
On Tue, 1 Jul 2008 09:19:34 -0700 (PDT), Luc Hermitte :

doivent



Sur le bouquin, c'est marqué "prefer", qui est nettement moins fort.
Mébon, je ne comprends pas plus que toi la contradiction :-(
Michael DOUBEZ
Le #11167861
Luc Hermitte a écrit :
Je suis en train de consulter plus en détails le /Coding Standards/
d'Herb Sutter et Andrei Alexandrescu, [...]
Le DIP est-il incompatible avec les classes contrats ? J'ai envie de
dire que non. Ai-je manqué le détail qui change tout ?
(au détail peut-être des invariants de classes exprimés sur l'_état_
interne de la classe)

Du coup, est-ce que le point 36 ne serait pas un peu excessif dans sa
formulation ? (qui stipule qu'une fonction membre n'a généralement pas
d'implémentation, et qui ne fait pas allusion au point 39)



Pour moi, la différence est d'utiliser les classes racines (avec
fonctions virtuelles pures) pour spécifier l'interface puis hériter pour
implémenter.
Alors que le pattern NVI permet d'avoir des classes héritées qui n'ont
pas la même interface.

--
Michael
James Kanze
Le #11168491
On Jul 1, 6:19 pm, Luc Hermitte
Je suis en train de consulter plus en détails le /Coding Standards/
d'Herb Sutter et Andrei Alexandrescu, en particulier le point 36
"Prefer providing abstract interfaces".
J'y lis que les classes racines doivent être des interfaces sans état
où toutes les fonctions membre sont virtuelles, de préférence pures.
Tout ça parce que le DIP, c'est bien (ce avec quoi je n'ai pas de
problème, bien au contraire).



Et d'un autre côté, je me souviens des classes contrats que James
avait pu me vendre, ainsi qu'à bien d'autres personnes [1]. Ces
classes contrats suivent le pattern NVI (item 39 du /Coding Standards/
qui conseille seulement de "considérer" l'utilisation du pattern NVI).



Du coup, je me pose des questions.



Le DIP est-il incompatible avec les classes contrats ? J'ai envie de
dire que non. Ai-je manqué le détail qui change tout ?
(au détail peut-être des invariants de classes exprimés sur l'_éta t_
interne de la classe)



Non. Je dirais le contraire, que ce sont deux aspects du même
principe. Ou peut-être que c'est en appliquant le DIP qu'on
définit le contrat ; qu'est-ce qu'il me faut de l'interface (le
contrat), par rapport à qu'est-ce qui est propre à une
implémentation donnée.

Du coup, est-ce que le point 36 ne serait pas un peu excessif dans sa
formulation ? (qui stipule qu'une fonction membre n'a généralement pas
d'implémentation, et qui ne fait pas allusion au point 39)



Peut-être. Le livre a été écrit par deux personnes, sur un
période de temps, et c'est plus que possible que parfois des
contradictions s'y introduisent. Sans doute quand ils ont écrit
le point 36, ils pensaient surtout à des fonctions
« classiques », qui définissent le comportement de l'objet, et
non à des fonctions qui ne font que valider le contrat.
Formellement, ils auraient pû dire qu'une classe racine ne doit
avoir ni d'état ni de comportement, mais c'est une formulation
un peu théorique et abstraite. Alors, pour rendre l'idée plus
facilement saisissable, ils l'ont traduite en termes plus
concrets : une class racine ne doit avoir ni de variables, ni
de fonctions non virtuelles.

[1] il y a-t-il un nom officiel, une personne que l'on peut créditer
pour cet idiome?



Le seul nom que je connais, c'est la programmation par contrat.
(Je tiens à ce qu'on ne le confond pas avec le « template
method pattern » ; la ressemblance n'en est que très
supérficielle, et la visée complètement différente.)

Je suis probablement le premier qui l'a formulé en tous ses
détails ; il y a eu une question dans comp.lang.c++.moderated
sur la façon de faire la programmation par contrat comme en
Eiffel, et j'ai développé l'argument. Mais en fait, je suis
certain d'avoir lu ou vu quelque chose avant qui m'a mis la puce
à l'oreille ; quelque chose qui, sans développer l'idée en
détail, l'a bien suggéré. Seulement, je n'arrive plus du tout à
trouver où ni quoi. (Il faut dire que je n'étais certainement
pas le premier à penser en termes de NVI -- quelqu'un
(peut-être Nathan Meyer ?), par exemple, a changé l'interface
de streambuf dans la norme pour l'utiliser, et ça, bien avant
que je n'y pense. Mais je ne sais pas si le but alors était la
programmation par contrat.)

--
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
Luc Hermitte
Le #15301961
On 2 juil, 10:06, James Kanze
On Jul 1, 6:19 pm, Luc Hermitte [...]
Peut-être. Le livre a été écrit par deux personnes, sur un
période de temps, et c'est plus que possible que parfois des
contradictions s'y introduisent. Sans doute quand ils ont écrit
le point 36, ils pensaient surtout à des fonctions
« classiques », qui définissent le comportement de l'objet, et
non à des fonctions qui ne font que valider le contrat.
Formellement, ils auraient pû dire qu'une classe racine ne doit
avoir ni d'état ni de comportement, mais c'est une formulation
un peu théorique et abstraite. Alors, pour rendre l'idée plus
facilement saisissable, ils l'ont traduite en termes plus
concrets : une class racine ne doit avoir ni de variables, ni
de fonctions non virtuelles.



Oui. Cela me parait une bonne hypothèse.
Merci à tous pour les précisions.

> [1] il y a-t-il un nom officiel, une personne que l'on peut créditer
> pour cet idiome?

Le seul nom que je connais, c'est la programmation par contrat.
(Je tiens à ce qu'on ne le confond pas avec le « template
method pattern » ; la ressemblance n'en est que très
supérficielle, et la visée complètement différente.)



Oui, je me souviens très bien de ton insistance à les différencier.
D'ailleurs, le /Coding Standards/ a une parenthèse au sujet de la
différence entre le pattern NVI et le pattern /Template Method/.

--
Luc Hermitte
Publicité
Poster une réponse
Anonyme