Là dessus, nous sommes bien d'accord...
Mais si le comportement "protégé" par les conditions est polymorphe, on *risque* de devoir aussi modifier les conditions, et il est alors *peut-être* nécessaire de prévoir que les conditions en question le soient aussi...
Mais ca, ca doit être déterminé en phase de conception (et il faut que l'implémentation s'y tienne) ;)
A vrai dire, je ne le coderais pas ainsi...
Pour moi, il n'y a rien qui puisse mieux être en mesure de dire qu'un objet est dans un état cohérent que... l'objet lui-même...
Si l'on modifie le comportement d'un type dérivé, comme je l'ai indiqué, il est *peut-être* nécessaire de modifier le comportement qui... vérifie que cet objet est cohérent.
C'est pour cela que je préfèrerais fortement coder la fonction sous la forme de
ou, si condition lance une exception, qui pourrait aller jusqu'à une forme proche deCode:
1
2
3
4
5
6
7
8
9
10
11 void fonction(A& a) { if(a.precheck()) { /* ok, on y va */ } if(!a.postcheck()) { /* ca a foiré, que faire pour récupérer a dans un état cohérent? */ } }
de manière à déléguer pleinement la responsabilité de vérifier les conditions à l'objet lui-même...Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 void fonction(A& a) { try { a.precheck(); //pré condition a.go(); // action a.postchech() // post condition } catch(PreConditionFailed & e) { } catch(PostConditionFailed &e) { /* quel comportement appler pour le "roll back" ? */ } }
Partant de là, s'il advient que le comportement doit etre polymorphe, ou que les condition doivent (et peuvent) l'être, la fonction s'adaptera du mieux possible à l'ensemble des possibilités ;)
Justement, c'est à l'objet de déterminer s'il est dans un état cohérent, ce qui permet - le cas échéans - à l'appelant de vérifier si les conditions sont remplies avant l'appel, mais ce qui peut permettre de créer une fonction qui s'en chargera ;)
En déléguant à l'objet la responsabilité de vérifier s'il est dans un état cohérent, tu gagne énormément de souplesse vis à vis de l'héritage et tu t'assure très facilement qu'une vérification apportera une réponse correcte, quelles que puissent-être les évolutions apportées au contrat ;)
Pour le 3, je dirais qu'il faut bien comprendre que, si tu as une fonction polymorphe, c'est le comportement de l'objet réellement en cours de traitement qu'il faut prendre en compte...
A partir de là, nous sommes bien d'accord sur le fait que la logique doit rester cohérente, et qu'il ne faut pas que ce comportement polymorphe renvoye faux alors qu'il aurait du renvoyer vrai... Là où nous ne sommes semble-t-il pas d'accord, c'est sur le fait que les conditions puissent évoluer, dans n'importe quel sens, en fonction du comportement polymorphe ;)
Si, si les conditions particulières, qui doivent de toutes manières prévaloir sur les conditions générales sont correctement énoncées et appliquées ;)Citation:
Après, ça ne veut pas dire que c'est la seule manière de faire, on est bien d'accord ;). Mais quand on sort de ce cadre, ça n'est plus de la programmation par contrats.