Principe de Liskov : cas concret ? - Algo - Programmation
Marsh Posté le 30-09-2008 à 11:49:13
Qu'en document soit membre ou libre, chiffré ou clair, c'est une information annexe, ça ne change pas la nature de ton document. Donc enlève ces trucs de ton arbre (pour rajouter des propriétés, template, héritage multiple, tu vois)
Marsh Posté le 01-10-2008 à 09:03:12
Apparemment vous me dites qu’ici la solution n’est pas l’héritage mais plutot la composition.
Très bien, mais si je n’ai que « Document » avec à l’intérieur des propriétés, par exemple comme c’est le cas maintenant « $this->oMembre » qui gère les données du membre pour le document. Si le document est libre cette propriété n’a pas de raison d’être, donc elle sera égale à « null ». Je ne suis pas spécialiste mais je sais qu’il n’est pas bon d’avoir des propriétés à null dans ses objets.
C’est pour cela que j’avais utilisé le concept de « Document Membre » pour ne pas avoir de propriétés à « null ». Si dans ce cas de figure vous me conseillez la composition, comment dois-je gérer cette variable « null » ?
Marsh Posté le 01-10-2008 à 09:22:19
Si je vous suis, je devrais faire quelque chose dans ce genre ?
Marsh Posté le 01-10-2008 à 09:36:40
jamesbond2 a écrit : |
Oui
jamesbond2 a écrit : |
C'est la meilleure de l'année. Je vois pas en quoi unmemebre à null pose un problème.
Marsh Posté le 01-10-2008 à 09:39:13
dans tous les livres de développement objets que j'ai peu lire ils disent clairement que si on a beaucoup de proriétés a "null" dans ses objets cela révele un défaut d'analyse.
Marsh Posté le 01-10-2008 à 09:39:43
brules ces livres
Marsh Posté le 01-10-2008 à 10:01:39
d'accord, si dans mon diagramme précédent, je met une propriété "$this->oClient" à mon "Document", si ensuite je cré un objet "Graphique" qui descend de "Document" et qui n'a en fait pas de client. la prorpiété "oClient" sera donc "null". Si maintenant je cré la fct de "Document" , "getClient()" et que je l'utilise dans "Graphique", cela viole le principe de substitution de Liskov, qui veut que TOUTES les fct de la classe mère puissent être utilisées dans la classe fille. Techniquement je peux le faire mais sémantiquement cela n'a pas de sens.
Marsh Posté le 01-10-2008 à 10:12:54
si je ne voulais pas avoir de variable "null",je ne mettrais pas "oClient" dans graphique ni dans "Document" je ne le mettrais uniquement dans des objets enfant de "Document" qui gère les clients. C'est pour cela que je dis que l'exemple de mon post précédent simulait une erreur volontaire d'analyse pour illistrer mon propos
Marsh Posté le 01-10-2008 à 10:13:04
si je ne voulais pas avoir de variable "null",je ne mettrais pas "oClient" dans graphique ni dans "Document" je ne le mettrais uniquement dans des objets enfant de "Document" qui gère les clients. C'est pour cela que je dis que l'exemple de mon post précédent simulait une erreur volontaire d'analyse pour illistrer mon propos
Marsh Posté le 01-10-2008 à 11:26:56
jamesbond2 a écrit : d'accord, si dans mon diagramme précédent, je met une propriété "$this->oClient" à mon "Document", si ensuite je cré un objet "Graphique" qui descend de "Document" et qui n'a en fait pas de client. la prorpiété "oClient" sera donc "null". Si maintenant je cré la fct de "Document" , "getClient()" et que je l'utilise dans "Graphique", cela viole le principe de substitution de Liskov, qui veut que TOUTES les fct de la classe mère puissent être utilisées dans la classe fille. Techniquement je peux le faire mais sémantiquement cela n'a pas de sens. |
Euh j'ai décroché. Comment tu fais pour avoir une méthode dans la classe mère et ne pas pouvoir l'utiliser dans une sous-classe ?
Marsh Posté le 01-10-2008 à 11:31:15
autre exemple :
J'ai une propriété de Numero de document ($this->iNumero). Dans tous mes documents, seuls "Graphique" et "Document Libre" n'ont pas de numéros.
Si je respect le schéma ci-dessus, j'ai deux solutions :
- Soit je mets la propriété "Numero" et ses fct accesseur/mutateur dans "Document", mais je viole le principe de substitution.
- Soit je répète la propriété "Numero" et ses fct accesseur/mutateur dans chaque document l'utilisant (Facture, Bl, Bc, Devis, Avoir), mais cela fait beaucoup de redondance de code
- Soit je crée un objet à part pour gérer la numérotation, mais cela me fait créer un objet annexe juste pour une propriété, c’est un peu dommage
quelle solution est la plus appropriée selon vous ?
Marsh Posté le 01-10-2008 à 11:32:45
Taz a écrit : |
je ne dis pas que je ne PEUX pas l'utiliser, je dis que si je l'utilise je viole le principe de substitution de Liskov, c'est TRES différent
Marsh Posté le 01-10-2008 à 11:47:03
Le principe de substitution de Liskov est le suivante :
"En clair, pour prétendre à l'héritage, une sous-classe doit être conçue de sorte que ses instances puissent se substituer à des instances de la classe de base partout où cette classe de base est utilisée."
c'est LA règle fondamentale de l'héritage
Marsh Posté le 01-10-2008 à 14:58:31
Il te faut une sous-classe document numéroté alors.
a) nan tu le violes pas, c'est juste que ton modèle est faux puisque les graphiques n'ont pas de Numero
b) dans ce cas là Facture.Numero n'a AUCUN lien avec les autres AutresDocuments.Numero. C'est juste le meme nom, pas une interface commune.
c) pas à part, juste un arbre à 3 niveaux.
Marsh Posté le 01-10-2008 à 14:59:15
jamesbond2 a écrit : Le principe de substitution de Liskov est le suivante : |
sans déconner ...
Marsh Posté le 01-10-2008 à 15:08:52
c'est gentil de nous faire un cours
masi ce n'est pas parceque tu dois pouvoir substituer un élément d'une classe fille a un élément d'une classe père que la fille et le père doivent avoir le même comportement, sinon, ca sert a rien de créer une autre classe si la fille ne peut pas redefinir les méthode du père
au niveau de ton dernier exemple, si vraiment je voulais éviter un inumero a vide, je créerai une classe docAvecInumero , dont hérite tes 5 premières classes et une autre docSansInumero dont hérite les deux autres.
Marsh Posté le 01-10-2008 à 15:19:03
Taz a écrit : Il te faut une sous-classe document numéroté alors. |
Merci pour tes réponses
a) ce qui est vrai pour Numéro l'est aussi pour un certains nombre de propriété(4 ou 5) qui sont commune à Facture, Bl, Bc, devis, Avoir; mais pas à Document Libre ou Graphique. C'est pourquoi j'avais créé la classe "Document Membre" pour regrouper ces propriétés commune à ces 5 types de document. Donc créer une classe "Document numéroté" va bien dans le sens de mon 1er diagramme avec une classe "Document Membre" (le nom est peut être mal choisi) !
b) je saisi pas...
c) entièrement d'accord
par contre je trouve que les sarcasmes du genre « sans déconner ... » n’apportent rien au débat…
Marsh Posté le 01-10-2008 à 15:37:54
en fait, dans ton premier diagramme, faut juste que ta classe "graphique" dérive de "document libre" (ou de "document" )
Marsh Posté le 30-09-2008 à 10:38:11
Bonjour j'ai un problème de modélisation objet a vous soumettre. Voici mon arborescence d'héritage :
Cette arborescence doit respecter le principe de substitution de Liskov.
Le problème c'est que les classes "Document chiffre" et "Courrier" utilisent des données faisant référence à un "Client" et à des fct d'insert et d'update BDD. MAIS l'objet "Graphique" (situé au même niveau de la hiérarchie) n'y fait absolument pas référence. Cependant "Graphique" doit hériter de "Document Membre" car il a besoin de certains autres element de cet objet.
C'est pourquoi j'ai décidé d'utiliser la composition pour "Document Membre" et de créer deux objets ; l'un gérant le client (oDatasClientDocument), l'autre les fct d'interfaçages avec la BDD (oBddDocument).
Mais avec cette nouvelle architecture certaines fct de "Document Membre" (entre autre getDatasClientDocument()) ne pourront pas être utilisé dans "Graphique" (cela n'aurait pas de sens). Donc cette architecture viole le principe de substitution.
Comment puis je faire pour que "Document Membre" gère les Clients et la Bdd tout en gardant la classe "Graphique" sans violer le principe de substitution.
Merci pour vos réponses