Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 12/10/2011, à 23:59

ehmicky

[POO]Principe de substitution de Liskov

Bonjour à tous,

Je me posais une question très générale de POO. Selon le principe de susbtitution de Liskov, une subclasse ne doit pas restreindre le contrat de sa classe parente, par exemple en rajoutant des préconditions.
Par exemple, une classe Carré ne doit pas être l'enfant d'une classe Rectangle, parce que Carré ajoute l'invariante "Tous les côtés sont égaux". Par exemple, si Rectangle définit les méthodes SetHorizontalEdges(), Carré ne devrait pas hériter de cette méthode, car cela ne respecterait l'invariante "Tous les côtés sont égaux".
Or, mettons que j'ai mon logiciel qui utilise la classe Rectangle depuis 3 ans, et qu'un jour, je me dise "C'est bête que lorsque tous les côtés de Rectangle sont égaux, ma classe CalculAire() multiplie sa longueur et sa largeur, alors que mettre l'un de ses côté au carré suffirait et serait plus efficient (bon, c'est pour l'exemple big_smile)". Donc je me dis, je vais implémenter une classe Carré, mais j'aimerais profiter de l'interface existante de Rectangle, du moins celle ne violant pas l'invariante "Tous les côtés sont égaux". Comment faire alors ? La seule idée qui me vient est de définir Rectangle et Carré comme un enfant d'une base classe Quadrilatère, qui rapatrierait toutes les méthodes communes aux deux enfants. Y a-t-il d'autres solutions ?
En d'autres termes, si B utilise plusieurs méthodes de A, mais pas toutes car B a un contrat plus restreint que A, faut-il créer une classe C parent de A et B, ou s'y prendre autrement ?

(ma question est pas spécifique à un langage, notamment par aux procédés de certains langages pour "dissimuler" des méthodes héritées des parents)

Dernière modification par ehmicky (Le 13/10/2011, à 00:04)


Stego++, bibliothèque libre de stéganographie (avec cryptographie), à venir !
Besoin de votre aide :
Stats sur les compilateurs C++ les plus utilisés
Comment utiliser les archetypes C++ ?

Hors ligne

#2 Le 13/10/2011, à 00:25

sputnick

Re : [POO]Principe de substitution de Liskov

Il y le polymorphisme qui peut être utilisé pour lancer CalculAire() sur un carré ou un rectangle et même un cercle, voir http://fr.wikipedia.org/wiki/Polymorphi … matique%29


On ne peut pas mettre d'array dans un string!
https://sputnick.fr/

Hors ligne

#3 Le 13/10/2011, à 00:59

ehmicky

Re : [POO]Principe de substitution de Liskov

Hum, merci effectivement c'est une solution.
Par contre, par exemple (pour prendre un langage) en C++, les deux solutions polymorphiques que je verrais serait :
  - une surcharge CalculAire(Carré) et CalculAire(Rectangle)
  - (mieux) une fonction à template CalculAire(T)
Mais dans les deux cas, cela m'oblige à sortir les méthodes de la "localité" de la fonction. Ca me gêne un peu, mais j'ai du mal à expliquer pourquoi smile
D'un autre côté, c'est le modèle choisi par les algorithmes standards. On a pas une base classe Container, dont hérite std::vector, std::list, etc., et qui définit l'ensemble des algorithmes (dieu merci).

En fait, ça me fait penser qu'à chaque fois que je réfléchis à comment construire ma bibliothèque, j'hésite entre deux modèles :
  - un basé sur l'héritage de classes
  - un basé sur la programmation générique
Je me disais toujours que les deux sont compatibles (par exemple la librarie standard utilise les deux), mais je me rends compte que plus j'essaie de "généraliser" le design avec des templates, plus je réduis les arborescences de classes, et j'ai parfois l'impression que les deux modèles sont concurrents, avec le deuxième étant plus flexible, léger et moderne.

Je sais pas quelles sont vos impressions là-dessus, je dis peut-être de grosses énormités big_smile

Dernière modification par ehmicky (Le 13/10/2011, à 01:01)


Stego++, bibliothèque libre de stéganographie (avec cryptographie), à venir !
Besoin de votre aide :
Stats sur les compilateurs C++ les plus utilisés
Comment utiliser les archetypes C++ ?

Hors ligne

#4 Le 13/10/2011, à 09:23

Luc Hermitte

Re : [POO]Principe de substitution de Liskov

Tu n'as pas forcément choisi le bon forum pour lancer ce genre de discussions. Tente le forum C++ de dvpz plutôt (n'hésite pas à donner un lien vers ici)
En attendant, les trucs à comprendre relativement au LSP et à cercle/ellipse c'est que l'héritage est valable si les objets sont immuables. On retrouve alors les objets mathématiques. Si on introduit des comportements dont la déformation, il n'y a plus d'héritage correct entre ces deux.
Le LSP nous pousse alors à extraire l'interface commune. Et pas vraiment le comportement commun.
- http://www.developpez.net/forums/d60768 … rectangle/
- http://www.developpez.net/forums/d64063 … on-liskov/

Ensuite entre template ou héritage, il y a deux mécanismes orthogonaux en jeu:
- le type de polymorphisme : inclusion ou paramétrique
- le dynamisme du polymorphisme : liaison tardive (/dynamique) ou liaison statique.
L'héritage en C++, c'est lié au polymorphisme d'inclusion, et le lien est dynamique.
Les templates en C++ sont liés au polymorphisme paramétrique, et le lien est statique.
En fin de compte, c'est souvent la nature du lien requis qui détermine la solution que l'on retient. S'il est impératif que le code sache s'adapter à l'exécution, on écarte les templates (ex: un logiciel de dessin type dia/visio/word/powerpoint qui permet d'altérer les formes déjà tracées). Si une liaison statique est acceptable et que l'on est plus dans le duck-typing (ce qui semble être une de tes interrogations) que dans le polymorphisme d'inclusion, les templates sont une bonne solution.
- http://cpp.developpez.com/faq/cpp/?page … EMENT_quoi

Hors ligne

#5 Le 13/10/2011, à 12:32

Hibou57

Re : [POO]Principe de substitution de Liskov

ehmicky a écrit :

Je me posais une question très générale de POO. Selon le principe de susbtitution de Liskov, une subclasse ne doit pas restreindre le contrat de sa classe parente, par exemple en rajoutant des préconditions.
Par exemple, une classe Carré ne doit pas être l'enfant d'une classe Rectangle, parce que Carré ajoute l'invariante "Tous les côtés sont égaux".

Ça n’est pas avec les objets en eux même que le problème se pose (tu décrit ici un objet en lui même, isolé), mais au niveau de leurs interactions. Le problème ne se pose pas de la même manière selon qu’un objet utilisé comme paramètre ou qu’il est reçu comme résultat, et il se pose même de manière inverse.

Une méthode d’un type dérivé, doit être plus tolérante avec ses paramètres, mais doit être plus stricte avec les résultats qu’elle renvoie; ceci, afin qu’une instance de ce type soit toujours substituable à une instance de son type parent.

Elle doit accepter un ensemble de paramètre au moins aussi large, sinon plus, et renvoyer au plus le même ensemble de valeur, sinon plus restreint.

C’est par contre plus difficile à réaliser qu’à dire.


P.S. Attention à ne pas confondre POO et classes wink Tu parle de classes ici, pas de POO. De toutes les manières, le terme POO ne veut rien dire, il mélange tout et n’importe quoi. Mais ce n’était qu’une parenthèse et désolé pour ce H.S.

Dernière modification par Hibou57 (Le 13/10/2011, à 12:35)


Hajimemashteeeee… \(^o^)/ Tachikoma desu (^_^;)
Le saviez‑vous : le j’m’en foutisme est la cause de la plupart des fléaux du monde contemporain.
Mangez des standards : un grand bol de Standard tous les matins, et vous débutez la journée en pleine forme !
bulleforum.net — Forum de discussions, La Bulle (papotage de la vie courante ou choses trop sérieuses)

Hors ligne

#6 Le 13/10/2011, à 21:26

ehmicky

Re : [POO]Principe de substitution de Liskov

Wow, vos commentaires sont vraiment tous les deux intéressants, merci !
Les liens aussi sont des débats très intéressants, je vais regarder ça tête reposée.
J'espère que le jour où j'aurais l'idée globale de l'interface publique, je pourrais vous présenter un diagramme UML ou un documentation simpliste Doxygen pour que je vous me donniez des conseils, c'est ma première bibliothèque ! smile


Stego++, bibliothèque libre de stéganographie (avec cryptographie), à venir !
Besoin de votre aide :
Stats sur les compilateurs C++ les plus utilisés
Comment utiliser les archetypes C++ ?

Hors ligne

#7 Le 22/10/2011, à 21:19

Hibou57

Re : [POO]Principe de substitution de Liskov


Hajimemashteeeee… \(^o^)/ Tachikoma desu (^_^;)
Le saviez‑vous : le j’m’en foutisme est la cause de la plupart des fléaux du monde contemporain.
Mangez des standards : un grand bol de Standard tous les matins, et vous débutez la journée en pleine forme !
bulleforum.net — Forum de discussions, La Bulle (papotage de la vie courante ou choses trop sérieuses)

Hors ligne